@procedures/ics 0.6.0 → 0.8.0

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/dist/days.d.ts CHANGED
@@ -15,6 +15,17 @@ export declare function dateTime(date: string, label: string): number;
15
15
  * - A date that is not valid, or a result outside the years 0000 to 9999, throws a `RangeError`.
16
16
  */
17
17
  export declare function shiftDay(date: string, days: number): string;
18
+ /**
19
+ * This function gives the date `months` months after a date (`YYYY-MM-DD`). A negative number gives
20
+ * an earlier date. The number of months must be an integer.
21
+ *
22
+ * - When the day is not in the month of the result, the result is the last day of that month: one
23
+ * month after `2026-01-31` is `2026-02-28`.
24
+ * - For the arithmetic of `Date.UTC`, where the 31st goes into the next month, add the days to the
25
+ * 1st: `shiftDay(shiftMonth("2026-01-01", 1), 30)` is `2026-03-03`.
26
+ * - A date that is not valid, or a result outside the years 0000 to 9999, throws a `RangeError`.
27
+ */
28
+ export declare function shiftMonth(date: string, months: number): string;
18
29
  /**
19
30
  * This function gives the number of whole days from the date `from` to the date `to`
20
31
  * (`YYYY-MM-DD`). It is negative when `to` is before `from`, and 0 for the same date.
@@ -23,4 +34,15 @@ export declare function shiftDay(date: string, days: number): string;
23
34
  * - A text that is not a date throws a `RangeError`.
24
35
  */
25
36
  export declare function daysBetween(from: string, to: string): number;
37
+ /** This function gives the day of the week of a date (`YYYY-MM-DD`): 0 for Sunday to 6 for Saturday. */
38
+ export declare function weekdayOf(date: string): number;
39
+ /**
40
+ * This function gives the name of the day of the week of a date (`YYYY-MM-DD`). The default is the
41
+ * long English name ("Monday"). `locale` and `style` give another name from `Intl`. A date has no
42
+ * time zone, so the name is the same in each zone.
43
+ */
44
+ export declare function weekdayName(date: string, options?: {
45
+ readonly locale?: string;
46
+ readonly style?: "long" | "short" | "narrow";
47
+ }): string;
26
48
  //# sourceMappingURL=days.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"days.d.ts","sourceRoot":"","sources":["../src/days.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAO5D;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAM3D;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAE5D"}
1
+ {"version":3,"file":"days.d.ts","sourceRoot":"","sources":["../src/days.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAO5D;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAM3D;AAQD;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAU/D;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,wGAAwG;AACxG,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAA;CAAO,GAAG,MAAM,CAG1I"}
package/dist/days.js CHANGED
@@ -33,6 +33,33 @@ export function shiftDay(date, days) {
33
33
  throw new RangeError(`shiftDay: ${date} plus ${String(days)} days is not from the year 0000 to 9999`);
34
34
  return text.slice(0, 10);
35
35
  }
36
+ /** This function tells if a year has a 29th of February, in the Gregorian calendar (the year 0000 has one). */
37
+ const isLeapYear = (year) => year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
38
+ /** The number of days of each month of a year that is not a leap year. */
39
+ const MONTH_DAYS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
40
+ /**
41
+ * This function gives the date `months` months after a date (`YYYY-MM-DD`). A negative number gives
42
+ * an earlier date. The number of months must be an integer.
43
+ *
44
+ * - When the day is not in the month of the result, the result is the last day of that month: one
45
+ * month after `2026-01-31` is `2026-02-28`.
46
+ * - For the arithmetic of `Date.UTC`, where the 31st goes into the next month, add the days to the
47
+ * 1st: `shiftDay(shiftMonth("2026-01-01", 1), 30)` is `2026-03-03`.
48
+ * - A date that is not valid, or a result outside the years 0000 to 9999, throws a `RangeError`.
49
+ */
50
+ export function shiftMonth(date, months) {
51
+ if (!Number.isSafeInteger(months))
52
+ throw new RangeError(`shiftMonth: the number of months ${String(months)} is not an integer`);
53
+ dateTime(date, "shiftMonth");
54
+ const total = Number(date.slice(0, 4)) * 12 + Number(date.slice(5, 7)) - 1 + months;
55
+ const year = Math.floor(total / 12);
56
+ if (!(year >= 0 && year <= 9999))
57
+ throw new RangeError(`shiftMonth: ${date} plus ${String(months)} months is not from the year 0000 to 9999`);
58
+ const month = total - year * 12;
59
+ const last = month === 1 && isLeapYear(year) ? 29 : MONTH_DAYS[month];
60
+ const day = Math.min(Number(date.slice(8, 10)), last);
61
+ return `${String(year).padStart(4, "0")}-${String(month + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
62
+ }
36
63
  /**
37
64
  * This function gives the number of whole days from the date `from` to the date `to`
38
65
  * (`YYYY-MM-DD`). It is negative when `to` is before `from`, and 0 for the same date.
@@ -43,4 +70,17 @@ export function shiftDay(date, days) {
43
70
  export function daysBetween(from, to) {
44
71
  return (dateTime(to, "daysBetween") - dateTime(from, "daysBetween")) / DAY;
45
72
  }
73
+ /** This function gives the day of the week of a date (`YYYY-MM-DD`): 0 for Sunday to 6 for Saturday. */
74
+ export function weekdayOf(date) {
75
+ return new Date(dateTime(date, "weekdayOf")).getUTCDay();
76
+ }
77
+ /**
78
+ * This function gives the name of the day of the week of a date (`YYYY-MM-DD`). The default is the
79
+ * long English name ("Monday"). `locale` and `style` give another name from `Intl`. A date has no
80
+ * time zone, so the name is the same in each zone.
81
+ */
82
+ export function weekdayName(date, options = {}) {
83
+ const noon = dateTime(date, "weekdayName") + DAY / 2;
84
+ return new Intl.DateTimeFormat(options.locale ?? "en-US", { timeZone: "UTC", weekday: options.style ?? "long" }).format(noon);
85
+ }
46
86
  //# sourceMappingURL=days.js.map
package/dist/days.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"days.js","sourceRoot":"","sources":["../src/days.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,GAAG,GAAG,UAAU,CAAC;AAEvB,0BAA0B;AAC1B,MAAM,IAAI,GAAG,qBAAqB,CAAC;AAEnC;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,KAAa;IAClD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;IAC5E,gGAAgG;IAChG,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC;QAC7E,MAAM,IAAI,UAAU,CAAC,GAAG,KAAK,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;IACjG,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,IAAY;IACjD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,gCAAgC,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACxH,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,GAAG,IAAI,GAAG,GAAG,CAAC;IACrD,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACpG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,aAAa,IAAI,SAAS,MAAM,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;IACjI,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC3B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,EAAU;IAClD,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC,GAAG,GAAG,CAAC;AAC7E,CAAC"}
1
+ {"version":3,"file":"days.js","sourceRoot":"","sources":["../src/days.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,GAAG,GAAG,UAAU,CAAC;AAEvB,0BAA0B;AAC1B,MAAM,IAAI,GAAG,qBAAqB,CAAC;AAEnC;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,KAAa;IAClD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;IAC5E,gGAAgG;IAChG,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC;QAC7E,MAAM,IAAI,UAAU,CAAC,GAAG,KAAK,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;IACjG,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,IAAY;IACjD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,gCAAgC,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACxH,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,GAAG,IAAI,GAAG,GAAG,CAAC;IACrD,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACpG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,aAAa,IAAI,SAAS,MAAM,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;IACjI,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC3B,CAAC;AAED,+GAA+G;AAC/G,MAAM,UAAU,GAAG,CAAC,IAAY,EAAW,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,KAAK,CAAC,IAAI,IAAI,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC;AAEvG,0EAA0E;AAC1E,MAAM,UAAU,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAU,CAAC;AAE7E;;;;;;;;;GASG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,MAAc;IACrD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,oCAAoC,MAAM,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChI,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;IACpF,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IACpC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,eAAe,IAAI,SAAS,MAAM,CAAC,MAAM,CAAC,2CAA2C,CAAC,CAAC;IAC9I,MAAM,KAAK,GAAG,KAAK,GAAG,IAAI,GAAG,EAAE,CAAC;IAChC,MAAM,IAAI,GAAG,KAAK,KAAK,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAE,CAAC;IACvE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACtD,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;AAClH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,EAAU;IAClD,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC,GAAG,GAAG,CAAC;AAC7E,CAAC;AAED,wGAAwG;AACxG,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,OAAO,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;AAC3D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,OAAO,GAA+E,EAAE;IAChI,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;IACrD,OAAO,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,MAAM,IAAI,OAAO,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,IAAI,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAChI,CAAC"}
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ export * from "./module.js";
2
2
  export * from "./procedures.js";
3
3
  export * from "./ics.js";
4
4
  export * from "./write.js";
5
- export { localDate, zonedOffset } from "./zone.js";
6
- export { daysBetween, shiftDay } from "./days.js";
5
+ export { localDate, localTime, zonedOffset } from "./zone.js";
6
+ export { daysBetween, shiftDay, shiftMonth, weekdayName, weekdayOf } from "./days.js";
7
7
  export * from "./types.js";
8
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAE3B,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAClD,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAE3B,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtF,cAAc,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ export * from "./procedures.js";
4
4
  export * from "./ics.js";
5
5
  export * from "./write.js";
6
6
  // The calendar days: the date of an instant in a zone, and the arithmetic of dates
7
- export { localDate, zonedOffset } from "./zone.js";
8
- export { daysBetween, shiftDay } from "./days.js";
7
+ export { localDate, localTime, zonedOffset } from "./zone.js";
8
+ export { daysBetween, shiftDay, shiftMonth, weekdayName, weekdayOf } from "./days.js";
9
9
  export * from "./types.js";
10
10
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,mFAAmF;AACnF,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAClD,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,mFAAmF;AACnF,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtF,cAAc,YAAY,CAAC"}
@@ -5,11 +5,22 @@ import { type AnyProcedure } from "@procedures/client";
5
5
  export declare const icsParseProcedure: AnyProcedure;
6
6
  export declare const icsOccurrencesProcedure: AnyProcedure;
7
7
  export declare const icsWriteProcedure: AnyProcedure;
8
+ /** The part of `fetch` that `fetchCalendar` uses. A test or a host gives its own with the option `fetch`. */
9
+ export type FetchText = (url: string, init: {
10
+ headers: Record<string, string>;
11
+ signal: AbortSignal;
12
+ }) => Promise<{
13
+ ok: boolean;
14
+ status: number;
15
+ text(): Promise<string>;
16
+ }>;
8
17
  /**
9
18
  * This function gets the text of a calendar feed. The address of a private feed is a secret, so
10
- * an error never includes it.
19
+ * an error never includes it. The option `fetch` replaces the global `fetch`.
11
20
  */
12
- export declare function fetchCalendar(url: string, timeoutMs: number, signal?: AbortSignal): Promise<string>;
21
+ export declare function fetchCalendar(url: string, timeoutMs: number, signal?: AbortSignal, options?: {
22
+ readonly fetch?: FetchText | undefined;
23
+ }): Promise<string>;
13
24
  export declare const icsFetchProcedure: AnyProcedure;
14
25
  export declare const icsProcedures: AnyProcedure[];
15
26
  //# sourceMappingURL=procedures.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"procedures.d.ts","sourceRoot":"","sources":["../src/procedures.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAA+B,KAAK,YAAY,EAAyB,MAAM,oBAAoB,CAAC;AA+C3G,eAAO,MAAM,iBAAiB,EAAE,YAUN,CAAC;AAiB3B,eAAO,MAAM,uBAAuB,EAAE,YAcZ,CAAC;AAM3B,eAAO,MAAM,iBAAiB,EAAE,YAUN,CAAC;AAY3B;;;GAGG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAezG;AAED,eAAO,MAAM,iBAAiB,EAAE,YAaN,CAAC;AAE3B,eAAO,MAAM,aAAa,EAAE,YAAY,EAAuF,CAAC"}
1
+ {"version":3,"file":"procedures.d.ts","sourceRoot":"","sources":["../src/procedures.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAA+B,KAAK,YAAY,EAAyB,MAAM,oBAAoB,CAAC;AA+C3G,eAAO,MAAM,iBAAiB,EAAE,YAUN,CAAC;AAiB3B,eAAO,MAAM,uBAAuB,EAAE,YAcZ,CAAC;AAM3B,eAAO,MAAM,iBAAiB,EAAE,YAUN,CAAC;AAY3B,6GAA6G;AAC7G,MAAM,MAAM,SAAS,GAAG,CACtB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,KAC3D,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;CAAE,CAAC,CAAC;AAEvE;;;GAGG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,WAAW,EACpB,OAAO,GAAE;IAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,GAAG,SAAS,CAAA;CAAO,GACvD,OAAO,CAAC,MAAM,CAAC,CAgBjB;AAED,eAAO,MAAM,iBAAiB,EAAE,YAaN,CAAC;AAE3B,eAAO,MAAM,aAAa,EAAE,YAAY,EAAuF,CAAC"}
@@ -93,13 +93,14 @@ const FetchInputSchema = z.object({
93
93
  });
94
94
  /**
95
95
  * This function gets the text of a calendar feed. The address of a private feed is a secret, so
96
- * an error never includes it.
96
+ * an error never includes it. The option `fetch` replaces the global `fetch`.
97
97
  */
98
- export async function fetchCalendar(url, timeoutMs, signal) {
98
+ export async function fetchCalendar(url, timeoutMs, signal, options = {}) {
99
99
  const signals = signal ? [signal, AbortSignal.timeout(timeoutMs)] : [AbortSignal.timeout(timeoutMs)];
100
+ const fetchText = options.fetch ?? fetch;
100
101
  let response;
101
102
  try {
102
- response = await fetch(url, { signal: AbortSignal.any(signals), headers: { accept: "text/calendar, */*" } });
103
+ response = await fetchText(url, { signal: AbortSignal.any(signals), headers: { accept: "text/calendar, */*" } });
103
104
  }
104
105
  catch (error) {
105
106
  const reason = error.name === "TimeoutError" ? `no answer in ${timeoutMs} ms` : "the request failed";
@@ -1 +1 @@
1
- {"version":3,"file":"procedures.js","sourceRoot":"","sources":["../src/procedures.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,UAAU,EAA4C,MAAM,oBAAoB,CAAC;AAC3G,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,QAAQ,EAAkC,MAAM,UAAU,CAAC;AACrG,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAA2C,MAAM,YAAY,CAAC;AAEhH,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;AAEvC,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,wBAAwB,CAAC,CAAC;AAEzG,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3B,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE;IACnB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACvC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACnC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACpC,CAAC,CAAC;AAEH,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE;IACnB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAChC,CAAC,CAAC;AAEH,gFAAgF;AAChF,YAAY;AACZ,gFAAgF;AAEhF,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wDAAwD,CAAC;CACpF,CAAC,CAAC;AAKH,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;AAEtE,MAAM,CAAC,MAAM,iBAAiB,GAAiB,eAAe,EAAE;KAC7D,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;KACtB,KAAK,CAAC,UAAU,CAAa,gBAAgB,CAAC,CAAC;KAC/C,MAAM,CAAC,UAAU,CAAe,kBAAkB,CAAC,CAAC;KACpD,IAAI,CAAC;IACJ,WAAW,EAAE,sCAAsC;IACnD,MAAM,EAAE,MAAM;IACd,OAAO,EAAE,IAAI;CACd,CAAC;KACD,OAAO,CAAC,KAAK,EAAE,KAAiB,EAAyB,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;KAC/F,KAAK,EAAkB,CAAC;AAE3B,gFAAgF;AAChF,kBAAkB;AAClB,gFAAgF;AAEhF,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;IAC/C,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,oCAAoC,CAAC;IAC5D,EAAE,EAAE,OAAO,CAAC,QAAQ,CAAC,kCAAkC,CAAC;CACzD,CAAC,CAAC;AAKH,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;AAErF,MAAM,CAAC,MAAM,uBAAuB,GAAiB,eAAe,EAAE;KACnE,IAAI,CAAC,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;KAC5B,KAAK,CAAC,UAAU,CAAmB,sBAAsB,CAAC,CAAC;KAC3D,MAAM,CAAC,UAAU,CAAoB,uBAAuB,CAAC,CAAC;KAC9D,IAAI,CAAC;IACJ,WAAW,EAAE,gGAAgG;IAC7G,MAAM,EAAE,MAAM;IACd,OAAO,EAAE,IAAI;CACd,CAAC;KACD,OAAO,CACN,KAAK,EAAE,KAAuB,EAA8B,EAAE,CAAC,CAAC;IAC9D,WAAW,EAAE,mBAAmB,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;CAC3F,CAAC,CACH;KACA,KAAK,EAAkB,CAAC;AAE3B,gFAAgF;AAChF,YAAY;AACZ,gFAAgF;AAEhF,MAAM,CAAC,MAAM,iBAAiB,GAAiB,eAAe,EAAE;KAC7D,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;KACtB,KAAK,CAAC,UAAU,CAAgB,mBAAmB,CAAC,CAAC;KACrD,MAAM,CAAC,UAAU,CAAiB,oBAAoB,CAAC,CAAC;KACxD,IAAI,CAAC;IACJ,WAAW,EAAE,oFAAoF;IACjG,MAAM,EAAE,MAAM;IACd,OAAO,EAAE,IAAI;CACd,CAAC;KACD,OAAO,CAAC,KAAK,EAAE,KAAoB,EAA2B,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;KACjF,KAAK,EAAkB,CAAC;AAE3B,gFAAgF;AAChF,YAAY;AACZ,gFAAgF;AAEhF,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,4FAA4F,CAAC;IACnH,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,iCAAiC,CAAC;CAChH,CAAC,CAAC;AAGH;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,GAAW,EAAE,SAAiB,EAAE,MAAoB;IACtF,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;IACrG,IAAI,QAAkB,CAAC;IACvB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,oBAAoB,EAAE,EAAE,CAAC,CAAC;IAC/G,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,MAAM,GAAI,KAA2B,CAAC,IAAI,KAAK,cAAc,CAAC,CAAC,CAAC,gBAAgB,SAAS,KAAK,CAAC,CAAC,CAAC,oBAAoB,CAAC;QAC5H,MAAM,IAAI,KAAK,CAAC,qCAAqC,MAAM,EAAE,CAAC,CAAC;IACjE,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACpF,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnC,6FAA6F;IAC7F,+BAA+B;IAC/B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IAC3F,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAiB,eAAe,EAAE;KAC7D,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;KACtB,KAAK,CAAC,UAAU,CAAa,gBAAgB,CAAC,CAAC;KAC/C,MAAM,CAAC,UAAU,CAAe,kBAAkB,CAAC,CAAC;KACpD,IAAI,CAAC;IACJ,WAAW,EAAE,yCAAyC;IACtD,IAAI,EAAE,CAAC,KAAK,CAAC;IACb,MAAM,EAAE,MAAM;IACd,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;CAC5C,CAAC;KACD,OAAO,CAAC,KAAK,EAAE,KAAiB,EAAE,GAAsB,EAAyB,EAAE;IAClF,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,aAAa,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,SAAS,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;AAC5F,CAAC,CAAC;KACD,KAAK,EAAkB,CAAC;AAE3B,MAAM,CAAC,MAAM,aAAa,GAAmB,CAAC,iBAAiB,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,iBAAiB,CAAC,CAAC"}
1
+ {"version":3,"file":"procedures.js","sourceRoot":"","sources":["../src/procedures.ts"],"names":[],"mappings":"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"}
package/dist/zone.d.ts CHANGED
@@ -30,4 +30,11 @@ export declare function zonedOffset(date: string, time: string, timeZone: string
30
30
  * - A zone that `Intl` does not know throws a `RangeError`.
31
31
  */
32
32
  export declare function localDate(instant: Date | number | string, timeZone: string): string;
33
+ /**
34
+ * This function gives the time (`HH:MM`, 24 hours, `00:00` at midnight) that a clock in an IANA
35
+ * time zone shows at an instant. The seconds are cut, not rounded. The instant is a `Date`,
36
+ * milliseconds since 1970, or a text that `Date.parse` reads. An instant that is not valid, or a
37
+ * zone that `Intl` does not know, throws a `RangeError`.
38
+ */
39
+ export declare function localTime(instant: Date | number | string, timeZone: string): string;
33
40
  //# sourceMappingURL=zone.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"zone.d.ts","sourceRoot":"","sources":["../src/zone.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAsEH;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAOnE;AAOD;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAOhF;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMnF"}
1
+ {"version":3,"file":"zone.d.ts","sourceRoot":"","sources":["../src/zone.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAsEH;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAOnE;AAOD;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAOhF;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMnF;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAKnF"}
package/dist/zone.js CHANGED
@@ -110,4 +110,17 @@ export function localDate(instant, timeZone) {
110
110
  throw new RangeError(`localDate: the year ${fields.year} is not from 0 to 9999`);
111
111
  return `${pad(fields.year, 4)}-${pad(fields.month)}-${pad(fields.day)}`;
112
112
  }
113
+ /**
114
+ * This function gives the time (`HH:MM`, 24 hours, `00:00` at midnight) that a clock in an IANA
115
+ * time zone shows at an instant. The seconds are cut, not rounded. The instant is a `Date`,
116
+ * milliseconds since 1970, or a text that `Date.parse` reads. An instant that is not valid, or a
117
+ * zone that `Intl` does not know, throws a `RangeError`.
118
+ */
119
+ export function localTime(instant, timeZone) {
120
+ const time = instant instanceof Date ? instant.getTime() : typeof instant === "number" ? instant : Date.parse(instant);
121
+ if (!Number.isFinite(time))
122
+ throw new RangeError(`localTime: ${JSON.stringify(String(instant))} is not a valid instant`);
123
+ const fields = fieldsAt(time, timeZone);
124
+ return `${pad(fields.hour)}:${pad(fields.minute)}`;
125
+ }
113
126
  //# sourceMappingURL=zone.js.map
package/dist/zone.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"zone.js","sourceRoot":"","sources":["../src/zone.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"zone.js","sourceRoot":"","sources":["../src/zone.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package",
3
3
  "name": "@procedures/ics",
4
- "version": "0.6.0",
4
+ "version": "0.8.0",
5
5
  "description": "An iCalendar (RFC 5545) reader and writer without dependencies: the events of a calendar, their occurrences in a time window with the recurrences, and a calendar from events.",
6
6
  "keywords": [
7
7
  "ics",
@@ -59,7 +59,7 @@
59
59
  "provenance": true
60
60
  },
61
61
  "dependencies": {
62
- "@procedures/client": "0.6.0",
62
+ "@procedures/client": "0.8.0",
63
63
  "zod": "^4.6.5"
64
64
  },
65
65
  "devDependencies": {
package/src/days.ts CHANGED
@@ -36,6 +36,34 @@ export function shiftDay(date: string, days: number): string {
36
36
  return text.slice(0, 10);
37
37
  }
38
38
 
39
+ /** This function tells if a year has a 29th of February, in the Gregorian calendar (the year 0000 has one). */
40
+ const isLeapYear = (year: number): boolean => year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
41
+
42
+ /** The number of days of each month of a year that is not a leap year. */
43
+ const MONTH_DAYS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] as const;
44
+
45
+ /**
46
+ * This function gives the date `months` months after a date (`YYYY-MM-DD`). A negative number gives
47
+ * an earlier date. The number of months must be an integer.
48
+ *
49
+ * - When the day is not in the month of the result, the result is the last day of that month: one
50
+ * month after `2026-01-31` is `2026-02-28`.
51
+ * - For the arithmetic of `Date.UTC`, where the 31st goes into the next month, add the days to the
52
+ * 1st: `shiftDay(shiftMonth("2026-01-01", 1), 30)` is `2026-03-03`.
53
+ * - A date that is not valid, or a result outside the years 0000 to 9999, throws a `RangeError`.
54
+ */
55
+ export function shiftMonth(date: string, months: number): string {
56
+ if (!Number.isSafeInteger(months)) throw new RangeError(`shiftMonth: the number of months ${String(months)} is not an integer`);
57
+ dateTime(date, "shiftMonth");
58
+ const total = Number(date.slice(0, 4)) * 12 + Number(date.slice(5, 7)) - 1 + months;
59
+ const year = Math.floor(total / 12);
60
+ if (!(year >= 0 && year <= 9999)) throw new RangeError(`shiftMonth: ${date} plus ${String(months)} months is not from the year 0000 to 9999`);
61
+ const month = total - year * 12;
62
+ const last = month === 1 && isLeapYear(year) ? 29 : MONTH_DAYS[month]!;
63
+ const day = Math.min(Number(date.slice(8, 10)), last);
64
+ return `${String(year).padStart(4, "0")}-${String(month + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
65
+ }
66
+
39
67
  /**
40
68
  * This function gives the number of whole days from the date `from` to the date `to`
41
69
  * (`YYYY-MM-DD`). It is negative when `to` is before `from`, and 0 for the same date.
@@ -46,3 +74,18 @@ export function shiftDay(date: string, days: number): string {
46
74
  export function daysBetween(from: string, to: string): number {
47
75
  return (dateTime(to, "daysBetween") - dateTime(from, "daysBetween")) / DAY;
48
76
  }
77
+
78
+ /** This function gives the day of the week of a date (`YYYY-MM-DD`): 0 for Sunday to 6 for Saturday. */
79
+ export function weekdayOf(date: string): number {
80
+ return new Date(dateTime(date, "weekdayOf")).getUTCDay();
81
+ }
82
+
83
+ /**
84
+ * This function gives the name of the day of the week of a date (`YYYY-MM-DD`). The default is the
85
+ * long English name ("Monday"). `locale` and `style` give another name from `Intl`. A date has no
86
+ * time zone, so the name is the same in each zone.
87
+ */
88
+ export function weekdayName(date: string, options: { readonly locale?: string; readonly style?: "long" | "short" | "narrow" } = {}): string {
89
+ const noon = dateTime(date, "weekdayName") + DAY / 2;
90
+ return new Intl.DateTimeFormat(options.locale ?? "en-US", { timeZone: "UTC", weekday: options.style ?? "long" }).format(noon);
91
+ }
package/src/index.ts CHANGED
@@ -4,6 +4,6 @@ export * from "./procedures.js";
4
4
  export * from "./ics.js";
5
5
  export * from "./write.js";
6
6
  // The calendar days: the date of an instant in a zone, and the arithmetic of dates
7
- export { localDate, zonedOffset } from "./zone.js";
8
- export { daysBetween, shiftDay } from "./days.js";
7
+ export { localDate, localTime, zonedOffset } from "./zone.js";
8
+ export { daysBetween, shiftDay, shiftMonth, weekdayName, weekdayOf } from "./days.js";
9
9
  export * from "./types.js";
package/src/procedures.ts CHANGED
@@ -118,15 +118,27 @@ const FetchInputSchema = z.object({
118
118
  });
119
119
  type FetchInput = z.infer<typeof FetchInputSchema>;
120
120
 
121
+ /** The part of `fetch` that `fetchCalendar` uses. A test or a host gives its own with the option `fetch`. */
122
+ export type FetchText = (
123
+ url: string,
124
+ init: { headers: Record<string, string>; signal: AbortSignal }
125
+ ) => Promise<{ ok: boolean; status: number; text(): Promise<string> }>;
126
+
121
127
  /**
122
128
  * This function gets the text of a calendar feed. The address of a private feed is a secret, so
123
- * an error never includes it.
129
+ * an error never includes it. The option `fetch` replaces the global `fetch`.
124
130
  */
125
- export async function fetchCalendar(url: string, timeoutMs: number, signal?: AbortSignal): Promise<string> {
131
+ export async function fetchCalendar(
132
+ url: string,
133
+ timeoutMs: number,
134
+ signal?: AbortSignal,
135
+ options: { readonly fetch?: FetchText | undefined } = {}
136
+ ): Promise<string> {
126
137
  const signals = signal ? [signal, AbortSignal.timeout(timeoutMs)] : [AbortSignal.timeout(timeoutMs)];
127
- let response: Response;
138
+ const fetchText: FetchText = options.fetch ?? fetch;
139
+ let response: Awaited<ReturnType<FetchText>>;
128
140
  try {
129
- response = await fetch(url, { signal: AbortSignal.any(signals), headers: { accept: "text/calendar, */*" } });
141
+ response = await fetchText(url, { signal: AbortSignal.any(signals), headers: { accept: "text/calendar, */*" } });
130
142
  } catch (error) {
131
143
  const reason = (error as { name?: string }).name === "TimeoutError" ? `no answer in ${timeoutMs} ms` : "the request failed";
132
144
  throw new Error(`The calendar feed did not answer: ${reason}`);
package/src/zone.ts CHANGED
@@ -126,3 +126,16 @@ export function localDate(instant: Date | number | string, timeZone: string): st
126
126
  if (fields.year < 0 || fields.year > 9999) throw new RangeError(`localDate: the year ${fields.year} is not from 0 to 9999`);
127
127
  return `${pad(fields.year, 4)}-${pad(fields.month)}-${pad(fields.day)}`;
128
128
  }
129
+
130
+ /**
131
+ * This function gives the time (`HH:MM`, 24 hours, `00:00` at midnight) that a clock in an IANA
132
+ * time zone shows at an instant. The seconds are cut, not rounded. The instant is a `Date`,
133
+ * milliseconds since 1970, or a text that `Date.parse` reads. An instant that is not valid, or a
134
+ * zone that `Intl` does not know, throws a `RangeError`.
135
+ */
136
+ export function localTime(instant: Date | number | string, timeZone: string): string {
137
+ const time = instant instanceof Date ? instant.getTime() : typeof instant === "number" ? instant : Date.parse(instant);
138
+ if (!Number.isFinite(time)) throw new RangeError(`localTime: ${JSON.stringify(String(instant))} is not a valid instant`);
139
+ const fields = fieldsAt(time, timeZone);
140
+ return `${pad(fields.hour)}:${pad(fields.minute)}`;
141
+ }