@typescript-calendar-lib/core 0.5.2 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Shared, framework-agnostic calendar utilities: date math, locale data, and grid building. Zero runtime dependencies.
4
4
 
5
- > **Tip:** You normally don't need `core` directly — the `cli`, `react`, `svelte`, and `tui` packages re-export the types and utilities you'll need. Reach for `core` when building your own renderer.
5
+ > **Tip:** You normally don't need `core` directly. The `cli`, `react`, `svelte`, and `tui` packages build on `core`, but each exposes only its own surface — reach for `core` directly when you want the date math, locale tables, or grid builder itself.
6
6
 
7
7
  ## Installation
8
8
 
@@ -10,8 +10,6 @@ Shared, framework-agnostic calendar utilities: date math, locale data, and grid
10
10
  pnpm add @typescript-calendar-lib/core
11
11
  # or
12
12
  npm install @typescript-calendar-lib/core
13
- # or
14
- bun add @typescript-calendar-lib/core
15
13
  ```
16
14
 
17
15
  ## Types
@@ -45,6 +43,7 @@ interface CalendarOptions {
45
43
  year: number;
46
44
  month: number; // 1-indexed (1–12)
47
45
  locale?: Locale; // default: "en"
46
+ holidayLocale?: Locale; // default: "ja" (see Holidays)
48
47
  weekStart?: WeekStart; // default: "sunday"
49
48
  highlight?: Date; // date to highlight (e.g. today)
50
49
  highlightStyle?: HighlightStyle; // default: "bracket"
@@ -61,6 +60,7 @@ Same as `CalendarOptions` minus `month` — renders a full year:
61
60
  interface CalendarYearOptions {
62
61
  year: number;
63
62
  locale?: Locale;
63
+ holidayLocale?: Locale; // default: "ja"
64
64
  weekStart?: WeekStart;
65
65
  highlight?: Date;
66
66
  highlightStyle?: HighlightStyle;
@@ -78,6 +78,7 @@ interface CalendarRangeOptions {
78
78
  from: Date;
79
79
  to: Date;
80
80
  locale?: Locale;
81
+ holidayLocale?: Locale; // default: "ja"
81
82
  weekStart?: WeekStart;
82
83
  highlight?: Date;
83
84
  highlightStyle?: HighlightStyle;
@@ -90,6 +91,35 @@ interface CalendarRangeOptions {
90
91
 
91
92
  Same as `CalendarOptions` minus `year`/`month`. Used by the low-level `renderMonth` helper.
92
93
 
94
+ ### `CalendarCellState`
95
+
96
+ Flags computed by `getCalendarCellState` for a single day cell:
97
+
98
+ ```ts
99
+ interface CalendarCellState {
100
+ isWeekend: boolean; // Saturday or Sunday
101
+ isHoliday: boolean; // holiday per `holidayLocale` (default "ja")
102
+ isToday: boolean; // matches `today`
103
+ isHighlight: boolean; // matches `highlight`
104
+ isInRange: boolean; // within `range` (inclusive)
105
+ isDisabled: boolean; // matches `isDateDisabled`
106
+ }
107
+ ```
108
+
109
+ ### `LocaleData`
110
+
111
+ The shape of the per-locale data held in `LOCALES`:
112
+
113
+ ```ts
114
+ interface LocaleData {
115
+ months: readonly string[];
116
+ weekdays: readonly string[];
117
+ weekdaysShort: readonly string[];
118
+ weekdaysMonday: readonly string[];
119
+ weekdaysMondayShort: readonly string[];
120
+ }
121
+ ```
122
+
93
123
  ## Constants
94
124
 
95
125
  ### `LOCALES`
@@ -104,6 +134,12 @@ Contains month names, weekday headers, and short weekday headers for each locale
104
134
 
105
135
  The supported year range (`1` / `9999`). Values outside this range are rejected by validation.
106
136
 
137
+ ### `HOLIDAY_MIN_YEAR` / `HOLIDAY_MAX_YEAR`
138
+
139
+ The year range for which holiday rules are implemented (`1949` / `2100`). Outside that
140
+ range the holiday functions report "no holiday" rather than throwing — see
141
+ [Holidays](#holidays).
142
+
107
143
  ## Functions
108
144
 
109
145
  ### `getMonthName(locale, month): string`
@@ -124,6 +160,24 @@ getWeekdayHeaders("en", "sunday"); // ["Sun", "Mon", ..., "Sat"]
124
160
  getWeekdayHeaders("en", "monday"); // ["Mon", "Tue", ..., "Sun"]
125
161
  ```
126
162
 
163
+ ### `getLocaleData(locale): LocaleData`
164
+
165
+ Returns the raw locale data (`months`, `weekdays`, `weekdaysShort`, plus the Monday-start rotations `weekdaysMonday` and `weekdaysMondayShort`). Throws `RangeError` for an unknown locale.
166
+
167
+ ```ts
168
+ getLocaleData("en").weekdays; // ["Sun", "Mon", ..., "Sat"]
169
+ getLocaleData("ja").weekdaysMonday; // ["月", "火", ..., "日"]
170
+ ```
171
+
172
+ ### `getLocaleData(locale): LocaleData`
173
+
174
+ Returns the raw locale data (`months`, `weekdays`, `weekdaysShort`, plus the Monday-start rotations `weekdaysMonday` and `weekdaysMondayShort`). Throws `RangeError` for an unknown locale.
175
+
176
+ ```ts
177
+ getLocaleData("en").weekdays; // ["Sun", "Mon", ..., "Sat"]
178
+ getLocaleData("ja").weekdaysMonday; // ["月", "火", ..., "日"]
179
+ ```
180
+
127
181
  ### `buildMonthGrid(year, month, weekStart): (number | null)[][]`
128
182
 
129
183
  Builds a 6×7 grid of day numbers (`1`–`31`) with `null` for empty cells. The grid is always 6 rows tall for stable layouts:
@@ -184,6 +238,250 @@ Creates a local `Date` at `00:00:00` without the `new Date(year, ...)` 1900-inte
184
238
 
185
239
  Throws `RangeError` when `date` is not a `Date` instance or is an `Invalid Date`.
186
240
 
241
+ ### `getCalendarCellState(date, options?): CalendarCellState`
242
+
243
+ Computes the display state of a single day cell (weekend, holiday, today, highlight, in-range, disabled) — the shared predicate every package uses to style and gate cells:
244
+
245
+ ```ts
246
+ const state = getCalendarCellState(new Date(2026, 8, 6), {
247
+ today: new Date(2026, 8, 6),
248
+ highlight: new Date(2026, 8, 6),
249
+ range: { from: new Date(2026, 8, 1), to: new Date(2026, 8, 10) },
250
+ });
251
+ // { isWeekend: true, isHoliday: false, isToday: true, isHighlight: true, isInRange: true, isDisabled: false }
252
+ ```
253
+
254
+ Options (all optional) mirror the per-locale calendar options: `today`, `highlight`, `range`, `isDateDisabled`, and `holidayLocale`. Pass `isDateDisabled` to mark specific dates as non-selectable — it is called once per cell with the cell's `Date`; returning `true` sets `isDisabled` (this is what the `tui`, `cli`, `react`, and `svelte` packages use to block selection/cursor movement):
255
+
256
+ ```ts
257
+ const state = getCalendarCellState(new Date(2026, 8, 15), {
258
+ isDateDisabled: (date) => date.getDay() === 0, // disable Sundays
259
+ });
260
+ // state.isDisabled === true
261
+ ```
262
+
263
+ With no options every flag is `false` except `isWeekend` (derived from the date) and `isHoliday` (derived from `holidayLocale`). Throws `RangeError` when `date` is invalid.
264
+
265
+ ### `isLeapYear(year): boolean`
266
+
267
+ Returns `true` for Gregorian leap years (divisible by 4, except by 100 unless also by 400):
268
+
269
+ ```ts
270
+ isLeapYear(2024); // true
271
+ isLeapYear(1900); // false
272
+ isLeapYear(2000); // true
273
+ ```
274
+
275
+ Works for years `1`–`99` too (no 1900-interpretation). Throws `RangeError` for out-of-range or non-integer years.
276
+
277
+ ### `daysInMonth(year, month): number`
278
+
279
+ Returns the number of days in the month (`28`–`31`):
280
+
281
+ ```ts
282
+ daysInMonth(2026, 2); // 28
283
+ daysInMonth(2024, 2); // 29 (leap year)
284
+ daysInMonth(2026, 4); // 30
285
+ ```
286
+
287
+ Throws `RangeError` for invalid `year`/`month`.
288
+
289
+ #### Arithmetic
290
+
291
+ ### `addDays(date, amount): Date`
292
+
293
+ Adds whole days (negative subtracts). Calendar-day based (`setDate`), so DST transitions don't shift the time — the same local time is preserved. Returns a new `Date`; the input is unchanged.
294
+
295
+ ```ts
296
+ addDays(new Date(2026, 8, 25), 7); // Oct 02 2026, same time
297
+ addDays(new Date(2026, 8, 25), -25); // Aug 31 2026
298
+ ```
299
+
300
+ ### `addWeeks(date, amount): Date`
301
+
302
+ Adds whole weeks — equivalent to `addDays(date, amount * 7)`. `amount` must be an integer.
303
+
304
+ ### `addMonths(date, amount): Date`
305
+
306
+ Adds whole months. When the target day doesn't exist in the destination month, the result clamps to the month's last day.
307
+
308
+ ```ts
309
+ addMonths(new Date(2026, 0, 31), 1); // Feb 28 2026 (Jan 31 + 1 month)
310
+ addMonths(new Date(2028, 0, 31), 1); // Feb 29 2028 (leap year)
311
+ ```
312
+
313
+ ### `addYears(date, amount): Date`
314
+
315
+ Adds whole years. Feb 29 clamps to Feb 28 of the target year.
316
+
317
+ ```ts
318
+ addYears(new Date(2028, 1, 29), 1); // Feb 28 2029
319
+ ```
320
+
321
+ #### Period boundaries
322
+
323
+ `startOf*` normalize to `00:00:00.000`, `endOf*` to `23:59:59.999`.
324
+
325
+ ### `startOfDay(date): Date`
326
+
327
+ Returns the date at `00:00:00.000`.
328
+
329
+ ### `endOfDay(date): Date`
330
+
331
+ Returns the date at `23:59:59.999`.
332
+
333
+ ### `startOfWeek(date, weekStart?): Date`
334
+
335
+ Returns the first day of the containing week at `00:00:00.000`. `weekStart` defaults to `"sunday"`.
336
+
337
+ ### `endOfWeek(date, weekStart?): Date`
338
+
339
+ Returns the last day of the containing week at `23:59:59.999`. `weekStart` defaults to `"sunday"`.
340
+
341
+ ### `startOfMonth(date): Date`
342
+
343
+ Returns the 1st of the month at `00:00:00.000`.
344
+
345
+ ### `endOfMonth(date): Date`
346
+
347
+ Returns the last day of the month at `23:59:59.999`.
348
+
349
+ ### `startOfYear(date): Date`
350
+
351
+ Returns Jan 1 at `00:00:00.000`.
352
+
353
+ ### `endOfYear(date): Date`
354
+
355
+ Returns Dec 31 at `23:59:59.999`.
356
+
357
+ #### Differences
358
+
359
+ Calendar differences ignore the time component, may be negative, and are DST-safe.
360
+
361
+ ### `diffInCalendarDays(from, to): number`
362
+
363
+ Returns `to - from` in calendar days.
364
+
365
+ ### `diffInCalendarMonths(from, to): number`
366
+
367
+ Returns `to - from` in whole calendar months.
368
+
369
+ ### `diffInCalendarYears(from, to): number`
370
+
371
+ Returns `to - from` in whole calendar years.
372
+
373
+ #### Comparison
374
+
375
+ ### `isBefore(date, other): boolean`
376
+
377
+ `true` when `date` is strictly before `other` (ms comparison).
378
+
379
+ ### `isAfter(date, other): boolean`
380
+
381
+ `true` when `date` is strictly after `other` (ms comparison).
382
+
383
+ ### `isSameMonth(a, b): boolean`
384
+
385
+ `true` when both dates share the year and month (day ignored).
386
+
387
+ ### `isSameYear(a, b): boolean`
388
+
389
+ `true` when both dates share the year.
390
+
391
+ ### `isWeekend(date): boolean`
392
+
393
+ `true` for Saturday or Sunday.
394
+
395
+ #### Week & year position
396
+
397
+ ### `getISOWeek(date): number`
398
+
399
+ Returns the ISO 8601 week number (`1`–`53`; week 1 contains the first Thursday).
400
+
401
+ ### `getWeekOfYear(date, weekStart?): number`
402
+
403
+ Returns the week number using the US convention — the week containing Jan 1 is week 1 (like `cal -w`). `weekStart` defaults to `"sunday"`.
404
+
405
+ ### `getDayOfYear(date): number`
406
+
407
+ Returns the 1-based day of year (Jan 1 = `1`, Dec 31 = `365`/`366`).
408
+
409
+ #### Clamping
410
+
411
+ ### `clampDate(date, min, max): Date`
412
+
413
+ Returns `date` clamped into `[min, max]`: `min` when earlier, `max` when later, otherwise the original `date`. All three dates are validated.
414
+
415
+ ```ts
416
+ clampDate(new Date(2026, 8, 25), new Date(2026, 8, 1), new Date(2026, 8, 15)); // Sep 15 2026
417
+ ```
418
+
419
+ #### Formatting
420
+
421
+ ### `formatDate(date, pattern, locale?): string`
422
+
423
+ Formats a date with the given pattern. Tokens are replaced with localized values; everything else is output verbatim.
424
+
425
+ | Token | Meaning |
426
+ | :--- | :--- |
427
+ | `yyyy` | 4-digit year (`2026`) |
428
+ | `yy` | last 2 digits of the year (`26`) |
429
+ | `MMMM` | full month name (`September`, `9月`) |
430
+ | `MM` / `M` | zero-padded / plain month (`09` / `9`) |
431
+ | `dd` / `d` | zero-padded / plain day (`05` / `5`) |
432
+ | `EEE` | short weekday, localized (`Fri`, `金`) |
433
+
434
+ ```ts
435
+ formatDate(date, "yyyy-MM-dd"); // "2026-09-25"
436
+ formatDate(date, "MMMM d, yyyy (EEE)"); // "September 25, 2026 (Fri)"
437
+ formatDate(date, "yyyy年M月d日", "ja"); // "2026年9月25日"
438
+ ```
439
+
440
+ > **Note:** all of the above validate their inputs and throw `RangeError` on invalid values: dates are checked with `assertValidDate`, `add*` amounts must be integers, and `weekStart` must be `"sunday" | "monday"`.
441
+
442
+
443
+ ## Holidays
444
+
445
+ `core` ships a complete Japanese holiday table — fixed-date holidays, happy-Monday
446
+ rules, and the equinox-based `春分の日` / `秋分の日` approximations — plus the
447
+ 2019/2020/2021 reforms and the pre-1973 fixed-date rules.
448
+
449
+ ```ts
450
+ import { getHolidayName, isHoliday } from "@typescript-calendar-lib/core";
451
+
452
+ isHoliday(new Date(2026, 4, 4)); // true
453
+ getHolidayName(new Date(2026, 4, 4)); // "みどりの日"
454
+ isHoliday(new Date(2026, 4, 6)); // true
455
+ getHolidayName(new Date(2026, 4, 6)); // "振替休日" (happy-Monday rule)
456
+ isHoliday(new Date(2026, 8, 22)); // true
457
+ getHolidayName(new Date(2026, 8, 22)); // "国民の休日"
458
+ isHoliday(new Date(2026, 8, 24)); // false
459
+ getHolidayName(new Date(2026, 8, 24)); // undefined
460
+ ```
461
+
462
+ > **Note:** `holidayLocale` defaults to `"ja"` — *independently of `locale`*. Calling
463
+ > `isHoliday(date)` with no arguments answers the **Japanese** calendar question, so an
464
+ > `locale: "en"` calendar still flags Japanese holidays. Pass `holidayLocale` explicitly
465
+ > if that is not what you want.
466
+
467
+ Rules are implemented for `HOLIDAY_MIN_YEAR` (`1949`) through `HOLIDAY_MAX_YEAR`
468
+ (`2100`). Outside that window the functions report "no holiday" rather than throwing.
469
+ Only `"ja"` has a rule table today: any other `holidayLocale` behaves as "no holidays",
470
+ which lets a caller opt out explicitly instead of relying on the default.
471
+
472
+ ### Business days
473
+
474
+ ```ts
475
+ import { addBusinessDays, diffInBusinessDays, isBusinessDay } from "@typescript-calendar-lib/core";
476
+
477
+ isBusinessDay(new Date(2026, 8, 5)); // false — Saturday
478
+ addBusinessDays(new Date(2026, 8, 4), 1); // Mon Sep 7 2026
479
+ diffInBusinessDays(new Date(2026, 8, 4), new Date(2026, 8, 7)); // 1
480
+ ```
481
+
482
+ A business day is a day that is neither a weekend nor a holiday under `holidayLocale`.
483
+ All three take an optional trailing `holidayLocale`.
484
+
187
485
  ## Input validation
188
486
 
189
487
  All functions validate their inputs and throw `RangeError` on invalid values instead of silently producing wrong results:
@@ -203,30 +501,70 @@ All functions validate their inputs and throw `RangeError` on invalid values ins
203
501
  ```ts
204
502
  // Types
205
503
  import type {
504
+ CalendarCellState,
206
505
  CalendarOptions,
207
506
  CalendarRangeOptions,
208
507
  CalendarYearOptions,
508
+ DateRange,
209
509
  HighlightStyle,
210
510
  Locale,
511
+ LocaleData,
211
512
  RenderMonthOptions,
212
513
  WeekStart,
213
514
  } from "@typescript-calendar-lib/core";
214
515
 
215
516
  // Values
216
517
  import {
518
+ HOLIDAY_MAX_YEAR,
519
+ HOLIDAY_MIN_YEAR,
217
520
  LOCALES,
218
521
  MAX_YEAR,
219
522
  MIN_YEAR,
523
+ addBusinessDays,
524
+ addDays,
525
+ addMonths,
526
+ addWeeks,
527
+ addYears,
220
528
  assertValidDate,
221
529
  buildMonthGrid,
530
+ clampDate,
222
531
  createDate,
532
+ daysInMonth,
533
+ diffInBusinessDays,
534
+ diffInCalendarDays,
535
+ diffInCalendarMonths,
536
+ diffInCalendarYears,
537
+ endOfDay,
538
+ endOfMonth,
539
+ endOfWeek,
540
+ endOfYear,
223
541
  firstDayOfMonth,
542
+ formatDate,
543
+ getCalendarCellState,
544
+ getDayOfYear,
545
+ getHolidayName,
546
+ getISOWeek,
547
+ getLocaleData,
224
548
  getMonthName,
225
549
  getMonthRange,
550
+ getWeekOfYear,
226
551
  getWeekdayHeaders,
552
+ isAfter,
553
+ isBefore,
554
+ isBusinessDay,
227
555
  isDateInRange,
556
+ isHoliday,
557
+ isLeapYear,
228
558
  isSameDay,
559
+ isSameMonth,
560
+ isSameYear,
561
+ isWeekend,
229
562
  lastDayOfMonth,
563
+ sortRange,
564
+ startOfDay,
565
+ startOfMonth,
566
+ startOfWeek,
567
+ startOfYear,
230
568
  } from "@typescript-calendar-lib/core";
231
569
  ```
232
570
 
package/dist/index.d.ts CHANGED
@@ -4,6 +4,8 @@ type WeekStart = "sunday" | "monday";
4
4
  type HighlightStyle = "bracket" | "reverse";
5
5
  interface BaseCalendarOptions {
6
6
  locale?: Locale;
7
+ /** 祝日判定に使うロケール。省略時は "ja"(日本の祝日) */
8
+ holidayLocale?: Locale;
7
9
  weekStart?: WeekStart;
8
10
  highlight?: Date;
9
11
  highlightStyle?: HighlightStyle;
@@ -26,6 +28,118 @@ interface CalendarRangeOptions extends BaseCalendarOptions {
26
28
  }
27
29
  interface RenderMonthOptions extends BaseCalendarOptions {}
28
30
  //#endregion
31
+ //#region src/date-math.d.ts
32
+ /**
33
+ * 日付に日数を加算する(負数で減算)。時刻は保持される。
34
+ * `setDate` ベースの暦日加算のため DST 遷移でも 1 日ずれない。
35
+ * 入力 Date は変更されず、新しい Date を返す。
36
+ */
37
+ export declare function addDays(date: Date, amount: number): Date;
38
+ /** 日付に週数を加算する(負数で減算)。addDays(date, amount * 7) と同じ */
39
+ export declare function addWeeks(date: Date, amount: number): Date;
40
+ /**
41
+ * 日付に月数を加算する(負数で減算)。時刻は保持される。
42
+ * 月中旬の日付は月を跨いでも同じ日付を保つ(例: 1月15日 + 1ヶ月 = 2月15日)。
43
+ * 移動先の月に存在しない日付は月末に丸められる
44
+ * (例: 1月31日 + 1ヶ月 = 2月28日/29日、1月30日 + 1ヶ月 = 2月28日/29日)。
45
+ */
46
+ export declare function addMonths(date: Date, amount: number): Date;
47
+ /** 日付に年数を加算する(負数で減算)。うるう日の 2月29日は 2月28日に丸められる */
48
+ export declare function addYears(date: Date, amount: number): Date;
49
+ /** その日の 00:00:00.000 を返す */
50
+ export declare function startOfDay(date: Date): Date;
51
+ /** その日の 23:59:59.999 を返す */
52
+ export declare function endOfDay(date: Date): Date;
53
+ /** 日付を含む週の初日(weekStart 曜日)の 00:00:00.000 を返す */
54
+ export declare function startOfWeek(date: Date, weekStart?: WeekStart): Date;
55
+ /** 日付を含む週の最終日の 23:59:59.999 を返す(週末を含む範囲に便利) */
56
+ export declare function endOfWeek(date: Date, weekStart?: WeekStart): Date;
57
+ /** 日付を含む月の初日の 00:00:00.000 を返す */
58
+ export declare function startOfMonth(date: Date): Date;
59
+ /** 日付を含む月の最終日の 23:59:59.999 を返す */
60
+ export declare function endOfMonth(date: Date): Date;
61
+ /** 日付を含む年の初日(1月1日)の 00:00:00.000 を返す */
62
+ export declare function startOfYear(date: Date): Date;
63
+ /** 日付を含む年の最終日の 23:59:59.999 を返す */
64
+ export declare function endOfYear(date: Date): Date;
65
+ /**
66
+ * 2つの日付の間の暦日数(to - from)を返す。マイナスもありうる。
67
+ * 時刻は無視され、DST 遷移があっても 1 日単位の差は正しい。
68
+ */
69
+ export declare function diffInCalendarDays(from: Date, to: Date): number;
70
+ /** 2つの日付の間の暦月数(to - from)を返す。マイナスもありうる */
71
+ export declare function diffInCalendarMonths(from: Date, to: Date): number;
72
+ /** 2つの日付の間の暦年数(to - from)を返す。マイナスもありうる */
73
+ export declare function diffInCalendarYears(from: Date, to: Date): number;
74
+ /** date が other より前(厳密に時刻が小さい)か */
75
+ export declare function isBefore(date: Date, other: Date): boolean;
76
+ /** date が other より後(厳密に時刻が大きい)か */
77
+ export declare function isAfter(date: Date, other: Date): boolean;
78
+ /** 同じ年月か(日は無視) */
79
+ export declare function isSameMonth(a: Date, b: Date): boolean;
80
+ /** 同じ年か(月・日は無視) */
81
+ export declare function isSameYear(a: Date, b: Date): boolean;
82
+ /** 週末(土曜 or 日曜)か */
83
+ export declare function isWeekend(date: Date): boolean;
84
+ /** ISO 8601 の週番号(1-53)を返す。第1週は最初の木曜日を含む週 */
85
+ export declare function getISOWeek(date: Date): number;
86
+ /**
87
+ * 年始(1月1日)を含む週を第1週とする週番号を返す。
88
+ * 1月1日より前の週の末日(例: 日曜始まりの 1月1日が土曜のとき)は前年の第52週/第53週になる。
89
+ * 北米のカレンダー(cal -w 相当)で使われる規則。
90
+ */
91
+ export declare function getWeekOfYear(date: Date, weekStart?: WeekStart): number;
92
+ /** 年の通算日(1月1日 = 1、12月31日 = 365/366)を返す */
93
+ export declare function getDayOfYear(date: Date): number;
94
+ /** 日付を [min, max] の範囲内にクランプする。範囲外なら min/max を、範囲内なら元の Date を返す */
95
+ export declare function clampDate(date: Date, min: Date, max: Date): Date;
96
+ /**
97
+ * パターン文字列に従って日付をフォーマットする。
98
+ *
99
+ * 対応トークン:
100
+ * - `yyyy` — 4桁の年(例: 2026)
101
+ * - `yy` — 西暦下2桁(例: 26)
102
+ * - `MMMM` — フル月名(ロケール依存。例: September / 9月)
103
+ * - `MM` — 0埋め2桁の月(01-12)
104
+ * - `M` — 月(1-12)
105
+ * - `dd` — 0埋め2桁の日(01-31)
106
+ * - `d` — 日(1-31)
107
+ * - `EEE` — 曜日の短縮名(ロケール依存。例: Fri / 金)
108
+ *
109
+ * トークン以外の文字はそのまま出力される。
110
+ *
111
+ * ```ts
112
+ * formatDate(date, "yyyy-MM-dd"); // "2026-09-25"
113
+ * formatDate(date, "MMMM d, yyyy (EEE)"); // "September 25, 2026 (Fri)"
114
+ * formatDate(date, "yyyy年M月d日", "ja"); // "2026年9月25日"
115
+ * ```
116
+ */
117
+ export declare function formatDate(date: Date, pattern: string, locale?: Locale): string;
118
+ //#endregion
119
+ //#region src/holidays.d.ts
120
+ /** 祝日が計算できる年範囲(1949 年以降の現行祝日法制に基づく) */
121
+ export declare const HOLIDAY_MIN_YEAR = 1949;
122
+ /** 祝日が計算できる年範囲(秋分の日の近似式が有効な上限。実用上十分) */
123
+ export declare const HOLIDAY_MAX_YEAR = 2100;
124
+ /** 日付が祝日(日本の国民の祝日・振替休日・国民の休日)か判定する。対象外ロケール/年は false */
125
+ export declare function isHoliday(date: Date, locale?: Locale): boolean;
126
+ /** 日付の祝日名を返す。祝日でない・対象外ロケール/年は undefined */
127
+ export declare function getHolidayName(date: Date, locale?: Locale): string | undefined;
128
+ /** 日付が営業日(平日かつ祝日でない)か判定する */
129
+ export declare function isBusinessDay(date: Date, locale?: Locale): boolean;
130
+ /**
131
+ * 日付に営業日数を加算する(負数で減算)。土日・祝日はスキップされる。
132
+ * 加算の起点は date そのもの(date 自体は数えない)。date === 戻り値になるのは amount = 0 のとき。
133
+ * 例: 2026-05-01(金)に 1 を足すと 2026-05-07(木)になる(5/3-5/6 が祝日)。
134
+ */
135
+ export declare function addBusinessDays(date: Date, amount: number, locale?: Locale): Date;
136
+ /**
137
+ * 2つの日付の間の営業日数(to - from 方向)を返す。マイナスもありうる。
138
+ * from 自身は数えず、to は数える。例: 月曜→火曜 = 1、金曜→翌月曜 = 1(土日はスキップ)。
139
+ * `addBusinessDays(from, n) === to` と `diffInBusinessDays(from, to) === n` は同値。
140
+ */
141
+ export declare function diffInBusinessDays(from: Date, to: Date, locale?: Locale): number;
142
+ //#endregion
29
143
  //#region src/locale.d.ts
30
144
  interface LocaleData {
31
145
  months: readonly string[];
@@ -35,12 +149,16 @@ interface LocaleData {
35
149
  weekdaysMondayShort: readonly string[];
36
150
  }
37
151
  export declare const LOCALES: Record<Locale, LocaleData>;
152
+ /** ロケールデータを取得する(未知のロケールは RangeError) */
153
+ export declare function getLocaleData(locale: Locale): LocaleData;
38
154
  export declare function getWeekdayHeaders(locale: Locale, weekStart: WeekStart): readonly string[];
39
155
  export declare function getMonthName(locale: Locale, month: number): string;
40
156
  //#endregion
41
157
  //#region src/utils.d.ts
42
158
  interface CalendarCellState {
43
159
  isWeekend: boolean;
160
+ /** 祝日かどうか(holidayLocale に従って判定。指定なしは "ja") */
161
+ isHoliday: boolean;
44
162
  isToday: boolean;
45
163
  isHighlight: boolean;
46
164
  isInRange: boolean;
@@ -81,6 +199,8 @@ export declare function getCalendarCellState(date: Date, options?: {
81
199
  to: Date;
82
200
  };
83
201
  isDateDisabled?: (date: Date) => boolean;
202
+ /** 祝日判定に使うロケール。省略時は "ja"(isHoliday のデフォルト) */
203
+ holidayLocale?: Locale;
84
204
  }): CalendarCellState;
85
205
  /** 日付が範囲の開始年から終了年までの月リストを返す */
86
206
  export declare function getMonthRange(from: Date, to: Date): {
package/dist/index.js CHANGED
@@ -256,6 +256,456 @@ function getMonthName(locale, month) {
256
256
  return getLocaleData(locale).months[month - 1];
257
257
  }
258
258
  //#endregion
259
+ //#region src/date-math.ts
260
+ /** 加算量が整数であることを検証する */
261
+ function assertAmount(amount) {
262
+ if (!Number.isInteger(amount)) throw new RangeError(`Invalid amount: ${amount} (expected an integer)`);
263
+ }
264
+ /**
265
+ * 日付に日数を加算する(負数で減算)。時刻は保持される。
266
+ * `setDate` ベースの暦日加算のため DST 遷移でも 1 日ずれない。
267
+ * 入力 Date は変更されず、新しい Date を返す。
268
+ */
269
+ function addDays(date, amount) {
270
+ assertValidDate(date);
271
+ assertAmount(amount);
272
+ const result = new Date(date.getTime());
273
+ result.setDate(result.getDate() + amount);
274
+ return result;
275
+ }
276
+ /** 日付に週数を加算する(負数で減算)。addDays(date, amount * 7) と同じ */
277
+ function addWeeks(date, amount) {
278
+ return addDays(date, amount * 7);
279
+ }
280
+ /**
281
+ * 日付に月数を加算する(負数で減算)。時刻は保持される。
282
+ * 月中旬の日付は月を跨いでも同じ日付を保つ(例: 1月15日 + 1ヶ月 = 2月15日)。
283
+ * 移動先の月に存在しない日付は月末に丸められる
284
+ * (例: 1月31日 + 1ヶ月 = 2月28日/29日、1月30日 + 1ヶ月 = 2月28日/29日)。
285
+ */
286
+ function addMonths(date, amount) {
287
+ assertValidDate(date);
288
+ assertAmount(amount);
289
+ const result = startOfDay(date);
290
+ const targetDay = date.getDate();
291
+ result.setDate(1);
292
+ result.setMonth(result.getMonth() + amount);
293
+ const lastDay = daysInMonthOf(result);
294
+ result.setDate(Math.min(targetDay, lastDay));
295
+ result.setHours(date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds());
296
+ return result;
297
+ }
298
+ /** 日付に年数を加算する(負数で減算)。うるう日の 2月29日は 2月28日に丸められる */
299
+ function addYears(date, amount) {
300
+ return addMonths(date, amount * 12);
301
+ }
302
+ /** 月の日数(1-31)を返す(Date 基準) */
303
+ function daysInMonthOf(date) {
304
+ return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
305
+ }
306
+ /** その日の 00:00:00.000 を返す */
307
+ function startOfDay(date) {
308
+ assertValidDate(date);
309
+ return createDate(date.getFullYear(), date.getMonth(), date.getDate());
310
+ }
311
+ /** その日の 23:59:59.999 を返す */
312
+ function endOfDay(date) {
313
+ const result = startOfDay(date);
314
+ result.setHours(23, 59, 59, 999);
315
+ return result;
316
+ }
317
+ /** 日付を含む週の初日(weekStart 曜日)の 00:00:00.000 を返す */
318
+ function startOfWeek(date, weekStart = "sunday") {
319
+ assertValidDate(date);
320
+ assertValidWeekStart(weekStart);
321
+ const day = startOfDay(date);
322
+ return addDays(day, -(weekStart === "sunday" ? day.getDay() : (day.getDay() + 6) % 7));
323
+ }
324
+ /** 日付を含む週の最終日の 23:59:59.999 を返す(週末を含む範囲に便利) */
325
+ function endOfWeek(date, weekStart = "sunday") {
326
+ return endOfDay(addDays(startOfWeek(date, weekStart), 6));
327
+ }
328
+ /** 日付を含む月の初日の 00:00:00.000 を返す */
329
+ function startOfMonth(date) {
330
+ assertValidDate(date);
331
+ return createDate(date.getFullYear(), date.getMonth(), 1);
332
+ }
333
+ /** 日付を含む月の最終日の 23:59:59.999 を返す */
334
+ function endOfMonth(date) {
335
+ return endOfDay(createDate(date.getFullYear(), date.getMonth() + 1, 0));
336
+ }
337
+ /** 日付を含む年の初日(1月1日)の 00:00:00.000 を返す */
338
+ function startOfYear(date) {
339
+ assertValidDate(date);
340
+ return createDate(date.getFullYear(), 0, 1);
341
+ }
342
+ /** 日付を含む年の最終日の 23:59:59.999 を返す */
343
+ function endOfYear(date) {
344
+ return endOfDay(createDate(date.getFullYear(), 12, 0));
345
+ }
346
+ /** 日付の「日」部分を UTC 日数(epoch からの日数)に正規化する。DST や year 0-99 の影響を受けない */
347
+ function toUtcDays(date) {
348
+ const utc = /* @__PURE__ */ new Date(0);
349
+ utc.setUTCFullYear(date.getFullYear(), date.getMonth(), date.getDate());
350
+ return utc.getTime() / 864e5;
351
+ }
352
+ /**
353
+ * 2つの日付の間の暦日数(to - from)を返す。マイナスもありうる。
354
+ * 時刻は無視され、DST 遷移があっても 1 日単位の差は正しい。
355
+ */
356
+ function diffInCalendarDays(from, to) {
357
+ assertValidDate(from);
358
+ assertValidDate(to);
359
+ return toUtcDays(to) - toUtcDays(from);
360
+ }
361
+ /** 2つの日付の間の暦月数(to - from)を返す。マイナスもありうる */
362
+ function diffInCalendarMonths(from, to) {
363
+ assertValidDate(from);
364
+ assertValidDate(to);
365
+ return (to.getFullYear() - from.getFullYear()) * 12 + (to.getMonth() - from.getMonth());
366
+ }
367
+ /** 2つの日付の間の暦年数(to - from)を返す。マイナスもありうる */
368
+ function diffInCalendarYears(from, to) {
369
+ assertValidDate(from);
370
+ assertValidDate(to);
371
+ return to.getFullYear() - from.getFullYear();
372
+ }
373
+ /** date が other より前(厳密に時刻が小さい)か */
374
+ function isBefore(date, other) {
375
+ assertValidDate(date);
376
+ assertValidDate(other);
377
+ return date.getTime() < other.getTime();
378
+ }
379
+ /** date が other より後(厳密に時刻が大きい)か */
380
+ function isAfter(date, other) {
381
+ assertValidDate(date);
382
+ assertValidDate(other);
383
+ return date.getTime() > other.getTime();
384
+ }
385
+ /** 同じ年月か(日は無視) */
386
+ function isSameMonth(a, b) {
387
+ assertValidDate(a);
388
+ assertValidDate(b);
389
+ return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth();
390
+ }
391
+ /** 同じ年か(月・日は無視) */
392
+ function isSameYear(a, b) {
393
+ assertValidDate(a);
394
+ assertValidDate(b);
395
+ return a.getFullYear() === b.getFullYear();
396
+ }
397
+ /** 週末(土曜 or 日曜)か */
398
+ function isWeekend(date) {
399
+ assertValidDate(date);
400
+ const day = date.getDay();
401
+ return day === 0 || day === 6;
402
+ }
403
+ /** ISO 8601 の週番号(1-53)を返す。第1週は最初の木曜日を含む週 */
404
+ function getISOWeek(date) {
405
+ assertValidDate(date);
406
+ const day = startOfDay(date);
407
+ const thursday = addDays(day, 3 - (day.getDay() + 6) % 7);
408
+ const jan1 = createDate(thursday.getFullYear(), 0, 1);
409
+ const firstThursday = addDays(jan1, (3 - (jan1.getDay() + 6) % 7 + 7) % 7);
410
+ return Math.floor(diffInCalendarDays(firstThursday, thursday) / 7) + 1;
411
+ }
412
+ /**
413
+ * 年始(1月1日)を含む週を第1週とする週番号を返す。
414
+ * 1月1日より前の週の末日(例: 日曜始まりの 1月1日が土曜のとき)は前年の第52週/第53週になる。
415
+ * 北米のカレンダー(cal -w 相当)で使われる規則。
416
+ */
417
+ function getWeekOfYear(date, weekStart = "sunday") {
418
+ assertValidDate(date);
419
+ assertValidWeekStart(weekStart);
420
+ const day = startOfDay(date);
421
+ const weekStartJan1 = startOfWeek(createDate(day.getFullYear(), 0, 1), weekStart);
422
+ return Math.floor(diffInCalendarDays(weekStartJan1, day) / 7) + 1;
423
+ }
424
+ /** 年の通算日(1月1日 = 1、12月31日 = 365/366)を返す */
425
+ function getDayOfYear(date) {
426
+ assertValidDate(date);
427
+ return diffInCalendarDays(startOfYear(date), date) + 1;
428
+ }
429
+ /** 日付を [min, max] の範囲内にクランプする。範囲外なら min/max を、範囲内なら元の Date を返す */
430
+ function clampDate(date, min, max) {
431
+ assertValidDate(date);
432
+ assertValidDate(min);
433
+ assertValidDate(max);
434
+ if (date.getTime() < min.getTime()) return min;
435
+ if (date.getTime() > max.getTime()) return max;
436
+ return date;
437
+ }
438
+ const TOKEN_RE = /yyyy|MMMM|EEE|yy|MM|dd|M|d/g;
439
+ /**
440
+ * パターン文字列に従って日付をフォーマットする。
441
+ *
442
+ * 対応トークン:
443
+ * - `yyyy` — 4桁の年(例: 2026)
444
+ * - `yy` — 西暦下2桁(例: 26)
445
+ * - `MMMM` — フル月名(ロケール依存。例: September / 9月)
446
+ * - `MM` — 0埋め2桁の月(01-12)
447
+ * - `M` — 月(1-12)
448
+ * - `dd` — 0埋め2桁の日(01-31)
449
+ * - `d` — 日(1-31)
450
+ * - `EEE` — 曜日の短縮名(ロケール依存。例: Fri / 金)
451
+ *
452
+ * トークン以外の文字はそのまま出力される。
453
+ *
454
+ * ```ts
455
+ * formatDate(date, "yyyy-MM-dd"); // "2026-09-25"
456
+ * formatDate(date, "MMMM d, yyyy (EEE)"); // "September 25, 2026 (Fri)"
457
+ * formatDate(date, "yyyy年M月d日", "ja"); // "2026年9月25日"
458
+ * ```
459
+ */
460
+ function formatDate(date, pattern, locale = "en") {
461
+ assertValidDate(date);
462
+ const data = getLocaleData(locale);
463
+ return pattern.replace(TOKEN_RE, (token) => {
464
+ switch (token) {
465
+ case "yyyy": return String(date.getFullYear()).padStart(4, "0");
466
+ case "yy": return String(date.getFullYear() % 100).padStart(2, "0");
467
+ case "MMMM": return getMonthName(locale, date.getMonth() + 1);
468
+ case "MM": return String(date.getMonth() + 1).padStart(2, "0");
469
+ case "M": return String(date.getMonth() + 1);
470
+ case "dd": return String(date.getDate()).padStart(2, "0");
471
+ case "d": return String(date.getDate());
472
+ case "EEE": return data.weekdays[date.getDay()];
473
+ default: return token;
474
+ }
475
+ });
476
+ }
477
+ //#endregion
478
+ //#region src/holidays.ts
479
+ /** 祝日が計算できる年範囲(1949 年以降の現行祝日法制に基づく) */
480
+ const HOLIDAY_MIN_YEAR = 1949;
481
+ /** 祝日が計算できる年範囲(秋分の日の近似式が有効な上限。実用上十分) */
482
+ const HOLIDAY_MAX_YEAR = 2100;
483
+ /** 1回限りの祝日(皇室行事・改元に伴う法律で定められたもの) */
484
+ const ONE_OFF_HOLIDAYS = [
485
+ {
486
+ year: 1959,
487
+ month: 4,
488
+ day: 10,
489
+ name: "皇太子明仁親王の結婚の儀"
490
+ },
491
+ {
492
+ year: 1989,
493
+ month: 2,
494
+ day: 24,
495
+ name: "昭和天皇の大喪の礼"
496
+ },
497
+ {
498
+ year: 1990,
499
+ month: 11,
500
+ day: 12,
501
+ name: "即位の礼正殿の儀"
502
+ },
503
+ {
504
+ year: 1993,
505
+ month: 6,
506
+ day: 9,
507
+ name: "皇太子徳仁親王の結婚の儀"
508
+ },
509
+ {
510
+ year: 2019,
511
+ month: 5,
512
+ day: 1,
513
+ name: "天皇即位の日"
514
+ },
515
+ {
516
+ year: 2019,
517
+ month: 10,
518
+ day: 22,
519
+ name: "即位礼正殿の儀"
520
+ }
521
+ ];
522
+ /** 年月日の曜日(0=日曜) */
523
+ function dayOfWeek(year, month, day) {
524
+ return createDate(year, month - 1, day).getDay();
525
+ }
526
+ /**
527
+ * 国民の祝日に関する法律と特例法に基づき、年の祝日一覧を規則から算出する。
528
+ *
529
+ * 計算順: ①祝日(固定日・第n月曜・春分/秋分)→ ②特例の祝日 → ③振替休日
530
+ * (1973年以降、祝日が日曜のとき直後の祝日でない日)→ ④国民の休日
531
+ * (1986年以降、祝日(日曜を除く)に挟まれた平日)。
532
+ * 祝日の名称は「元日」「成人の日」など法律上の名称、「振替休日」「国民の休日」はそのままの名称。
533
+ * 2020/2021 年の東京五輪特例(海の日・山の日・スポーツの日の振替)も反映する。
534
+ * 秋分の日・春分の日は天文学的な秋分/春分の日付(1851〜2099 年で有効な近似式)で算出する。
535
+ */
536
+ function holidaysOfYear(year) {
537
+ const list = [];
538
+ const add = (month, day, name) => {
539
+ list.push({
540
+ month,
541
+ day,
542
+ name
543
+ });
544
+ };
545
+ /** 指定月の第 n 曜日(weekday: 0=日曜 .. 6=土曜)の日付を返す */
546
+ const nthWeekday = (weekday, n, month) => {
547
+ return 1 + (weekday - createDate(year, month - 1, 1).getDay() + 7) % 7 + (n - 1) * 7;
548
+ };
549
+ const monday = (n, month) => nthWeekday(1, n, month);
550
+ const springEquinox = Math.floor(20.8431 + .242194 * (year - 1980) - Math.floor((year - 1980) / 4));
551
+ const fallEquinox = Math.floor(23.2488 + .242194 * (year - 1980) - Math.floor((year - 1980) / 4));
552
+ if (year >= 1949) add(1, 1, "元日");
553
+ if (year >= 1949) add(1, year <= 1999 ? 15 : monday(2, 1), "成人の日");
554
+ if (year >= 1967) add(2, 11, "建国記念の日");
555
+ if (year >= 1949) {
556
+ if (year <= 1988) add(4, 29, "天皇誕生日");
557
+ else if (year <= 2018) add(12, 23, "天皇誕生日");
558
+ else if (year >= 2020) add(2, 23, "天皇誕生日");
559
+ }
560
+ if (year >= 2007) add(4, 29, "昭和の日");
561
+ if (year >= 1949) add(5, 3, "憲法記念日");
562
+ if (year >= 1989 && year <= 2006) add(4, 29, "みどりの日");
563
+ if (year >= 2007) add(5, 4, "みどりの日");
564
+ if (year >= 1949) add(5, 5, "こどもの日");
565
+ if (year >= 1996) {
566
+ if (year <= 2002) add(7, 20, "海の日");
567
+ else if (year === 2020) add(7, 23, "海の日");
568
+ else if (year === 2021) add(7, 22, "海の日");
569
+ else add(7, monday(3, 7), "海の日");
570
+ }
571
+ if (year >= 2016) {
572
+ if (year === 2020) add(8, 10, "山の日");
573
+ else if (year === 2021) add(8, 8, "山の日");
574
+ else add(8, 11, "山の日");
575
+ }
576
+ if (year >= 1949) add(3, springEquinox, "春分の日");
577
+ if (year >= 1966) add(9, year <= 2002 ? 15 : monday(3, 9), "敬老の日");
578
+ if (year >= 1949) add(9, fallEquinox, "秋分の日");
579
+ if (year >= 1966) {
580
+ if (year <= 1999) add(10, 10, "体育の日");
581
+ else if (year <= 2019) add(10, monday(2, 10), "体育の日");
582
+ else if (year === 2020) add(7, 24, "スポーツの日");
583
+ else if (year === 2021) add(7, 23, "スポーツの日");
584
+ else add(10, monday(2, 10), "スポーツの日");
585
+ }
586
+ if (year >= 1949) add(11, 3, "文化の日");
587
+ if (year >= 1949) add(11, 23, "勤労感謝の日");
588
+ for (const { year: y, month: m, day: d, name } of ONE_OFF_HOLIDAYS) if (y === year) add(m, d, name);
589
+ const inList = (month, day) => list.some((h) => h.month === month && h.day === day);
590
+ if (year >= 1973) {
591
+ const substituteFrom = createDate(1973, 3, 12).getTime();
592
+ for (const h of [...list]) {
593
+ if (dayOfWeek(year, h.month, h.day) !== 0) continue;
594
+ const base = createDate(year, h.month - 1, h.day);
595
+ if (base.getTime() < substituteFrom) continue;
596
+ for (let i = 1; i <= 7; i++) {
597
+ const next = addDays(base, i);
598
+ if (!inList(next.getMonth() + 1, next.getDate())) {
599
+ add(next.getMonth() + 1, next.getDate(), "振替休日");
600
+ break;
601
+ }
602
+ }
603
+ }
604
+ }
605
+ if (year >= 1986) for (let month = 1; month <= 12; month++) {
606
+ const days = createDate(year, month, 0).getDate();
607
+ for (let day = 1; day <= days; day++) {
608
+ if (inList(month, day)) continue;
609
+ const date = createDate(year, month - 1, day);
610
+ if (date.getDay() === 0) continue;
611
+ const prev = addDays(date, -1);
612
+ const next = addDays(date, 1);
613
+ if (inList(prev.getMonth() + 1, prev.getDate()) && inList(next.getMonth() + 1, next.getDate())) add(month, day, "国民の休日");
614
+ }
615
+ }
616
+ return list;
617
+ }
618
+ /**
619
+ * 祝日一覧に月・日のインデックスを張る。
620
+ */
621
+ function toIndex(list) {
622
+ const byMonth = /* @__PURE__ */ new Map();
623
+ for (const h of list) {
624
+ let days = byMonth.get(h.month);
625
+ if (days === void 0) {
626
+ days = /* @__PURE__ */ new Map();
627
+ byMonth.set(h.month, days);
628
+ }
629
+ days.set(h.day, h.name);
630
+ }
631
+ return {
632
+ list,
633
+ byMonth
634
+ };
635
+ }
636
+ /** 年の計算結果キャッシュ(同じ年を何度も参照する描画用途のため) */
637
+ const holidayCache = /* @__PURE__ */ new Map();
638
+ /** 祝日インデックスを取得する。対象外ロケール・範囲外の年は null */
639
+ function holidayIndexOf(date, locale) {
640
+ if (locale !== "ja") return null;
641
+ const year = date.getFullYear();
642
+ if (year < 1949 || year > 2100) return null;
643
+ const cached = holidayCache.get(year);
644
+ if (cached !== void 0) return cached;
645
+ const index = toIndex(holidaysOfYear(year));
646
+ holidayCache.set(year, index);
647
+ return index;
648
+ }
649
+ /** 日付が祝日(日本の国民の祝日・振替休日・国民の休日)か判定する。対象外ロケール/年は false */
650
+ function isHoliday(date, locale = "ja") {
651
+ assertValidDate(date);
652
+ const index = holidayIndexOf(date, locale);
653
+ if (index === null) return false;
654
+ return index.byMonth.get(date.getMonth() + 1)?.get(date.getDate()) !== void 0;
655
+ }
656
+ /** 日付の祝日名を返す。祝日でない・対象外ロケール/年は undefined */
657
+ function getHolidayName(date, locale = "ja") {
658
+ assertValidDate(date);
659
+ const index = holidayIndexOf(date, locale);
660
+ if (index === null) return void 0;
661
+ return index.byMonth.get(date.getMonth() + 1)?.get(date.getDate());
662
+ }
663
+ /** 日付が営業日(平日かつ祝日でない)か判定する */
664
+ function isBusinessDay(date, locale = "ja") {
665
+ assertValidDate(date);
666
+ if (date.getDay() === 0 || date.getDay() === 6) return false;
667
+ return !isHoliday(date, locale);
668
+ }
669
+ /** 加算する営業日数が整数であることを検証する */
670
+ function assertBusinessAmount(amount) {
671
+ if (!Number.isInteger(amount)) throw new RangeError(`Invalid amount: ${amount} (expected an integer)`);
672
+ }
673
+ /**
674
+ * 日付に営業日数を加算する(負数で減算)。土日・祝日はスキップされる。
675
+ * 加算の起点は date そのもの(date 自体は数えない)。date === 戻り値になるのは amount = 0 のとき。
676
+ * 例: 2026-05-01(金)に 1 を足すと 2026-05-07(木)になる(5/3-5/6 が祝日)。
677
+ */
678
+ function addBusinessDays(date, amount, locale = "ja") {
679
+ assertValidDate(date);
680
+ assertBusinessAmount(amount);
681
+ const result = new Date(date.getTime());
682
+ const step = amount >= 0 ? 1 : -1;
683
+ let remaining = Math.abs(amount);
684
+ while (remaining > 0) {
685
+ result.setDate(result.getDate() + step);
686
+ if (isBusinessDay(result, locale)) remaining--;
687
+ }
688
+ return result;
689
+ }
690
+ /**
691
+ * 2つの日付の間の営業日数(to - from 方向)を返す。マイナスもありうる。
692
+ * from 自身は数えず、to は数える。例: 月曜→火曜 = 1、金曜→翌月曜 = 1(土日はスキップ)。
693
+ * `addBusinessDays(from, n) === to` と `diffInBusinessDays(from, to) === n` は同値。
694
+ */
695
+ function diffInBusinessDays(from, to, locale = "ja") {
696
+ assertValidDate(from);
697
+ assertValidDate(to);
698
+ const sign = to.getTime() >= from.getTime() ? 1 : -1;
699
+ const cursor = new Date(from.getTime());
700
+ let count = 0;
701
+ for (;;) {
702
+ cursor.setDate(cursor.getDate() + sign);
703
+ if (sign > 0 ? cursor.getTime() > to.getTime() : cursor.getTime() < to.getTime()) break;
704
+ if (isBusinessDay(cursor, locale)) count++;
705
+ }
706
+ return count * sign;
707
+ }
708
+ //#endregion
259
709
  //#region src/utils.ts
260
710
  /**
261
711
  * 2つの日付を from <= to の順にソートした範囲を返す。
@@ -326,6 +776,7 @@ function getCalendarCellState(date, options = {}) {
326
776
  assertValidDate(date);
327
777
  return {
328
778
  isWeekend: date.getDay() === 0 || date.getDay() === 6,
779
+ isHoliday: isHoliday(date, options.holidayLocale),
329
780
  isToday: options.today !== void 0 && isSameDay(date, options.today),
330
781
  isHighlight: options.highlight !== void 0 && isSameDay(date, options.highlight),
331
782
  isInRange: options.range !== void 0 && isDateInRange(date, options.range),
@@ -356,6 +807,6 @@ function daysInMonth(year, month) {
356
807
  return lastDayOfMonth(year, month).getDate();
357
808
  }
358
809
  //#endregion
359
- export { LOCALES, MAX_YEAR, MIN_YEAR, assertValidDate, buildMonthGrid, createDate, daysInMonth, firstDayOfMonth, getCalendarCellState, getMonthName, getMonthRange, getWeekdayHeaders, isDateInRange, isLeapYear, isSameDay, lastDayOfMonth, sortRange };
810
+ export { HOLIDAY_MAX_YEAR, HOLIDAY_MIN_YEAR, LOCALES, MAX_YEAR, MIN_YEAR, addBusinessDays, addDays, addMonths, addWeeks, addYears, assertValidDate, buildMonthGrid, clampDate, createDate, daysInMonth, diffInBusinessDays, diffInCalendarDays, diffInCalendarMonths, diffInCalendarYears, endOfDay, endOfMonth, endOfWeek, endOfYear, firstDayOfMonth, formatDate, getCalendarCellState, getDayOfYear, getHolidayName, getISOWeek, getLocaleData, getMonthName, getMonthRange, getWeekOfYear, getWeekdayHeaders, isAfter, isBefore, isBusinessDay, isDateInRange, isHoliday, isLeapYear, isSameDay, isSameMonth, isSameYear, isWeekend, lastDayOfMonth, sortRange, startOfDay, startOfMonth, startOfWeek, startOfYear };
360
811
 
361
812
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/validation.ts","../src/locale.ts","../src/utils.ts"],"sourcesContent":["// ─── 入力検証 ─────────────────────────────────────────────\n\n/** サポートする年の最小値(JS Date は 0-99 を 1900+年 と解釈するため 1 から) */\nexport const MIN_YEAR = 1;\n/** サポートする年の最大値 */\nexport const MAX_YEAR = 9999;\n\n/** 値が min-max の整数であることを検証する(不正なら RangeError) */\nfunction assertIntegerInRange(\n name: string,\n value: number,\n min: number,\n max: number,\n): void {\n if (!Number.isInteger(value) || value < min || value > max) {\n throw new RangeError(\n `Invalid ${name}: ${value} (expected an integer between ${min} and ${max})`,\n );\n }\n}\n\n/** 年が 1-9999 の整数であることを検証する */\nexport function assertValidYear(year: number): void {\n assertIntegerInRange(\"year\", year, MIN_YEAR, MAX_YEAR);\n}\n\n/** 月が 1-12 の整数であることを検証する */\nexport function assertValidMonth(month: number): void {\n assertIntegerInRange(\"month\", month, 1, 12);\n}\n\n/** 年の組み合わせ(year と month)を検証する */\nexport function assertValidYearMonth(year: number, month: number): void {\n assertValidYear(year);\n assertValidMonth(month);\n}\n\n/** 週の開始曜日を検証する */\nexport function assertValidWeekStart(weekStart: string): void {\n if (weekStart !== \"sunday\" && weekStart !== \"monday\") {\n throw new RangeError(\n `Invalid weekStart: \"${weekStart}\" (expected \"sunday\" or \"monday\")`,\n );\n }\n}\n\n/** Date が有効(Invalid Date でない)ことを検証する */\nexport function assertValidDate(date: Date): void {\n if (!(date instanceof Date) || Number.isNaN(date.getTime())) {\n throw new RangeError(`Invalid Date: ${String(date)}`);\n }\n}\n\n/**\n * ローカルの指定日 00:00:00 を生成する。\n * `new Date(year, ...)` は year 0-99 を 1900+year と解釈するため、\n * setFullYear を使って year 0-99 も正しく扱えるようにする。\n *\n * - year は 1-9999、monthIndex は 0-12、day は 0-31 の整数である必要がある(それ以外は RangeError)\n * - monthIndex 12 は翌年1月(`new Date` と同じロールオーバー。lastDayOfMonth が 12月の月末取得に使う)\n * - day 0 は前月の月末(`new Date` と同じ規則)\n * - day がその月の日数を超える場合は翌月にロールする(`new Date` と同じ挙動)\n */\nexport function createDate(\n year: number,\n monthIndex: number,\n day: number,\n): Date {\n assertValidYear(year);\n assertIntegerInRange(\"monthIndex\", monthIndex, 0, 12);\n assertIntegerInRange(\"day\", day, 0, 31);\n const date = new Date(0);\n date.setHours(0, 0, 0, 0);\n date.setFullYear(year, monthIndex, day);\n return date;\n}\n","import type { Locale, WeekStart } from \"./types.ts\";\nimport { assertValidMonth, assertValidWeekStart } from \"./validation.ts\";\n\nexport interface LocaleData {\n months: readonly string[];\n weekdays: readonly string[];\n weekdaysShort: readonly string[];\n weekdaysMonday: readonly string[];\n weekdaysMondayShort: readonly string[];\n}\n\n/** 月曜始まりの配列は日曜始まりの配列を前ローテーションして生成する */\nfunction makeLocale(\n months: readonly string[],\n weekdays: readonly string[],\n weekdaysShort: readonly string[] = weekdays,\n): LocaleData {\n const rotate = (arr: readonly string[]) => [...arr.slice(1), arr[0]!];\n return {\n months,\n weekdays,\n weekdaysShort,\n weekdaysMonday: rotate(weekdays),\n weekdaysMondayShort: rotate(weekdaysShort),\n };\n}\n\nexport const LOCALES: Record<Locale, LocaleData> = {\n en: makeLocale(\n [\n \"January\",\n \"February\",\n \"March\",\n \"April\",\n \"May\",\n \"June\",\n \"July\",\n \"August\",\n \"September\",\n \"October\",\n \"November\",\n \"December\",\n ],\n [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n [\"Su\", \"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\"],\n ),\n ja: makeLocale(\n [\n \"1月\",\n \"2月\",\n \"3月\",\n \"4月\",\n \"5月\",\n \"6月\",\n \"7月\",\n \"8月\",\n \"9月\",\n \"10月\",\n \"11月\",\n \"12月\",\n ],\n [\"日\", \"月\", \"火\", \"水\", \"木\", \"金\", \"土\"],\n ),\n es: makeLocale(\n [\n \"enero\",\n \"febrero\",\n \"marzo\",\n \"abril\",\n \"mayo\",\n \"junio\",\n \"julio\",\n \"agosto\",\n \"septiembre\",\n \"octubre\",\n \"noviembre\",\n \"diciembre\",\n ],\n [\"dom\", \"lun\", \"mar\", \"mié\", \"jue\", \"vie\", \"sáb\"],\n [\"do\", \"lu\", \"ma\", \"mi\", \"ju\", \"vi\", \"sá\"],\n ),\n de: makeLocale(\n [\n \"Januar\",\n \"Februar\",\n \"März\",\n \"April\",\n \"Mai\",\n \"Juni\",\n \"Juli\",\n \"August\",\n \"September\",\n \"Oktober\",\n \"November\",\n \"Dezember\",\n ],\n [\"So\", \"Mo\", \"Di\", \"Mi\", \"Do\", \"Fr\", \"Sa\"],\n ),\n fr: makeLocale(\n [\n \"janvier\",\n \"février\",\n \"mars\",\n \"avril\",\n \"mai\",\n \"juin\",\n \"juillet\",\n \"août\",\n \"septembre\",\n \"octobre\",\n \"novembre\",\n \"décembre\",\n ],\n [\"dim.\", \"lun.\", \"mar.\", \"mer.\", \"jeu.\", \"ven.\", \"sam.\"],\n [\"di\", \"lu\", \"ma\", \"me\", \"je\", \"ve\", \"sa\"],\n ),\n ko: makeLocale(\n [\n \"1월\",\n \"2월\",\n \"3월\",\n \"4월\",\n \"5월\",\n \"6월\",\n \"7월\",\n \"8월\",\n \"9월\",\n \"10월\",\n \"11월\",\n \"12월\",\n ],\n [\"일\", \"월\", \"화\", \"수\", \"목\", \"금\", \"토\"],\n ),\n zh: makeLocale(\n [\n \"一月\",\n \"二月\",\n \"三月\",\n \"四月\",\n \"五月\",\n \"六月\",\n \"七月\",\n \"八月\",\n \"九月\",\n \"十月\",\n \"十一月\",\n \"十二月\",\n ],\n [\"日\", \"一\", \"二\", \"三\", \"四\", \"五\", \"六\"],\n ),\n};\n\n/** ロケールデータを取得する(未知のロケールは RangeError) */\nfunction getLocaleData(locale: Locale): LocaleData {\n const data = LOCALES[locale];\n if (data === undefined) {\n throw new RangeError(`Invalid locale: \"${locale}\"`);\n }\n return data;\n}\n\nexport function getWeekdayHeaders(\n locale: Locale,\n weekStart: WeekStart,\n): readonly string[] {\n assertValidWeekStart(weekStart);\n const data = getLocaleData(locale);\n return weekStart === \"monday\" ? data.weekdaysMonday : data.weekdays;\n}\n\nexport function getMonthName(locale: Locale, month: number): string {\n assertValidMonth(month);\n const data = getLocaleData(locale);\n return data.months[month - 1]!;\n}\n","import type { WeekStart } from \"./types.ts\";\nimport {\n assertValidDate,\n assertValidWeekStart,\n assertValidYear,\n assertValidYearMonth,\n createDate,\n} from \"./validation.ts\";\n\nexport interface CalendarCellState {\n isWeekend: boolean;\n isToday: boolean;\n isHighlight: boolean;\n isInRange: boolean;\n isDisabled: boolean;\n}\n\n/** 日付範囲(from <= to) */\nexport interface DateRange {\n from: Date;\n to: Date;\n}\n\n/**\n * 2つの日付を from <= to の順にソートした範囲を返す。\n * どちらかが null なら undefined(範囲なし)。\n */\nexport function sortRange(\n a: Date | null,\n b: Date | null,\n): DateRange | undefined {\n if (a === null || b === null) return undefined;\n return a.getTime() <= b.getTime() ? { from: a, to: b } : { from: b, to: a };\n}\n\n/** 月初日(1日)を返す */\nexport function firstDayOfMonth(year: number, month: number): Date {\n assertValidYearMonth(year, month);\n return createDate(year, month - 1, 1);\n}\n\n/** 月末日を返す */\nexport function lastDayOfMonth(year: number, month: number): Date {\n assertValidYearMonth(year, month);\n return createDate(year, month, 0);\n}\n\n/**\n * 月の日付グリッドを生成する(6行×7列)\n * 各セルは日数(1-31)または null(空欄)\n */\nexport function buildMonthGrid(\n year: number,\n month: number,\n weekStart: WeekStart,\n): (number | null)[][] {\n assertValidYearMonth(year, month);\n assertValidWeekStart(weekStart);\n\n const daysInMonth = lastDayOfMonth(year, month).getDate();\n let skip = firstDayOfMonth(year, month).getDay();\n if (weekStart === \"monday\") {\n skip = (skip + 6) % 7;\n }\n\n const grid: (number | null)[][] = [];\n let day = 1;\n for (let week = 0; week < 6; week++) {\n const row: (number | null)[] = [];\n for (let col = 0; col < 7; col++) {\n if (day > daysInMonth || (week === 0 && col < skip)) {\n row.push(null);\n } else {\n row.push(day++);\n }\n }\n grid.push(row);\n }\n return grid;\n}\n\n/** 範囲(from/to)が有効であることを検証する */\nfunction assertValidRange(from: Date, to: Date): void {\n assertValidDate(from);\n assertValidDate(to);\n if (from.getTime() > to.getTime()) {\n throw new RangeError(\"Invalid range: from must not be after to\");\n }\n}\n\n/** 日付が範囲内に含まれるか */\nexport function isDateInRange(\n date: Date,\n range?: { from: Date; to: Date },\n): boolean {\n if (!range) return false;\n assertValidRange(range.from, range.to);\n assertValidDate(date);\n const time = date.getTime();\n return time >= range.from.getTime() && time <= range.to.getTime();\n}\n\n/** 日付が今日と一致するか(日付のみ比較) */\nexport function isSameDay(a: Date, b: Date): boolean {\n assertValidDate(a);\n assertValidDate(b);\n return (\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate()\n );\n}\n\n/** 日付セルの表示状態を計算する */\nexport function getCalendarCellState(\n date: Date,\n options: {\n today?: Date;\n highlight?: Date;\n range?: { from: Date; to: Date };\n isDateDisabled?: (date: Date) => boolean;\n } = {},\n): CalendarCellState {\n assertValidDate(date);\n return {\n isWeekend: date.getDay() === 0 || date.getDay() === 6,\n isToday: options.today !== undefined && isSameDay(date, options.today),\n isHighlight:\n options.highlight !== undefined && isSameDay(date, options.highlight),\n isInRange:\n options.range !== undefined && isDateInRange(date, options.range),\n isDisabled: options.isDateDisabled?.(date) ?? false,\n };\n}\n\n/** 日付が範囲の開始年から終了年までの月リストを返す */\nexport function getMonthRange(\n from: Date,\n to: Date,\n): { year: number; month: number }[] {\n assertValidRange(from, to);\n const start = from.getFullYear() * 12 + from.getMonth();\n const end = to.getFullYear() * 12 + to.getMonth();\n return Array.from({ length: end - start + 1 }, (_, i) => {\n const n = start + i;\n return { year: Math.floor(n / 12), month: (n % 12) + 1 };\n });\n}\n\n/** グレゴリオ暦のうるう年判定(4で割れるが100では割れない、または400で割れる) */\nexport function isLeapYear(year: number): boolean {\n assertValidYear(year);\n return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n}\n\n/** 月の日数(1-31)を返す */\nexport function daysInMonth(year: number, month: number): number {\n assertValidYearMonth(year, month);\n return lastDayOfMonth(year, month).getDate();\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/validation.ts","../src/locale.ts","../src/date-math.ts","../src/holidays.ts","../src/utils.ts"],"sourcesContent":["// ─── 入力検証 ─────────────────────────────────────────────\n\n/** サポートする年の最小値(JS Date は 0-99 を 1900+年 と解釈するため 1 から) */\nexport const MIN_YEAR = 1;\n/** サポートする年の最大値 */\nexport const MAX_YEAR = 9999;\n\n/** 値が min-max の整数であることを検証する(不正なら RangeError) */\nfunction assertIntegerInRange(\n name: string,\n value: number,\n min: number,\n max: number,\n): void {\n if (!Number.isInteger(value) || value < min || value > max) {\n throw new RangeError(\n `Invalid ${name}: ${value} (expected an integer between ${min} and ${max})`,\n );\n }\n}\n\n/** 年が 1-9999 の整数であることを検証する */\nexport function assertValidYear(year: number): void {\n assertIntegerInRange(\"year\", year, MIN_YEAR, MAX_YEAR);\n}\n\n/** 月が 1-12 の整数であることを検証する */\nexport function assertValidMonth(month: number): void {\n assertIntegerInRange(\"month\", month, 1, 12);\n}\n\n/** 年の組み合わせ(year と month)を検証する */\nexport function assertValidYearMonth(year: number, month: number): void {\n assertValidYear(year);\n assertValidMonth(month);\n}\n\n/** 週の開始曜日を検証する */\nexport function assertValidWeekStart(weekStart: string): void {\n if (weekStart !== \"sunday\" && weekStart !== \"monday\") {\n throw new RangeError(\n `Invalid weekStart: \"${weekStart}\" (expected \"sunday\" or \"monday\")`,\n );\n }\n}\n\n/** Date が有効(Invalid Date でない)ことを検証する */\nexport function assertValidDate(date: Date): void {\n if (!(date instanceof Date) || Number.isNaN(date.getTime())) {\n throw new RangeError(`Invalid Date: ${String(date)}`);\n }\n}\n\n/**\n * ローカルの指定日 00:00:00 を生成する。\n * `new Date(year, ...)` は year 0-99 を 1900+year と解釈するため、\n * setFullYear を使って year 0-99 も正しく扱えるようにする。\n *\n * - year は 1-9999、monthIndex は 0-12、day は 0-31 の整数である必要がある(それ以外は RangeError)\n * - monthIndex 12 は翌年1月(`new Date` と同じロールオーバー。lastDayOfMonth が 12月の月末取得に使う)\n * - day 0 は前月の月末(`new Date` と同じ規則)\n * - day がその月の日数を超える場合は翌月にロールする(`new Date` と同じ挙動)\n */\nexport function createDate(\n year: number,\n monthIndex: number,\n day: number,\n): Date {\n assertValidYear(year);\n assertIntegerInRange(\"monthIndex\", monthIndex, 0, 12);\n assertIntegerInRange(\"day\", day, 0, 31);\n const date = new Date(0);\n date.setHours(0, 0, 0, 0);\n date.setFullYear(year, monthIndex, day);\n return date;\n}\n","import type { Locale, WeekStart } from \"./types.ts\";\nimport { assertValidMonth, assertValidWeekStart } from \"./validation.ts\";\n\nexport interface LocaleData {\n months: readonly string[];\n weekdays: readonly string[];\n weekdaysShort: readonly string[];\n weekdaysMonday: readonly string[];\n weekdaysMondayShort: readonly string[];\n}\n\n/** 月曜始まりの配列は日曜始まりの配列を前ローテーションして生成する */\nfunction makeLocale(\n months: readonly string[],\n weekdays: readonly string[],\n weekdaysShort: readonly string[] = weekdays,\n): LocaleData {\n const rotate = (arr: readonly string[]) => [...arr.slice(1), arr[0]!];\n return {\n months,\n weekdays,\n weekdaysShort,\n weekdaysMonday: rotate(weekdays),\n weekdaysMondayShort: rotate(weekdaysShort),\n };\n}\n\nexport const LOCALES: Record<Locale, LocaleData> = {\n en: makeLocale(\n [\n \"January\",\n \"February\",\n \"March\",\n \"April\",\n \"May\",\n \"June\",\n \"July\",\n \"August\",\n \"September\",\n \"October\",\n \"November\",\n \"December\",\n ],\n [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n [\"Su\", \"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\"],\n ),\n ja: makeLocale(\n [\n \"1月\",\n \"2月\",\n \"3月\",\n \"4月\",\n \"5月\",\n \"6月\",\n \"7月\",\n \"8月\",\n \"9月\",\n \"10月\",\n \"11月\",\n \"12月\",\n ],\n [\"日\", \"月\", \"火\", \"水\", \"木\", \"金\", \"土\"],\n ),\n es: makeLocale(\n [\n \"enero\",\n \"febrero\",\n \"marzo\",\n \"abril\",\n \"mayo\",\n \"junio\",\n \"julio\",\n \"agosto\",\n \"septiembre\",\n \"octubre\",\n \"noviembre\",\n \"diciembre\",\n ],\n [\"dom\", \"lun\", \"mar\", \"mié\", \"jue\", \"vie\", \"sáb\"],\n [\"do\", \"lu\", \"ma\", \"mi\", \"ju\", \"vi\", \"sá\"],\n ),\n de: makeLocale(\n [\n \"Januar\",\n \"Februar\",\n \"März\",\n \"April\",\n \"Mai\",\n \"Juni\",\n \"Juli\",\n \"August\",\n \"September\",\n \"Oktober\",\n \"November\",\n \"Dezember\",\n ],\n [\"So\", \"Mo\", \"Di\", \"Mi\", \"Do\", \"Fr\", \"Sa\"],\n ),\n fr: makeLocale(\n [\n \"janvier\",\n \"février\",\n \"mars\",\n \"avril\",\n \"mai\",\n \"juin\",\n \"juillet\",\n \"août\",\n \"septembre\",\n \"octobre\",\n \"novembre\",\n \"décembre\",\n ],\n [\"dim.\", \"lun.\", \"mar.\", \"mer.\", \"jeu.\", \"ven.\", \"sam.\"],\n [\"di\", \"lu\", \"ma\", \"me\", \"je\", \"ve\", \"sa\"],\n ),\n ko: makeLocale(\n [\n \"1월\",\n \"2월\",\n \"3월\",\n \"4월\",\n \"5월\",\n \"6월\",\n \"7월\",\n \"8월\",\n \"9월\",\n \"10월\",\n \"11월\",\n \"12월\",\n ],\n [\"일\", \"월\", \"화\", \"수\", \"목\", \"금\", \"토\"],\n ),\n zh: makeLocale(\n [\n \"一月\",\n \"二月\",\n \"三月\",\n \"四月\",\n \"五月\",\n \"六月\",\n \"七月\",\n \"八月\",\n \"九月\",\n \"十月\",\n \"十一月\",\n \"十二月\",\n ],\n [\"日\", \"一\", \"二\", \"三\", \"四\", \"五\", \"六\"],\n ),\n};\n\n/** ロケールデータを取得する(未知のロケールは RangeError) */\nexport function getLocaleData(locale: Locale): LocaleData {\n const data = LOCALES[locale];\n if (data === undefined) {\n throw new RangeError(`Invalid locale: \"${locale}\"`);\n }\n return data;\n}\n\nexport function getWeekdayHeaders(\n locale: Locale,\n weekStart: WeekStart,\n): readonly string[] {\n assertValidWeekStart(weekStart);\n const data = getLocaleData(locale);\n return weekStart === \"monday\" ? data.weekdaysMonday : data.weekdays;\n}\n\nexport function getMonthName(locale: Locale, month: number): string {\n assertValidMonth(month);\n const data = getLocaleData(locale);\n return data.months[month - 1]!;\n}\n","import { getLocaleData, getMonthName } from \"./locale.ts\";\nimport type { Locale, WeekStart } from \"./types.ts\";\nimport {\n assertValidDate,\n assertValidWeekStart,\n createDate,\n} from \"./validation.ts\";\n\n// ─── 日付演算 ─────────────────────────────────────────────\n\n/** 加算量が整数であることを検証する */\nfunction assertAmount(amount: number): void {\n if (!Number.isInteger(amount)) {\n throw new RangeError(`Invalid amount: ${amount} (expected an integer)`);\n }\n}\n\n/**\n * 日付に日数を加算する(負数で減算)。時刻は保持される。\n * `setDate` ベースの暦日加算のため DST 遷移でも 1 日ずれない。\n * 入力 Date は変更されず、新しい Date を返す。\n */\nexport function addDays(date: Date, amount: number): Date {\n assertValidDate(date);\n assertAmount(amount);\n const result = new Date(date.getTime());\n result.setDate(result.getDate() + amount);\n return result;\n}\n\n/** 日付に週数を加算する(負数で減算)。addDays(date, amount * 7) と同じ */\nexport function addWeeks(date: Date, amount: number): Date {\n return addDays(date, amount * 7);\n}\n\n/**\n * 日付に月数を加算する(負数で減算)。時刻は保持される。\n * 月中旬の日付は月を跨いでも同じ日付を保つ(例: 1月15日 + 1ヶ月 = 2月15日)。\n * 移動先の月に存在しない日付は月末に丸められる\n * (例: 1月31日 + 1ヶ月 = 2月28日/29日、1月30日 + 1ヶ月 = 2月28日/29日)。\n */\nexport function addMonths(date: Date, amount: number): Date {\n assertValidDate(date);\n assertAmount(amount);\n const result = startOfDay(date);\n const targetDay = date.getDate();\n result.setDate(1);\n result.setMonth(result.getMonth() + amount);\n const lastDay = daysInMonthOf(result);\n result.setDate(Math.min(targetDay, lastDay));\n // 時刻を復元する\n result.setHours(\n date.getHours(),\n date.getMinutes(),\n date.getSeconds(),\n date.getMilliseconds(),\n );\n return result;\n}\n\n/** 日付に年数を加算する(負数で減算)。うるう日の 2月29日は 2月28日に丸められる */\nexport function addYears(date: Date, amount: number): Date {\n return addMonths(date, amount * 12);\n}\n\n/** 月の日数(1-31)を返す(Date 基準) */\nfunction daysInMonthOf(date: Date): number {\n return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();\n}\n\n// ─── 期間の境界 ───────────────────────────────────────────\n\n/** その日の 00:00:00.000 を返す */\nexport function startOfDay(date: Date): Date {\n assertValidDate(date);\n return createDate(date.getFullYear(), date.getMonth(), date.getDate());\n}\n\n/** その日の 23:59:59.999 を返す */\nexport function endOfDay(date: Date): Date {\n const result = startOfDay(date);\n result.setHours(23, 59, 59, 999);\n return result;\n}\n\n/** 日付を含む週の初日(weekStart 曜日)の 00:00:00.000 を返す */\nexport function startOfWeek(date: Date, weekStart: WeekStart = \"sunday\"): Date {\n assertValidDate(date);\n assertValidWeekStart(weekStart);\n const day = startOfDay(date);\n const offset = weekStart === \"sunday\" ? day.getDay() : (day.getDay() + 6) % 7;\n return addDays(day, -offset);\n}\n\n/** 日付を含む週の最終日の 23:59:59.999 を返す(週末を含む範囲に便利) */\nexport function endOfWeek(date: Date, weekStart: WeekStart = \"sunday\"): Date {\n return endOfDay(addDays(startOfWeek(date, weekStart), 6));\n}\n\n/** 日付を含む月の初日の 00:00:00.000 を返す */\nexport function startOfMonth(date: Date): Date {\n assertValidDate(date);\n return createDate(date.getFullYear(), date.getMonth(), 1);\n}\n\n/** 日付を含む月の最終日の 23:59:59.999 を返す */\nexport function endOfMonth(date: Date): Date {\n return endOfDay(createDate(date.getFullYear(), date.getMonth() + 1, 0));\n}\n\n/** 日付を含む年の初日(1月1日)の 00:00:00.000 を返す */\nexport function startOfYear(date: Date): Date {\n assertValidDate(date);\n return createDate(date.getFullYear(), 0, 1);\n}\n\n/** 日付を含む年の最終日の 23:59:59.999 を返す */\nexport function endOfYear(date: Date): Date {\n return endOfDay(createDate(date.getFullYear(), 12, 0));\n}\n\n// ─── 差(暦日ベース) ─────────────────────────────────────\n\n/** 日付の「日」部分を UTC 日数(epoch からの日数)に正規化する。DST や year 0-99 の影響を受けない */\nfunction toUtcDays(date: Date): number {\n const utc = new Date(0);\n utc.setUTCFullYear(date.getFullYear(), date.getMonth(), date.getDate());\n return utc.getTime() / 86_400_000;\n}\n\n/**\n * 2つの日付の間の暦日数(to - from)を返す。マイナスもありうる。\n * 時刻は無視され、DST 遷移があっても 1 日単位の差は正しい。\n */\nexport function diffInCalendarDays(from: Date, to: Date): number {\n assertValidDate(from);\n assertValidDate(to);\n return toUtcDays(to) - toUtcDays(from);\n}\n\n/** 2つの日付の間の暦月数(to - from)を返す。マイナスもありうる */\nexport function diffInCalendarMonths(from: Date, to: Date): number {\n assertValidDate(from);\n assertValidDate(to);\n return (\n (to.getFullYear() - from.getFullYear()) * 12 +\n (to.getMonth() - from.getMonth())\n );\n}\n\n/** 2つの日付の間の暦年数(to - from)を返す。マイナスもありうる */\nexport function diffInCalendarYears(from: Date, to: Date): number {\n assertValidDate(from);\n assertValidDate(to);\n return to.getFullYear() - from.getFullYear();\n}\n\n// ─── 比較 ─────────────────────────────────────────────────\n\n/** date が other より前(厳密に時刻が小さい)か */\nexport function isBefore(date: Date, other: Date): boolean {\n assertValidDate(date);\n assertValidDate(other);\n return date.getTime() < other.getTime();\n}\n\n/** date が other より後(厳密に時刻が大きい)か */\nexport function isAfter(date: Date, other: Date): boolean {\n assertValidDate(date);\n assertValidDate(other);\n return date.getTime() > other.getTime();\n}\n\n/** 同じ年月か(日は無視) */\nexport function isSameMonth(a: Date, b: Date): boolean {\n assertValidDate(a);\n assertValidDate(b);\n return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth();\n}\n\n/** 同じ年か(月・日は無視) */\nexport function isSameYear(a: Date, b: Date): boolean {\n assertValidDate(a);\n assertValidDate(b);\n return a.getFullYear() === b.getFullYear();\n}\n\n/** 週末(土曜 or 日曜)か */\nexport function isWeekend(date: Date): boolean {\n assertValidDate(date);\n const day = date.getDay();\n return day === 0 || day === 6;\n}\n\n// ─── 年・週の位置 ─────────────────────────────────────────\n\n/** ISO 8601 の週番号(1-53)を返す。第1週は最初の木曜日を含む週 */\nexport function getISOWeek(date: Date): number {\n assertValidDate(date);\n const day = startOfDay(date);\n const weekday = (day.getDay() + 6) % 7; // 月=0 ... 日=6\n // 今週の木曜日(ISO 年の基準。月曜〜日曜のどれを取っても同じ週番号になる)\n const thursday = addDays(day, 3 - weekday);\n const jan1 = createDate(thursday.getFullYear(), 0, 1);\n const jan1Weekday = (jan1.getDay() + 6) % 7;\n const firstThursday = addDays(jan1, (3 - jan1Weekday + 7) % 7);\n return Math.floor(diffInCalendarDays(firstThursday, thursday) / 7) + 1;\n}\n\n/**\n * 年始(1月1日)を含む週を第1週とする週番号を返す。\n * 1月1日より前の週の末日(例: 日曜始まりの 1月1日が土曜のとき)は前年の第52週/第53週になる。\n * 北米のカレンダー(cal -w 相当)で使われる規則。\n */\nexport function getWeekOfYear(\n date: Date,\n weekStart: WeekStart = \"sunday\",\n): number {\n assertValidDate(date);\n assertValidWeekStart(weekStart);\n const day = startOfDay(date);\n const jan1 = createDate(day.getFullYear(), 0, 1);\n const weekStartJan1 = startOfWeek(jan1, weekStart);\n return Math.floor(diffInCalendarDays(weekStartJan1, day) / 7) + 1;\n}\n\n/** 年の通算日(1月1日 = 1、12月31日 = 365/366)を返す */\nexport function getDayOfYear(date: Date): number {\n assertValidDate(date);\n return diffInCalendarDays(startOfYear(date), date) + 1;\n}\n\n// ─── その他 ───────────────────────────────────────────────\n\n/** 日付を [min, max] の範囲内にクランプする。範囲外なら min/max を、範囲内なら元の Date を返す */\nexport function clampDate(date: Date, min: Date, max: Date): Date {\n assertValidDate(date);\n assertValidDate(min);\n assertValidDate(max);\n if (date.getTime() < min.getTime()) return min;\n if (date.getTime() > max.getTime()) return max;\n return date;\n}\n\nconst TOKEN_RE = /yyyy|MMMM|EEE|yy|MM|dd|M|d/g;\n\n/**\n * パターン文字列に従って日付をフォーマットする。\n *\n * 対応トークン:\n * - `yyyy` — 4桁の年(例: 2026)\n * - `yy` — 西暦下2桁(例: 26)\n * - `MMMM` — フル月名(ロケール依存。例: September / 9月)\n * - `MM` — 0埋め2桁の月(01-12)\n * - `M` — 月(1-12)\n * - `dd` — 0埋め2桁の日(01-31)\n * - `d` — 日(1-31)\n * - `EEE` — 曜日の短縮名(ロケール依存。例: Fri / 金)\n *\n * トークン以外の文字はそのまま出力される。\n *\n * ```ts\n * formatDate(date, \"yyyy-MM-dd\"); // \"2026-09-25\"\n * formatDate(date, \"MMMM d, yyyy (EEE)\"); // \"September 25, 2026 (Fri)\"\n * formatDate(date, \"yyyy年M月d日\", \"ja\"); // \"2026年9月25日\"\n * ```\n */\nexport function formatDate(\n date: Date,\n pattern: string,\n locale: Locale = \"en\",\n): string {\n assertValidDate(date);\n const data = getLocaleData(locale);\n return pattern.replace(TOKEN_RE, (token) => {\n switch (token) {\n case \"yyyy\":\n return String(date.getFullYear()).padStart(4, \"0\");\n case \"yy\":\n return String(date.getFullYear() % 100).padStart(2, \"0\");\n case \"MMMM\":\n return getMonthName(locale, date.getMonth() + 1);\n case \"MM\":\n return String(date.getMonth() + 1).padStart(2, \"0\");\n case \"M\":\n return String(date.getMonth() + 1);\n case \"dd\":\n return String(date.getDate()).padStart(2, \"0\");\n case \"d\":\n return String(date.getDate());\n case \"EEE\":\n return data.weekdays[date.getDay()]!;\n default:\n return token;\n }\n });\n}\n","import { addDays } from \"./date-math.ts\";\nimport type { Locale } from \"./types.ts\";\nimport { assertValidDate, createDate } from \"./validation.ts\";\n\n// ─── 日本の祝日 ───────────────────────────────────────────\n\n/**\n * 祝日データを持つロケール。現在は日本語(日本の国民の祝日)のみ。\n * その他のロケールは「祝日なし」として扱われる(isHoliday は常に false)。\n */\nexport type HolidayLocale = \"ja\";\n\n/** 祝日が計算できる年範囲(1949 年以降の現行祝日法制に基づく) */\nexport const HOLIDAY_MIN_YEAR = 1949;\n\n/** 祝日が計算できる年範囲(秋分の日の近似式が有効な上限。実用上十分) */\nexport const HOLIDAY_MAX_YEAR = 2100;\n\n/** 1回限りの祝日(皇室行事・改元に伴う法律で定められたもの) */\nconst ONE_OFF_HOLIDAYS: readonly YearHolidayWithYear[] = [\n { year: 1959, month: 4, day: 10, name: \"皇太子明仁親王の結婚の儀\" },\n { year: 1989, month: 2, day: 24, name: \"昭和天皇の大喪の礼\" },\n { year: 1990, month: 11, day: 12, name: \"即位の礼正殿の儀\" },\n { year: 1993, month: 6, day: 9, name: \"皇太子徳仁親王の結婚の儀\" },\n { year: 2019, month: 5, day: 1, name: \"天皇即位の日\" },\n { year: 2019, month: 10, day: 22, name: \"即位礼正殿の儀\" },\n];\n\n/** 年の祝日一覧の1件(month は 1-12) */\ninterface YearHoliday {\n month: number;\n day: number;\n name: string;\n}\n\n/** 祝日一覧の1件に発生日(year)を添えたもの。一覧データの定義に使う */\ninterface YearHolidayWithYear extends YearHoliday {\n year: number;\n}\n\n/** 年月日の曜日(0=日曜) */\nfunction dayOfWeek(year: number, month: number, day: number): number {\n return createDate(year, month - 1, day).getDay();\n}\n\n/**\n * 国民の祝日に関する法律と特例法に基づき、年の祝日一覧を規則から算出する。\n *\n * 計算順: ①祝日(固定日・第n月曜・春分/秋分)→ ②特例の祝日 → ③振替休日\n * (1973年以降、祝日が日曜のとき直後の祝日でない日)→ ④国民の休日\n * (1986年以降、祝日(日曜を除く)に挟まれた平日)。\n * 祝日の名称は「元日」「成人の日」など法律上の名称、「振替休日」「国民の休日」はそのままの名称。\n * 2020/2021 年の東京五輪特例(海の日・山の日・スポーツの日の振替)も反映する。\n * 秋分の日・春分の日は天文学的な秋分/春分の日付(1851〜2099 年で有効な近似式)で算出する。\n */\nfunction holidaysOfYear(year: number): YearHoliday[] {\n const list: YearHoliday[] = [];\n const add = (month: number, day: number, name: string): void => {\n list.push({ month, day, name });\n };\n /** 指定月の第 n 曜日(weekday: 0=日曜 .. 6=土曜)の日付を返す */\n const nthWeekday = (weekday: number, n: number, month: number): number => {\n const first = createDate(year, month - 1, 1);\n const offset = (weekday - first.getDay() + 7) % 7;\n return 1 + offset + (n - 1) * 7;\n };\n const monday = (n: number, month: number): number => nthWeekday(1, n, month);\n const springEquinox = Math.floor(\n 20.8431 + 0.242194 * (year - 1980) - Math.floor((year - 1980) / 4),\n );\n const fallEquinox = Math.floor(\n 23.2488 + 0.242194 * (year - 1980) - Math.floor((year - 1980) / 4),\n );\n\n // ── ① 国民の祝日(法律上の規則) ──\n if (year >= 1949) add(1, 1, \"元日\");\n if (year >= 1949) {\n // 成人の日: 2000年以降は1月第2月曜\n add(1, year <= 1999 ? 15 : monday(2, 1), \"成人の日\");\n }\n if (year >= 1967) add(2, 11, \"建国記念の日\");\n if (year >= 1949) {\n // 天皇誕生日: 4/29(〜1988)→ 12/23(1989-2018)→ 2019年はなし → 2/23(2020-)\n if (year <= 1988) {\n add(4, 29, \"天皇誕生日\");\n } else if (year <= 2018) {\n add(12, 23, \"天皇誕生日\");\n } else if (year >= 2020) {\n add(2, 23, \"天皇誕生日\");\n }\n }\n if (year >= 2007) add(4, 29, \"昭和の日\");\n if (year >= 1949) add(5, 3, \"憲法記念日\");\n if (year >= 1989 && year <= 2006) add(4, 29, \"みどりの日\");\n if (year >= 2007) add(5, 4, \"みどりの日\");\n if (year >= 1949) add(5, 5, \"こどもの日\");\n if (year >= 1996) {\n // 海の日: 7/20(〜2002)→ 第3月曜(2003-)。2020/2021 は東京五輪特例\n if (year <= 2002) {\n add(7, 20, \"海の日\");\n } else if (year === 2020) {\n add(7, 23, \"海の日\");\n } else if (year === 2021) {\n add(7, 22, \"海の日\");\n } else {\n add(7, monday(3, 7), \"海の日\");\n }\n }\n if (year >= 2016) {\n // 山の日: 8/11。2020/2021 は東京五輪特例\n if (year === 2020) {\n add(8, 10, \"山の日\");\n } else if (year === 2021) {\n add(8, 8, \"山の日\");\n } else {\n add(8, 11, \"山の日\");\n }\n }\n if (year >= 1949) add(3, springEquinox, \"春分の日\");\n if (year >= 1966) {\n // 敬老の日: 9/15(〜2002)→ 第3月曜(2003-)\n add(9, year <= 2002 ? 15 : monday(3, 9), \"敬老の日\");\n }\n if (year >= 1949) add(9, fallEquinox, \"秋分の日\");\n if (year >= 1966) {\n // 体育の日: 10/10(〜1999)→ 第2月曜(2000-2019)→ スポーツの日(2020-)。\n // 2020/2021 は東京五輪特例\n if (year <= 1999) {\n add(10, 10, \"体育の日\");\n } else if (year <= 2019) {\n add(10, monday(2, 10), \"体育の日\");\n } else if (year === 2020) {\n add(7, 24, \"スポーツの日\");\n } else if (year === 2021) {\n add(7, 23, \"スポーツの日\");\n } else {\n add(10, monday(2, 10), \"スポーツの日\");\n }\n }\n if (year >= 1949) add(11, 3, \"文化の日\");\n if (year >= 1949) add(11, 23, \"勤労感謝の日\");\n\n // ── ② 特例の祝日 ──\n for (const { year: y, month: m, day: d, name } of ONE_OFF_HOLIDAYS) {\n if (y === year) add(m, d, name);\n }\n\n const inList = (month: number, day: number): boolean =>\n list.some((h) => h.month === month && h.day === day);\n\n // ── ③ 振替休日(1973年の法改正により同年4月12日から施行): 祝日が日曜に当たるとき、直後の祝日でない日を休日とする ──\n if (year >= 1973) {\n const substituteFrom = createDate(1973, 3, 12).getTime(); // 制度施行日 1973-04-12\n for (const h of [...list]) {\n if (dayOfWeek(year, h.month, h.day) !== 0) continue;\n const base = createDate(year, h.month - 1, h.day);\n if (base.getTime() < substituteFrom) continue;\n for (let i = 1; i <= 7; i++) {\n const next = addDays(base, i);\n if (!inList(next.getMonth() + 1, next.getDate())) {\n add(next.getMonth() + 1, next.getDate(), \"振替休日\");\n break;\n }\n }\n }\n }\n\n // ── ④ 国民の休日(1986年の法改正以降): 祝日(日曜を除く)に挟まれた平日を休日とする ──\n if (year >= 1986) {\n for (let month = 1; month <= 12; month++) {\n const days = createDate(year, month, 0).getDate();\n for (let day = 1; day <= days; day++) {\n if (inList(month, day)) continue;\n const date = createDate(year, month - 1, day);\n if (date.getDay() === 0) continue;\n const prev = addDays(date, -1);\n const next = addDays(date, 1);\n if (\n inList(prev.getMonth() + 1, prev.getDate()) &&\n inList(next.getMonth() + 1, next.getDate())\n ) {\n add(month, day, \"国民の休日\");\n }\n }\n }\n }\n\n return list;\n}\n\n/** 年の祝日一覧と検索用インデックス。キャッシュして描画ごとの参照を高速化する */\ninterface HolidayIndex {\n /** 祝日一覧(算出順) */\n list: YearHoliday[];\n /** 月ごとの day → 名称インデックス。祝日判定は参照1回で済む */\n byMonth: Map<number, Map<number, string>>;\n}\n\n/**\n * 祝日一覧に月・日のインデックスを張る。\n */\nfunction toIndex(list: YearHoliday[]): HolidayIndex {\n const byMonth = new Map<number, Map<number, string>>();\n for (const h of list) {\n let days = byMonth.get(h.month);\n if (days === undefined) {\n days = new Map<number, string>();\n byMonth.set(h.month, days);\n }\n days.set(h.day, h.name);\n }\n return { list, byMonth };\n}\n\n/** 年の計算結果キャッシュ(同じ年を何度も参照する描画用途のため) */\nconst holidayCache = new Map<number, HolidayIndex>();\n\n/** 祝日インデックスを取得する。対象外ロケール・範囲外の年は null */\nfunction holidayIndexOf(date: Date, locale: Locale): HolidayIndex | null {\n if (locale !== \"ja\") return null;\n const year = date.getFullYear();\n if (year < HOLIDAY_MIN_YEAR || year > HOLIDAY_MAX_YEAR) return null;\n const cached = holidayCache.get(year);\n if (cached !== undefined) return cached;\n const index = toIndex(holidaysOfYear(year));\n holidayCache.set(year, index);\n return index;\n}\n\n/** 日付が祝日(日本の国民の祝日・振替休日・国民の休日)か判定する。対象外ロケール/年は false */\nexport function isHoliday(date: Date, locale: Locale = \"ja\"): boolean {\n assertValidDate(date);\n const index = holidayIndexOf(date, locale);\n if (index === null) return false;\n return (\n index.byMonth.get(date.getMonth() + 1)?.get(date.getDate()) !== undefined\n );\n}\n\n/** 日付の祝日名を返す。祝日でない・対象外ロケール/年は undefined */\nexport function getHolidayName(\n date: Date,\n locale: Locale = \"ja\",\n): string | undefined {\n assertValidDate(date);\n const index = holidayIndexOf(date, locale);\n if (index === null) return undefined;\n return index.byMonth.get(date.getMonth() + 1)?.get(date.getDate());\n}\n\n// ─── 営業日 ───────────────────────────────────────────────\n\n/** 日付が営業日(平日かつ祝日でない)か判定する */\nexport function isBusinessDay(date: Date, locale: Locale = \"ja\"): boolean {\n assertValidDate(date);\n if (date.getDay() === 0 || date.getDay() === 6) return false;\n return !isHoliday(date, locale);\n}\n\n/** 加算する営業日数が整数であることを検証する */\nfunction assertBusinessAmount(amount: number): void {\n if (!Number.isInteger(amount)) {\n throw new RangeError(`Invalid amount: ${amount} (expected an integer)`);\n }\n}\n\n/**\n * 日付に営業日数を加算する(負数で減算)。土日・祝日はスキップされる。\n * 加算の起点は date そのもの(date 自体は数えない)。date === 戻り値になるのは amount = 0 のとき。\n * 例: 2026-05-01(金)に 1 を足すと 2026-05-07(木)になる(5/3-5/6 が祝日)。\n */\nexport function addBusinessDays(\n date: Date,\n amount: number,\n locale: Locale = \"ja\",\n): Date {\n assertValidDate(date);\n assertBusinessAmount(amount);\n const result = new Date(date.getTime());\n const step = amount >= 0 ? 1 : -1;\n let remaining = Math.abs(amount);\n while (remaining > 0) {\n result.setDate(result.getDate() + step);\n if (isBusinessDay(result, locale)) remaining--;\n }\n return result;\n}\n\n/**\n * 2つの日付の間の営業日数(to - from 方向)を返す。マイナスもありうる。\n * from 自身は数えず、to は数える。例: 月曜→火曜 = 1、金曜→翌月曜 = 1(土日はスキップ)。\n * `addBusinessDays(from, n) === to` と `diffInBusinessDays(from, to) === n` は同値。\n */\nexport function diffInBusinessDays(\n from: Date,\n to: Date,\n locale: Locale = \"ja\",\n): number {\n assertValidDate(from);\n assertValidDate(to);\n const sign = to.getTime() >= from.getTime() ? 1 : -1;\n const cursor = new Date(from.getTime());\n let count = 0;\n for (;;) {\n cursor.setDate(cursor.getDate() + sign);\n if (\n sign > 0\n ? cursor.getTime() > to.getTime()\n : cursor.getTime() < to.getTime()\n ) {\n break;\n }\n if (isBusinessDay(cursor, locale)) count++;\n }\n return count * sign;\n}\n","import { isHoliday } from \"./holidays.ts\";\nimport type { Locale, WeekStart } from \"./types.ts\";\nimport {\n assertValidDate,\n assertValidWeekStart,\n assertValidYear,\n assertValidYearMonth,\n createDate,\n} from \"./validation.ts\";\n\nexport interface CalendarCellState {\n isWeekend: boolean;\n /** 祝日かどうか(holidayLocale に従って判定。指定なしは \"ja\") */\n isHoliday: boolean;\n isToday: boolean;\n isHighlight: boolean;\n isInRange: boolean;\n isDisabled: boolean;\n}\n\n/** 日付範囲(from <= to) */\nexport interface DateRange {\n from: Date;\n to: Date;\n}\n\n/**\n * 2つの日付を from <= to の順にソートした範囲を返す。\n * どちらかが null なら undefined(範囲なし)。\n */\nexport function sortRange(\n a: Date | null,\n b: Date | null,\n): DateRange | undefined {\n if (a === null || b === null) return undefined;\n return a.getTime() <= b.getTime() ? { from: a, to: b } : { from: b, to: a };\n}\n\n/** 月初日(1日)を返す */\nexport function firstDayOfMonth(year: number, month: number): Date {\n assertValidYearMonth(year, month);\n return createDate(year, month - 1, 1);\n}\n\n/** 月末日を返す */\nexport function lastDayOfMonth(year: number, month: number): Date {\n assertValidYearMonth(year, month);\n return createDate(year, month, 0);\n}\n\n/**\n * 月の日付グリッドを生成する(6行×7列)\n * 各セルは日数(1-31)または null(空欄)\n */\nexport function buildMonthGrid(\n year: number,\n month: number,\n weekStart: WeekStart,\n): (number | null)[][] {\n assertValidYearMonth(year, month);\n assertValidWeekStart(weekStart);\n\n const daysInMonth = lastDayOfMonth(year, month).getDate();\n let skip = firstDayOfMonth(year, month).getDay();\n if (weekStart === \"monday\") {\n skip = (skip + 6) % 7;\n }\n\n const grid: (number | null)[][] = [];\n let day = 1;\n for (let week = 0; week < 6; week++) {\n const row: (number | null)[] = [];\n for (let col = 0; col < 7; col++) {\n if (day > daysInMonth || (week === 0 && col < skip)) {\n row.push(null);\n } else {\n row.push(day++);\n }\n }\n grid.push(row);\n }\n return grid;\n}\n\n/** 範囲(from/to)が有効であることを検証する */\nfunction assertValidRange(from: Date, to: Date): void {\n assertValidDate(from);\n assertValidDate(to);\n if (from.getTime() > to.getTime()) {\n throw new RangeError(\"Invalid range: from must not be after to\");\n }\n}\n\n/** 日付が範囲内に含まれるか */\nexport function isDateInRange(\n date: Date,\n range?: { from: Date; to: Date },\n): boolean {\n if (!range) return false;\n assertValidRange(range.from, range.to);\n assertValidDate(date);\n const time = date.getTime();\n return time >= range.from.getTime() && time <= range.to.getTime();\n}\n\n/** 日付が今日と一致するか(日付のみ比較) */\nexport function isSameDay(a: Date, b: Date): boolean {\n assertValidDate(a);\n assertValidDate(b);\n return (\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate()\n );\n}\n\n/** 日付セルの表示状態を計算する */\nexport function getCalendarCellState(\n date: Date,\n options: {\n today?: Date;\n highlight?: Date;\n range?: { from: Date; to: Date };\n isDateDisabled?: (date: Date) => boolean;\n /** 祝日判定に使うロケール。省略時は \"ja\"(isHoliday のデフォルト) */\n holidayLocale?: Locale;\n } = {},\n): CalendarCellState {\n assertValidDate(date);\n return {\n isWeekend: date.getDay() === 0 || date.getDay() === 6,\n isHoliday: isHoliday(date, options.holidayLocale),\n isToday: options.today !== undefined && isSameDay(date, options.today),\n isHighlight:\n options.highlight !== undefined && isSameDay(date, options.highlight),\n isInRange:\n options.range !== undefined && isDateInRange(date, options.range),\n isDisabled: options.isDateDisabled?.(date) ?? false,\n };\n}\n\n/** 日付が範囲の開始年から終了年までの月リストを返す */\nexport function getMonthRange(\n from: Date,\n to: Date,\n): { year: number; month: number }[] {\n assertValidRange(from, to);\n const start = from.getFullYear() * 12 + from.getMonth();\n const end = to.getFullYear() * 12 + to.getMonth();\n return Array.from({ length: end - start + 1 }, (_, i) => {\n const n = start + i;\n return { year: Math.floor(n / 12), month: (n % 12) + 1 };\n });\n}\n\n/** グレゴリオ暦のうるう年判定(4で割れるが100では割れない、または400で割れる) */\nexport function isLeapYear(year: number): boolean {\n assertValidYear(year);\n return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n}\n\n/** 月の日数(1-31)を返す */\nexport function daysInMonth(year: number, month: number): number {\n assertValidYearMonth(year, month);\n return lastDayOfMonth(year, month).getDate();\n}\n"],"mappings":";;AAGA,MAAa,WAAW;;AAExB,MAAa,WAAW;;AAGxB,SAAS,qBACP,MACA,OACA,KACA,KACM;CACN,IAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,OAAO,QAAQ,KACrD,MAAM,IAAI,WACR,WAAW,KAAK,IAAI,MAAM,gCAAgC,IAAI,OAAO,IAAI,EAC3E;AAEJ;;AAGA,SAAgB,gBAAgB,MAAoB;CAClD,qBAAqB,QAAQ,MAAA,GAAgB,QAAQ;AACvD;;AAGA,SAAgB,iBAAiB,OAAqB;CACpD,qBAAqB,SAAS,OAAO,GAAG,EAAE;AAC5C;;AAGA,SAAgB,qBAAqB,MAAc,OAAqB;CACtE,gBAAgB,IAAI;CACpB,iBAAiB,KAAK;AACxB;;AAGA,SAAgB,qBAAqB,WAAyB;CAC5D,IAAI,cAAc,YAAY,cAAc,UAC1C,MAAM,IAAI,WACR,uBAAuB,UAAU,kCACnC;AAEJ;;AAGA,SAAgB,gBAAgB,MAAkB;CAChD,IAAI,EAAE,gBAAgB,SAAS,OAAO,MAAM,KAAK,QAAQ,CAAC,GACxD,MAAM,IAAI,WAAW,iBAAiB,OAAO,IAAI,GAAG;AAExD;;;;;;;;;;;AAYA,SAAgB,WACd,MACA,YACA,KACM;CACN,gBAAgB,IAAI;CACpB,qBAAqB,cAAc,YAAY,GAAG,EAAE;CACpD,qBAAqB,OAAO,KAAK,GAAG,EAAE;CACtC,MAAM,uBAAO,IAAI,KAAK,CAAC;CACvB,KAAK,SAAS,GAAG,GAAG,GAAG,CAAC;CACxB,KAAK,YAAY,MAAM,YAAY,GAAG;CACtC,OAAO;AACT;;;;AC/DA,SAAS,WACP,QACA,UACA,gBAAmC,UACvB;CACZ,MAAM,UAAU,QAA2B,CAAC,GAAG,IAAI,MAAM,CAAC,GAAG,IAAI,EAAG;CACpE,OAAO;EACL;EACA;EACA;EACA,gBAAgB,OAAO,QAAQ;EAC/B,qBAAqB,OAAO,aAAa;CAC3C;AACF;AAEA,MAAa,UAAsC;CACjD,IAAI,WACF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,GACA;EAAC;EAAO;EAAO;EAAO;EAAO;EAAO;EAAO;CAAK,GAChD;EAAC;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;CAAI,CAC3C;CACA,IAAI,WACF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,GACA;EAAC;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;CAAG,CACpC;CACA,IAAI,WACF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,GACA;EAAC;EAAO;EAAO;EAAO;EAAO;EAAO;EAAO;CAAK,GAChD;EAAC;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;CAAI,CAC3C;CACA,IAAI,WACF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,GACA;EAAC;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;CAAI,CAC3C;CACA,IAAI,WACF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,GACA;EAAC;EAAQ;EAAQ;EAAQ;EAAQ;EAAQ;EAAQ;CAAM,GACvD;EAAC;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;CAAI,CAC3C;CACA,IAAI,WACF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,GACA;EAAC;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;CAAG,CACpC;CACA,IAAI,WACF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,GACA;EAAC;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;CAAG,CACpC;AACF;;AAGA,SAAgB,cAAc,QAA4B;CACxD,MAAM,OAAO,QAAQ;CACrB,IAAI,SAAS,KAAA,GACX,MAAM,IAAI,WAAW,oBAAoB,OAAO,EAAE;CAEpD,OAAO;AACT;AAEA,SAAgB,kBACd,QACA,WACmB;CACnB,qBAAqB,SAAS;CAC9B,MAAM,OAAO,cAAc,MAAM;CACjC,OAAO,cAAc,WAAW,KAAK,iBAAiB,KAAK;AAC7D;AAEA,SAAgB,aAAa,QAAgB,OAAuB;CAClE,iBAAiB,KAAK;CAEtB,OADa,cAAc,MACjB,CAAC,CAAC,OAAO,QAAQ;AAC7B;;;;ACnKA,SAAS,aAAa,QAAsB;CAC1C,IAAI,CAAC,OAAO,UAAU,MAAM,GAC1B,MAAM,IAAI,WAAW,mBAAmB,OAAO,uBAAuB;AAE1E;;;;;;AAOA,SAAgB,QAAQ,MAAY,QAAsB;CACxD,gBAAgB,IAAI;CACpB,aAAa,MAAM;CACnB,MAAM,SAAS,IAAI,KAAK,KAAK,QAAQ,CAAC;CACtC,OAAO,QAAQ,OAAO,QAAQ,IAAI,MAAM;CACxC,OAAO;AACT;;AAGA,SAAgB,SAAS,MAAY,QAAsB;CACzD,OAAO,QAAQ,MAAM,SAAS,CAAC;AACjC;;;;;;;AAQA,SAAgB,UAAU,MAAY,QAAsB;CAC1D,gBAAgB,IAAI;CACpB,aAAa,MAAM;CACnB,MAAM,SAAS,WAAW,IAAI;CAC9B,MAAM,YAAY,KAAK,QAAQ;CAC/B,OAAO,QAAQ,CAAC;CAChB,OAAO,SAAS,OAAO,SAAS,IAAI,MAAM;CAC1C,MAAM,UAAU,cAAc,MAAM;CACpC,OAAO,QAAQ,KAAK,IAAI,WAAW,OAAO,CAAC;CAE3C,OAAO,SACL,KAAK,SAAS,GACd,KAAK,WAAW,GAChB,KAAK,WAAW,GAChB,KAAK,gBAAgB,CACvB;CACA,OAAO;AACT;;AAGA,SAAgB,SAAS,MAAY,QAAsB;CACzD,OAAO,UAAU,MAAM,SAAS,EAAE;AACpC;;AAGA,SAAS,cAAc,MAAoB;CACzC,OAAO,IAAI,KAAK,KAAK,YAAY,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,CAAC,CAAC,QAAQ;AACtE;;AAKA,SAAgB,WAAW,MAAkB;CAC3C,gBAAgB,IAAI;CACpB,OAAO,WAAW,KAAK,YAAY,GAAG,KAAK,SAAS,GAAG,KAAK,QAAQ,CAAC;AACvE;;AAGA,SAAgB,SAAS,MAAkB;CACzC,MAAM,SAAS,WAAW,IAAI;CAC9B,OAAO,SAAS,IAAI,IAAI,IAAI,GAAG;CAC/B,OAAO;AACT;;AAGA,SAAgB,YAAY,MAAY,YAAuB,UAAgB;CAC7E,gBAAgB,IAAI;CACpB,qBAAqB,SAAS;CAC9B,MAAM,MAAM,WAAW,IAAI;CAE3B,OAAO,QAAQ,KAAK,EADL,cAAc,WAAW,IAAI,OAAO,KAAK,IAAI,OAAO,IAAI,KAAK,EACjD;AAC7B;;AAGA,SAAgB,UAAU,MAAY,YAAuB,UAAgB;CAC3E,OAAO,SAAS,QAAQ,YAAY,MAAM,SAAS,GAAG,CAAC,CAAC;AAC1D;;AAGA,SAAgB,aAAa,MAAkB;CAC7C,gBAAgB,IAAI;CACpB,OAAO,WAAW,KAAK,YAAY,GAAG,KAAK,SAAS,GAAG,CAAC;AAC1D;;AAGA,SAAgB,WAAW,MAAkB;CAC3C,OAAO,SAAS,WAAW,KAAK,YAAY,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,CAAC;AACxE;;AAGA,SAAgB,YAAY,MAAkB;CAC5C,gBAAgB,IAAI;CACpB,OAAO,WAAW,KAAK,YAAY,GAAG,GAAG,CAAC;AAC5C;;AAGA,SAAgB,UAAU,MAAkB;CAC1C,OAAO,SAAS,WAAW,KAAK,YAAY,GAAG,IAAI,CAAC,CAAC;AACvD;;AAKA,SAAS,UAAU,MAAoB;CACrC,MAAM,sBAAM,IAAI,KAAK,CAAC;CACtB,IAAI,eAAe,KAAK,YAAY,GAAG,KAAK,SAAS,GAAG,KAAK,QAAQ,CAAC;CACtE,OAAO,IAAI,QAAQ,IAAI;AACzB;;;;;AAMA,SAAgB,mBAAmB,MAAY,IAAkB;CAC/D,gBAAgB,IAAI;CACpB,gBAAgB,EAAE;CAClB,OAAO,UAAU,EAAE,IAAI,UAAU,IAAI;AACvC;;AAGA,SAAgB,qBAAqB,MAAY,IAAkB;CACjE,gBAAgB,IAAI;CACpB,gBAAgB,EAAE;CAClB,QACG,GAAG,YAAY,IAAI,KAAK,YAAY,KAAK,MACzC,GAAG,SAAS,IAAI,KAAK,SAAS;AAEnC;;AAGA,SAAgB,oBAAoB,MAAY,IAAkB;CAChE,gBAAgB,IAAI;CACpB,gBAAgB,EAAE;CAClB,OAAO,GAAG,YAAY,IAAI,KAAK,YAAY;AAC7C;;AAKA,SAAgB,SAAS,MAAY,OAAsB;CACzD,gBAAgB,IAAI;CACpB,gBAAgB,KAAK;CACrB,OAAO,KAAK,QAAQ,IAAI,MAAM,QAAQ;AACxC;;AAGA,SAAgB,QAAQ,MAAY,OAAsB;CACxD,gBAAgB,IAAI;CACpB,gBAAgB,KAAK;CACrB,OAAO,KAAK,QAAQ,IAAI,MAAM,QAAQ;AACxC;;AAGA,SAAgB,YAAY,GAAS,GAAkB;CACrD,gBAAgB,CAAC;CACjB,gBAAgB,CAAC;CACjB,OAAO,EAAE,YAAY,MAAM,EAAE,YAAY,KAAK,EAAE,SAAS,MAAM,EAAE,SAAS;AAC5E;;AAGA,SAAgB,WAAW,GAAS,GAAkB;CACpD,gBAAgB,CAAC;CACjB,gBAAgB,CAAC;CACjB,OAAO,EAAE,YAAY,MAAM,EAAE,YAAY;AAC3C;;AAGA,SAAgB,UAAU,MAAqB;CAC7C,gBAAgB,IAAI;CACpB,MAAM,MAAM,KAAK,OAAO;CACxB,OAAO,QAAQ,KAAK,QAAQ;AAC9B;;AAKA,SAAgB,WAAW,MAAoB;CAC7C,gBAAgB,IAAI;CACpB,MAAM,MAAM,WAAW,IAAI;CAG3B,MAAM,WAAW,QAAQ,KAAK,KAFb,IAAI,OAAO,IAAI,KAAK,CAEI;CACzC,MAAM,OAAO,WAAW,SAAS,YAAY,GAAG,GAAG,CAAC;CAEpD,MAAM,gBAAgB,QAAQ,OAAO,KADhB,KAAK,OAAO,IAAI,KAAK,IACa,KAAK,CAAC;CAC7D,OAAO,KAAK,MAAM,mBAAmB,eAAe,QAAQ,IAAI,CAAC,IAAI;AACvE;;;;;;AAOA,SAAgB,cACd,MACA,YAAuB,UACf;CACR,gBAAgB,IAAI;CACpB,qBAAqB,SAAS;CAC9B,MAAM,MAAM,WAAW,IAAI;CAE3B,MAAM,gBAAgB,YADT,WAAW,IAAI,YAAY,GAAG,GAAG,CACT,GAAG,SAAS;CACjD,OAAO,KAAK,MAAM,mBAAmB,eAAe,GAAG,IAAI,CAAC,IAAI;AAClE;;AAGA,SAAgB,aAAa,MAAoB;CAC/C,gBAAgB,IAAI;CACpB,OAAO,mBAAmB,YAAY,IAAI,GAAG,IAAI,IAAI;AACvD;;AAKA,SAAgB,UAAU,MAAY,KAAW,KAAiB;CAChE,gBAAgB,IAAI;CACpB,gBAAgB,GAAG;CACnB,gBAAgB,GAAG;CACnB,IAAI,KAAK,QAAQ,IAAI,IAAI,QAAQ,GAAG,OAAO;CAC3C,IAAI,KAAK,QAAQ,IAAI,IAAI,QAAQ,GAAG,OAAO;CAC3C,OAAO;AACT;AAEA,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;AAuBjB,SAAgB,WACd,MACA,SACA,SAAiB,MACT;CACR,gBAAgB,IAAI;CACpB,MAAM,OAAO,cAAc,MAAM;CACjC,OAAO,QAAQ,QAAQ,WAAW,UAAU;EAC1C,QAAQ,OAAR;GACE,KAAK,QACH,OAAO,OAAO,KAAK,YAAY,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;GACnD,KAAK,MACH,OAAO,OAAO,KAAK,YAAY,IAAI,GAAG,CAAC,CAAC,SAAS,GAAG,GAAG;GACzD,KAAK,QACH,OAAO,aAAa,QAAQ,KAAK,SAAS,IAAI,CAAC;GACjD,KAAK,MACH,OAAO,OAAO,KAAK,SAAS,IAAI,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;GACpD,KAAK,KACH,OAAO,OAAO,KAAK,SAAS,IAAI,CAAC;GACnC,KAAK,MACH,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;GAC/C,KAAK,KACH,OAAO,OAAO,KAAK,QAAQ,CAAC;GAC9B,KAAK,OACH,OAAO,KAAK,SAAS,KAAK,OAAO;GACnC,SACE,OAAO;EACX;CACF,CAAC;AACH;;;;AC3RA,MAAa,mBAAmB;;AAGhC,MAAa,mBAAmB;;AAGhC,MAAM,mBAAmD;CACvD;EAAE,MAAM;EAAM,OAAO;EAAG,KAAK;EAAI,MAAM;CAAe;CACtD;EAAE,MAAM;EAAM,OAAO;EAAG,KAAK;EAAI,MAAM;CAAY;CACnD;EAAE,MAAM;EAAM,OAAO;EAAI,KAAK;EAAI,MAAM;CAAW;CACnD;EAAE,MAAM;EAAM,OAAO;EAAG,KAAK;EAAG,MAAM;CAAe;CACrD;EAAE,MAAM;EAAM,OAAO;EAAG,KAAK;EAAG,MAAM;CAAS;CAC/C;EAAE,MAAM;EAAM,OAAO;EAAI,KAAK;EAAI,MAAM;CAAU;AACpD;;AAeA,SAAS,UAAU,MAAc,OAAe,KAAqB;CACnE,OAAO,WAAW,MAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,OAAO;AACjD;;;;;;;;;;;AAYA,SAAS,eAAe,MAA6B;CACnD,MAAM,OAAsB,CAAC;CAC7B,MAAM,OAAO,OAAe,KAAa,SAAuB;EAC9D,KAAK,KAAK;GAAE;GAAO;GAAK;EAAK,CAAC;CAChC;;CAEA,MAAM,cAAc,SAAiB,GAAW,UAA0B;EAGxE,OAAO,KADS,UADF,WAAW,MAAM,QAAQ,GAAG,CACZ,CAAC,CAAC,OAAO,IAAI,KAAK,KAC3B,IAAI,KAAK;CAChC;CACA,MAAM,UAAU,GAAW,UAA0B,WAAW,GAAG,GAAG,KAAK;CAC3E,MAAM,gBAAgB,KAAK,MACzB,UAAU,WAAY,OAAO,QAAQ,KAAK,OAAO,OAAO,QAAQ,CAAC,CACnE;CACA,MAAM,cAAc,KAAK,MACvB,UAAU,WAAY,OAAO,QAAQ,KAAK,OAAO,OAAO,QAAQ,CAAC,CACnE;CAGA,IAAI,QAAQ,MAAM,IAAI,GAAG,GAAG,IAAI;CAChC,IAAI,QAAQ,MAEV,IAAI,GAAG,QAAQ,OAAO,KAAK,OAAO,GAAG,CAAC,GAAG,MAAM;CAEjD,IAAI,QAAQ,MAAM,IAAI,GAAG,IAAI,QAAQ;CACrC,IAAI,QAAQ,MAAM;EAEhB,IAAI,QAAQ,MACV,IAAI,GAAG,IAAI,OAAO;OACb,IAAI,QAAQ,MACjB,IAAI,IAAI,IAAI,OAAO;OACd,IAAI,QAAQ,MACjB,IAAI,GAAG,IAAI,OAAO;CAEtB;CACA,IAAI,QAAQ,MAAM,IAAI,GAAG,IAAI,MAAM;CACnC,IAAI,QAAQ,MAAM,IAAI,GAAG,GAAG,OAAO;CACnC,IAAI,QAAQ,QAAQ,QAAQ,MAAM,IAAI,GAAG,IAAI,OAAO;CACpD,IAAI,QAAQ,MAAM,IAAI,GAAG,GAAG,OAAO;CACnC,IAAI,QAAQ,MAAM,IAAI,GAAG,GAAG,OAAO;CACnC,IAAI,QAAQ,MAAM;EAEhB,IAAI,QAAQ,MACV,IAAI,GAAG,IAAI,KAAK;OACX,IAAI,SAAS,MAClB,IAAI,GAAG,IAAI,KAAK;OACX,IAAI,SAAS,MAClB,IAAI,GAAG,IAAI,KAAK;OAEhB,IAAI,GAAG,OAAO,GAAG,CAAC,GAAG,KAAK;CAE9B;CACA,IAAI,QAAQ,MAAM;EAEhB,IAAI,SAAS,MACX,IAAI,GAAG,IAAI,KAAK;OACX,IAAI,SAAS,MAClB,IAAI,GAAG,GAAG,KAAK;OAEf,IAAI,GAAG,IAAI,KAAK;CAEpB;CACA,IAAI,QAAQ,MAAM,IAAI,GAAG,eAAe,MAAM;CAC9C,IAAI,QAAQ,MAEV,IAAI,GAAG,QAAQ,OAAO,KAAK,OAAO,GAAG,CAAC,GAAG,MAAM;CAEjD,IAAI,QAAQ,MAAM,IAAI,GAAG,aAAa,MAAM;CAC5C,IAAI,QAAQ,MAAM;EAGhB,IAAI,QAAQ,MACV,IAAI,IAAI,IAAI,MAAM;OACb,IAAI,QAAQ,MACjB,IAAI,IAAI,OAAO,GAAG,EAAE,GAAG,MAAM;OACxB,IAAI,SAAS,MAClB,IAAI,GAAG,IAAI,QAAQ;OACd,IAAI,SAAS,MAClB,IAAI,GAAG,IAAI,QAAQ;OAEnB,IAAI,IAAI,OAAO,GAAG,EAAE,GAAG,QAAQ;CAEnC;CACA,IAAI,QAAQ,MAAM,IAAI,IAAI,GAAG,MAAM;CACnC,IAAI,QAAQ,MAAM,IAAI,IAAI,IAAI,QAAQ;CAGtC,KAAK,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,UAAU,kBAChD,IAAI,MAAM,MAAM,IAAI,GAAG,GAAG,IAAI;CAGhC,MAAM,UAAU,OAAe,QAC7B,KAAK,MAAM,MAAM,EAAE,UAAU,SAAS,EAAE,QAAQ,GAAG;CAGrD,IAAI,QAAQ,MAAM;EAChB,MAAM,iBAAiB,WAAW,MAAM,GAAG,EAAE,CAAC,CAAC,QAAQ;EACvD,KAAK,MAAM,KAAK,CAAC,GAAG,IAAI,GAAG;GACzB,IAAI,UAAU,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,GAAG;GAC3C,MAAM,OAAO,WAAW,MAAM,EAAE,QAAQ,GAAG,EAAE,GAAG;GAChD,IAAI,KAAK,QAAQ,IAAI,gBAAgB;GACrC,KAAK,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK;IAC3B,MAAM,OAAO,QAAQ,MAAM,CAAC;IAC5B,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,GAAG,KAAK,QAAQ,CAAC,GAAG;KAChD,IAAI,KAAK,SAAS,IAAI,GAAG,KAAK,QAAQ,GAAG,MAAM;KAC/C;IACF;GACF;EACF;CACF;CAGA,IAAI,QAAQ,MACV,KAAK,IAAI,QAAQ,GAAG,SAAS,IAAI,SAAS;EACxC,MAAM,OAAO,WAAW,MAAM,OAAO,CAAC,CAAC,CAAC,QAAQ;EAChD,KAAK,IAAI,MAAM,GAAG,OAAO,MAAM,OAAO;GACpC,IAAI,OAAO,OAAO,GAAG,GAAG;GACxB,MAAM,OAAO,WAAW,MAAM,QAAQ,GAAG,GAAG;GAC5C,IAAI,KAAK,OAAO,MAAM,GAAG;GACzB,MAAM,OAAO,QAAQ,MAAM,EAAE;GAC7B,MAAM,OAAO,QAAQ,MAAM,CAAC;GAC5B,IACE,OAAO,KAAK,SAAS,IAAI,GAAG,KAAK,QAAQ,CAAC,KAC1C,OAAO,KAAK,SAAS,IAAI,GAAG,KAAK,QAAQ,CAAC,GAE1C,IAAI,OAAO,KAAK,OAAO;EAE3B;CACF;CAGF,OAAO;AACT;;;;AAaA,SAAS,QAAQ,MAAmC;CAClD,MAAM,0BAAU,IAAI,IAAiC;CACrD,KAAK,MAAM,KAAK,MAAM;EACpB,IAAI,OAAO,QAAQ,IAAI,EAAE,KAAK;EAC9B,IAAI,SAAS,KAAA,GAAW;GACtB,uBAAO,IAAI,IAAoB;GAC/B,QAAQ,IAAI,EAAE,OAAO,IAAI;EAC3B;EACA,KAAK,IAAI,EAAE,KAAK,EAAE,IAAI;CACxB;CACA,OAAO;EAAE;EAAM;CAAQ;AACzB;;AAGA,MAAM,+BAAe,IAAI,IAA0B;;AAGnD,SAAS,eAAe,MAAY,QAAqC;CACvE,IAAI,WAAW,MAAM,OAAO;CAC5B,MAAM,OAAO,KAAK,YAAY;CAC9B,IAAI,OAAA,QAA2B,OAAA,MAAyB,OAAO;CAC/D,MAAM,SAAS,aAAa,IAAI,IAAI;CACpC,IAAI,WAAW,KAAA,GAAW,OAAO;CACjC,MAAM,QAAQ,QAAQ,eAAe,IAAI,CAAC;CAC1C,aAAa,IAAI,MAAM,KAAK;CAC5B,OAAO;AACT;;AAGA,SAAgB,UAAU,MAAY,SAAiB,MAAe;CACpE,gBAAgB,IAAI;CACpB,MAAM,QAAQ,eAAe,MAAM,MAAM;CACzC,IAAI,UAAU,MAAM,OAAO;CAC3B,OACE,MAAM,QAAQ,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,EAAE,IAAI,KAAK,QAAQ,CAAC,MAAM,KAAA;AAEpE;;AAGA,SAAgB,eACd,MACA,SAAiB,MACG;CACpB,gBAAgB,IAAI;CACpB,MAAM,QAAQ,eAAe,MAAM,MAAM;CACzC,IAAI,UAAU,MAAM,OAAO,KAAA;CAC3B,OAAO,MAAM,QAAQ,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,EAAE,IAAI,KAAK,QAAQ,CAAC;AACnE;;AAKA,SAAgB,cAAc,MAAY,SAAiB,MAAe;CACxE,gBAAgB,IAAI;CACpB,IAAI,KAAK,OAAO,MAAM,KAAK,KAAK,OAAO,MAAM,GAAG,OAAO;CACvD,OAAO,CAAC,UAAU,MAAM,MAAM;AAChC;;AAGA,SAAS,qBAAqB,QAAsB;CAClD,IAAI,CAAC,OAAO,UAAU,MAAM,GAC1B,MAAM,IAAI,WAAW,mBAAmB,OAAO,uBAAuB;AAE1E;;;;;;AAOA,SAAgB,gBACd,MACA,QACA,SAAiB,MACX;CACN,gBAAgB,IAAI;CACpB,qBAAqB,MAAM;CAC3B,MAAM,SAAS,IAAI,KAAK,KAAK,QAAQ,CAAC;CACtC,MAAM,OAAO,UAAU,IAAI,IAAI;CAC/B,IAAI,YAAY,KAAK,IAAI,MAAM;CAC/B,OAAO,YAAY,GAAG;EACpB,OAAO,QAAQ,OAAO,QAAQ,IAAI,IAAI;EACtC,IAAI,cAAc,QAAQ,MAAM,GAAG;CACrC;CACA,OAAO;AACT;;;;;;AAOA,SAAgB,mBACd,MACA,IACA,SAAiB,MACT;CACR,gBAAgB,IAAI;CACpB,gBAAgB,EAAE;CAClB,MAAM,OAAO,GAAG,QAAQ,KAAK,KAAK,QAAQ,IAAI,IAAI;CAClD,MAAM,SAAS,IAAI,KAAK,KAAK,QAAQ,CAAC;CACtC,IAAI,QAAQ;CACZ,SAAS;EACP,OAAO,QAAQ,OAAO,QAAQ,IAAI,IAAI;EACtC,IACE,OAAO,IACH,OAAO,QAAQ,IAAI,GAAG,QAAQ,IAC9B,OAAO,QAAQ,IAAI,GAAG,QAAQ,GAElC;EAEF,IAAI,cAAc,QAAQ,MAAM,GAAG;CACrC;CACA,OAAO,QAAQ;AACjB;;;;;;;AC7RA,SAAgB,UACd,GACA,GACuB;CACvB,IAAI,MAAM,QAAQ,MAAM,MAAM,OAAO,KAAA;CACrC,OAAO,EAAE,QAAQ,KAAK,EAAE,QAAQ,IAAI;EAAE,MAAM;EAAG,IAAI;CAAE,IAAI;EAAE,MAAM;EAAG,IAAI;CAAE;AAC5E;;AAGA,SAAgB,gBAAgB,MAAc,OAAqB;CACjE,qBAAqB,MAAM,KAAK;CAChC,OAAO,WAAW,MAAM,QAAQ,GAAG,CAAC;AACtC;;AAGA,SAAgB,eAAe,MAAc,OAAqB;CAChE,qBAAqB,MAAM,KAAK;CAChC,OAAO,WAAW,MAAM,OAAO,CAAC;AAClC;;;;;AAMA,SAAgB,eACd,MACA,OACA,WACqB;CACrB,qBAAqB,MAAM,KAAK;CAChC,qBAAqB,SAAS;CAE9B,MAAM,cAAc,eAAe,MAAM,KAAK,CAAC,CAAC,QAAQ;CACxD,IAAI,OAAO,gBAAgB,MAAM,KAAK,CAAC,CAAC,OAAO;CAC/C,IAAI,cAAc,UAChB,QAAQ,OAAO,KAAK;CAGtB,MAAM,OAA4B,CAAC;CACnC,IAAI,MAAM;CACV,KAAK,IAAI,OAAO,GAAG,OAAO,GAAG,QAAQ;EACnC,MAAM,MAAyB,CAAC;EAChC,KAAK,IAAI,MAAM,GAAG,MAAM,GAAG,OACzB,IAAI,MAAM,eAAgB,SAAS,KAAK,MAAM,MAC5C,IAAI,KAAK,IAAI;OAEb,IAAI,KAAK,KAAK;EAGlB,KAAK,KAAK,GAAG;CACf;CACA,OAAO;AACT;;AAGA,SAAS,iBAAiB,MAAY,IAAgB;CACpD,gBAAgB,IAAI;CACpB,gBAAgB,EAAE;CAClB,IAAI,KAAK,QAAQ,IAAI,GAAG,QAAQ,GAC9B,MAAM,IAAI,WAAW,0CAA0C;AAEnE;;AAGA,SAAgB,cACd,MACA,OACS;CACT,IAAI,CAAC,OAAO,OAAO;CACnB,iBAAiB,MAAM,MAAM,MAAM,EAAE;CACrC,gBAAgB,IAAI;CACpB,MAAM,OAAO,KAAK,QAAQ;CAC1B,OAAO,QAAQ,MAAM,KAAK,QAAQ,KAAK,QAAQ,MAAM,GAAG,QAAQ;AAClE;;AAGA,SAAgB,UAAU,GAAS,GAAkB;CACnD,gBAAgB,CAAC;CACjB,gBAAgB,CAAC;CACjB,OACE,EAAE,YAAY,MAAM,EAAE,YAAY,KAClC,EAAE,SAAS,MAAM,EAAE,SAAS,KAC5B,EAAE,QAAQ,MAAM,EAAE,QAAQ;AAE9B;;AAGA,SAAgB,qBACd,MACA,UAOI,CAAC,GACc;CACnB,gBAAgB,IAAI;CACpB,OAAO;EACL,WAAW,KAAK,OAAO,MAAM,KAAK,KAAK,OAAO,MAAM;EACpD,WAAW,UAAU,MAAM,QAAQ,aAAa;EAChD,SAAS,QAAQ,UAAU,KAAA,KAAa,UAAU,MAAM,QAAQ,KAAK;EACrE,aACE,QAAQ,cAAc,KAAA,KAAa,UAAU,MAAM,QAAQ,SAAS;EACtE,WACE,QAAQ,UAAU,KAAA,KAAa,cAAc,MAAM,QAAQ,KAAK;EAClE,YAAY,QAAQ,iBAAiB,IAAI,KAAK;CAChD;AACF;;AAGA,SAAgB,cACd,MACA,IACmC;CACnC,iBAAiB,MAAM,EAAE;CACzB,MAAM,QAAQ,KAAK,YAAY,IAAI,KAAK,KAAK,SAAS;CACtD,MAAM,MAAM,GAAG,YAAY,IAAI,KAAK,GAAG,SAAS;CAChD,OAAO,MAAM,KAAK,EAAE,QAAQ,MAAM,QAAQ,EAAE,IAAI,GAAG,MAAM;EACvD,MAAM,IAAI,QAAQ;EAClB,OAAO;GAAE,MAAM,KAAK,MAAM,IAAI,EAAE;GAAG,OAAQ,IAAI,KAAM;EAAE;CACzD,CAAC;AACH;;AAGA,SAAgB,WAAW,MAAuB;CAChD,gBAAgB,IAAI;CACpB,OAAQ,OAAO,MAAM,KAAK,OAAO,QAAQ,KAAM,OAAO,QAAQ;AAChE;;AAGA,SAAgB,YAAY,MAAc,OAAuB;CAC/D,qBAAqB,MAAM,KAAK;CAChC,OAAO,eAAe,MAAM,KAAK,CAAC,CAAC,QAAQ;AAC7C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typescript-calendar-lib/core",
3
- "version": "0.5.2",
3
+ "version": "0.5.4",
4
4
  "description": "Core date utilities and calendar data primitives for typescript-calendar-lib",
5
5
  "type": "module",
6
6
  "repository": {