daymath 0.7.0 → 0.7.1
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 +4 -4
- package/index.d.ts +242 -12
- package/index.js +7 -7
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -42,8 +42,8 @@ that reads a clock.
|
|
|
42
42
|
Start here. No arguments means today, in UTC.
|
|
43
43
|
|
|
44
44
|
```js
|
|
45
|
-
day() //
|
|
46
|
-
addDays(day(), 2) //
|
|
45
|
+
day() // today, in UTC
|
|
46
|
+
addDays(day(), 2) // two days from today
|
|
47
47
|
```
|
|
48
48
|
|
|
49
49
|
Then hand it whatever you already have. It converts; it never stores what you gave it.
|
|
@@ -75,7 +75,7 @@ UTC day to the one caller who asked for a local one. Put the zone in the string
|
|
|
75
75
|
Name a zone when the answer depends on one.
|
|
76
76
|
|
|
77
77
|
```js
|
|
78
|
-
day('Asia/Tokyo') //
|
|
78
|
+
day('Asia/Tokyo') // today in Tokyo
|
|
79
79
|
day(row.createdAt, 'America/New_York') // '2026-08-06' the evening before
|
|
80
80
|
day('2026-08-08T23:00:00Z', 'Asia/Tokyo') // '2026-08-09' same instant, next day
|
|
81
81
|
day(zdt.toString()) // the zone in the string wins
|
|
@@ -214,7 +214,7 @@ For the accepting family only the year label moves, so every export still answer
|
|
|
214
214
|
the annotation rides along:
|
|
215
215
|
|
|
216
216
|
```js
|
|
217
|
-
getYear('2026-01-31[u-ca=buddhist]') // 2569
|
|
217
|
+
getYear('2026-01-31[u-ca=buddhist]') // 2569 not 2026
|
|
218
218
|
getMonth('2026-01-31[u-ca=buddhist]') // 1
|
|
219
219
|
addDays('2026-01-31[u-ca=buddhist]', 1) // '2026-02-01[u-ca=buddhist]'
|
|
220
220
|
setYear('2026-01-31[u-ca=buddhist]', 2570) // '2027-01-31[u-ca=buddhist]'
|
package/index.d.ts
CHANGED
|
@@ -80,121 +80,351 @@ export type WeekOptions = {
|
|
|
80
80
|
*
|
|
81
81
|
* A calendar that renumbers months or days is still refused where it is
|
|
82
82
|
* applied, which means with a `[Zone]` bracket and on a day string.
|
|
83
|
+
* @example day(row.createdAt) // a Date, read in UTC
|
|
84
|
+
* @example day(row.createdAt, 'Asia/Tokyo') // the same instant, Tokyo's day
|
|
85
|
+
* @example day('1999-01-01T00:00:00Z') // '1999-01-01'
|
|
86
|
+
* @example day('2026-08-08 12:00:00') // '2026-08-08' a SQLite DATETIME
|
|
87
|
+
* @example day('2026-05-05', 'Asia/Tokyo') // '2026-05-05' a day carries no time
|
|
83
88
|
*/
|
|
84
|
-
export function day(tz?: string): string
|
|
85
89
|
export function day(
|
|
86
90
|
moment: Date | number | DayInput | null | undefined,
|
|
87
91
|
tz?: string,
|
|
88
92
|
): string
|
|
93
|
+
/**
|
|
94
|
+
* Today's calendar day, in a zone. **This is the one overload that reads a clock**, so it is the
|
|
95
|
+
* only call in daymath that is not a pure function. Give the other overload a moment and it is.
|
|
96
|
+
*
|
|
97
|
+
* The zone defaults to UTC, and the default is STATED rather than assumed: daymath has no silent
|
|
98
|
+
* local now. UTC is not your day for part of every day — it runs ahead of `America/New_York` for
|
|
99
|
+
* 16.7% of the day and behind `Asia/Tokyo` for 37.5% — so name your zone when that matters.
|
|
100
|
+
*
|
|
101
|
+
* A lone string here is read as a zone only after it fails to be a day, a zoned time and an
|
|
102
|
+
* instant, in that order. The zone test is by shape, so a timestamp can never be read as a zone.
|
|
103
|
+
* @example day() // today, in UTC
|
|
104
|
+
* @example day('Asia/Tokyo') // today in Tokyo
|
|
105
|
+
* @example day('+05:30') // a bare offset is a zone too
|
|
106
|
+
*/
|
|
107
|
+
export function day(tz?: string): string
|
|
89
108
|
|
|
90
109
|
/**
|
|
91
110
|
* True for a valid daymath day string / PlainDate.
|
|
92
111
|
* Invalid strings → false. `Date` → throws TypeError (not a quiet false).
|
|
112
|
+
* @example isValid('2026-08-08') // true
|
|
113
|
+
* @example isValid('2026-02-30') // false
|
|
114
|
+
* @example isValid('2026-08-08 12:00:00') // true clock dropped
|
|
115
|
+
* @example isValid(new Date()) // throws TypeError, not false
|
|
93
116
|
*/
|
|
94
117
|
export function isValid(value: unknown): boolean
|
|
95
118
|
|
|
96
|
-
/**
|
|
119
|
+
/**
|
|
120
|
+
* Validate / normalize to ISO 8601 day string (Temporal `toString` form).
|
|
121
|
+
*
|
|
122
|
+
* `parse` preserves what it is given; `day()` normalizes. So a calendar
|
|
123
|
+
* annotation survives here and is dropped by `day()`.
|
|
124
|
+
* @example parse('2026-08-08') // '2026-08-08'
|
|
125
|
+
* @example parse('2026-08-08 12:00:00') // '2026-08-08' clock dropped
|
|
126
|
+
* @example parse('2026-01-31[u-ca=buddhist]') // '2026-01-31[u-ca=buddhist]'
|
|
127
|
+
* @example parse('2026-02-30') // throws RangeError
|
|
128
|
+
*/
|
|
97
129
|
export function parse(date: DayInput): string
|
|
98
130
|
|
|
99
|
-
/**
|
|
131
|
+
/**
|
|
132
|
+
* Format as ISO day (only `yyyy-MM-dd` / `YYYY-MM-DD` patterns supported).
|
|
133
|
+
*
|
|
134
|
+
* Not locale display. For that, use `Intl` or a date-fns formatter.
|
|
135
|
+
* @example format('2026-08-08') // '2026-08-08'
|
|
136
|
+
* @example format('2026-08-08', 'dd/MM/yyyy') // throws RangeError
|
|
137
|
+
*/
|
|
100
138
|
export function format(date: DayInput, pattern?: 'yyyy-MM-dd' | 'YYYY-MM-DD'): string
|
|
101
139
|
|
|
140
|
+
/**
|
|
141
|
+
* @example addDays('2026-08-08', 30) // '2026-09-07'
|
|
142
|
+
* @example addDays('2026-08-08', -1) // '2026-08-07'
|
|
143
|
+
*/
|
|
102
144
|
export function addDays(date: DayInput, amount: number): string
|
|
145
|
+
/** @example subDays('2026-08-08', 1) // '2026-08-07' */
|
|
103
146
|
export function subDays(date: DayInput, amount: number): string
|
|
147
|
+
/** @example addWeeks('2026-08-08', 2) // '2026-08-22' */
|
|
104
148
|
export function addWeeks(date: DayInput, amount: number): string
|
|
149
|
+
/** Whole weeks. @example subWeeks('2026-08-22', 2) // '2026-08-08' */
|
|
105
150
|
export function subWeeks(date: DayInput, amount: number): string
|
|
151
|
+
/**
|
|
152
|
+
* Overflow **clamps** to the last day of the target month; it never rolls into
|
|
153
|
+
* the next one. Same rule in both directions, and the same rule `setMonth`,
|
|
154
|
+
* `setDate` and `setYear` use.
|
|
155
|
+
* @example addMonths('2026-01-31', 1) // '2026-02-28' clamped, not '2026-03-03'
|
|
156
|
+
* @example addMonths('2026-03-31', -1) // '2026-02-28'
|
|
157
|
+
* @example addMonths('2024-01-31', 1) // '2024-02-29' leap year
|
|
158
|
+
*/
|
|
106
159
|
export function addMonths(date: DayInput, amount: number): string
|
|
160
|
+
/**
|
|
161
|
+
* Clamps, exactly as `addMonths` does.
|
|
162
|
+
* @example subMonths('2026-03-31', 1) // '2026-02-28' clamped
|
|
163
|
+
*/
|
|
107
164
|
export function subMonths(date: DayInput, amount: number): string
|
|
165
|
+
/**
|
|
166
|
+
* Clamps, so 29 February lands on the 28th of a common year.
|
|
167
|
+
* @example addYears('2024-02-29', 1) // '2025-02-28' clamped
|
|
168
|
+
*/
|
|
108
169
|
export function addYears(date: DayInput, amount: number): string
|
|
170
|
+
/**
|
|
171
|
+
* Clamps, exactly as `addYears` does.
|
|
172
|
+
* @example subYears('2024-02-29', 1) // '2023-02-28' clamped
|
|
173
|
+
*/
|
|
109
174
|
export function subYears(date: DayInput, amount: number): string
|
|
175
|
+
/**
|
|
176
|
+
* Three months at a time, and it clamps.
|
|
177
|
+
* @example addQuarters('2026-01-31', 1) // '2026-04-30' clamped
|
|
178
|
+
*/
|
|
110
179
|
export function addQuarters(date: DayInput, amount: number): string
|
|
180
|
+
/** Three months back, and it clamps. @example subQuarters('2026-04-30', 1) // '2026-01-30' */
|
|
111
181
|
export function subQuarters(date: DayInput, amount: number): string
|
|
112
182
|
|
|
113
|
-
/**
|
|
183
|
+
/**
|
|
184
|
+
* Full year number. An annotation is applied on top of the ISO date part, never instead of it.
|
|
185
|
+
* @example getYear('2026-08-08') // 2026
|
|
186
|
+
* @example getYear('2026-01-31[u-ca=buddhist]') // 2569 the annotation adds 543
|
|
187
|
+
*/
|
|
114
188
|
export function getYear(date: DayInput): number
|
|
115
|
-
/**
|
|
189
|
+
/**
|
|
190
|
+
* Month number, ISO 8601: 1 = January … 12 = December. Not date-fns's 0-based index.
|
|
191
|
+
* @example getMonth('2026-08-08') // 8 — date-fns would answer 7
|
|
192
|
+
* @example getMonth('2026-01-15') // 1
|
|
193
|
+
*/
|
|
116
194
|
export function getMonth(date: DayInput): number
|
|
117
|
-
/** Day of month 1…31. */
|
|
195
|
+
/** Day of month 1…31. @example getDate('2026-08-08') // 8 */
|
|
118
196
|
export function getDate(date: DayInput): number
|
|
119
|
-
/**
|
|
197
|
+
/**
|
|
198
|
+
* Weekday, ISO 8601: 1 = Monday … 7 = Sunday. Only Sunday differs from date-fns.
|
|
199
|
+
* @example getDay('2026-08-10') // 1 a Monday
|
|
200
|
+
* @example getDay('2026-08-09') // 7 a Sunday — date-fns would answer 0
|
|
201
|
+
*/
|
|
120
202
|
export function getDay(date: DayInput): number
|
|
203
|
+
/** 1 on 1 January. @example getDayOfYear('2026-03-01') // 60 */
|
|
121
204
|
export function getDayOfYear(date: DayInput): number
|
|
205
|
+
/** @example getDaysInMonth('2024-02-10') // 29 */
|
|
122
206
|
export function getDaysInMonth(date: DayInput): number
|
|
123
|
-
/** Quarter 1…4. */
|
|
207
|
+
/** Quarter 1…4. @example getQuarter('2026-08-08') // 3 */
|
|
124
208
|
export function getQuarter(date: DayInput): number
|
|
209
|
+
/**
|
|
210
|
+
* Leap year of the day's own ISO year.
|
|
211
|
+
*
|
|
212
|
+
* **This is the one way to get a wrong answer with no error**, and it is worth reading before
|
|
213
|
+
* you pass a non-ISO calendar's year. A `[u-ca=…]` day is judged on its ISO year, which is the
|
|
214
|
+
* date part — so a Buddhist year written as a bare ISO year is a different year. Buddhist 2567
|
|
215
|
+
* is ISO 2024 and IS a leap year, but 2567 read as ISO is not, because 543 mod 4 is 3. The two
|
|
216
|
+
* rules disagree in 49 of the 101 Buddhist years from 2500 to 2600, and nothing throws.
|
|
217
|
+
* @example isLeapYear('2024-01-01') // true
|
|
218
|
+
* @example isLeapYear('2567-01-01') // false ISO 2567, NOT Buddhist 2567 (which is ISO 2024)
|
|
219
|
+
*/
|
|
125
220
|
export function isLeapYear(date: DayInput): boolean
|
|
126
221
|
|
|
222
|
+
/**
|
|
223
|
+
* Overflow clamps, so 29 February survives a move to a common year. **date-fns rolls here
|
|
224
|
+
* instead**, so this is the second deliberate disagreement after `setDate` — and the one a caller
|
|
225
|
+
* reaches by accident, through a stored 29 February.
|
|
226
|
+
* @example setYear('2024-02-29', 2026) // '2026-02-28' clamped; date-fns gives '2026-03-01'
|
|
227
|
+
*/
|
|
127
228
|
export function setYear(date: DayInput, year: number): string
|
|
128
|
-
/**
|
|
229
|
+
/**
|
|
230
|
+
* `month`: 1 = January … 12 = December (ISO 8601). Overflow clamps.
|
|
231
|
+
* @example setMonth('2026-01-31', 2) // '2026-02-28' clamped
|
|
232
|
+
*/
|
|
129
233
|
export function setMonth(date: DayInput, month: number): string
|
|
234
|
+
/**
|
|
235
|
+
* Overflow clamps to the end of the month. **date-fns rolls here instead**, so
|
|
236
|
+
* this is one of the few places the two answer differently on purpose.
|
|
237
|
+
* @example setDate('2026-02-01', 31) // '2026-02-28' daymath clamps
|
|
238
|
+
*/
|
|
130
239
|
export function setDate(date: DayInput, dayOfMonth: number): string
|
|
131
240
|
|
|
241
|
+
/** @example startOfMonth('2026-08-08') // '2026-08-01' */
|
|
132
242
|
export function startOfMonth(date: DayInput): string
|
|
243
|
+
/**
|
|
244
|
+
* @example endOfMonth('2024-02-01') // '2024-02-29'
|
|
245
|
+
*/
|
|
133
246
|
export function endOfMonth(date: DayInput): string
|
|
247
|
+
/** @example startOfYear('2026-08-08') // '2026-01-01' */
|
|
134
248
|
export function startOfYear(date: DayInput): string
|
|
249
|
+
/** @example endOfYear('2026-08-08') // '2026-12-31' */
|
|
135
250
|
export function endOfYear(date: DayInput): string
|
|
251
|
+
/** @example startOfQuarter('2026-08-08') // '2026-07-01' */
|
|
136
252
|
export function startOfQuarter(date: DayInput): string
|
|
253
|
+
/** @example endOfQuarter('2026-08-08') // '2026-09-30' */
|
|
137
254
|
export function endOfQuarter(date: DayInput): string
|
|
255
|
+
/**
|
|
256
|
+
* `weekStartsOn` defaults to **7 (Sunday)**, and `0` is accepted for Sunday too.
|
|
257
|
+
* @example startOfWeek('2026-08-12') // '2026-08-09' Sunday
|
|
258
|
+
* @example startOfWeek('2026-08-12', { weekStartsOn: 1 }) // '2026-08-10' Monday
|
|
259
|
+
*/
|
|
138
260
|
export function startOfWeek(date: DayInput, options?: WeekOptions): string
|
|
261
|
+
/**
|
|
262
|
+
* `weekStartsOn` defaults to 7 (Sunday), so the week ends on Saturday.
|
|
263
|
+
* @example endOfWeek('2026-08-12') // '2026-08-15' Saturday
|
|
264
|
+
* @example endOfWeek('2026-08-12', { weekStartsOn: 1 }) // '2026-08-16' Sunday
|
|
265
|
+
*/
|
|
139
266
|
export function endOfWeek(date: DayInput, options?: WeekOptions): string
|
|
140
267
|
|
|
141
|
-
/**
|
|
268
|
+
/**
|
|
269
|
+
* Full days: `dateLeft − dateRight` (date-fns argument order).
|
|
270
|
+
* @example differenceInDays('2026-08-08', '2026-08-01') // 7
|
|
271
|
+
* @example differenceInDays('2026-08-01', '2026-08-08') // -7 order matters
|
|
272
|
+
*/
|
|
142
273
|
export function differenceInDays(dateLeft: DayInput, dateRight: DayInput): number
|
|
274
|
+
/** Whole weeks. @example differenceInWeeks('2026-08-15', '2026-08-08') // 1 */
|
|
143
275
|
export function differenceInWeeks(dateLeft: DayInput, dateRight: DayInput): number
|
|
276
|
+
/**
|
|
277
|
+
* A month counts as full when `addMonths` would carry the earlier date to the
|
|
278
|
+
* later one, so `differenceInMonths(addMonths(d, n), d) === n` always holds. Use
|
|
279
|
+
* `differenceInCalendarMonths` to count boundaries crossed instead.
|
|
280
|
+
* @example differenceInMonths('2026-02-28', '2026-01-31') // 1 addMonths clamps to here
|
|
281
|
+
* @example differenceInCalendarMonths('2026-02-01', '2026-01-31') // 1 one boundary, one day apart
|
|
282
|
+
*/
|
|
144
283
|
export function differenceInMonths(dateLeft: DayInput, dateRight: DayInput): number
|
|
284
|
+
/**
|
|
285
|
+
* Month boundaries crossed, not whole months. `differenceInMonths` is the other question.
|
|
286
|
+
* @example differenceInCalendarMonths('2026-02-01', '2026-01-31') // 1 one day apart
|
|
287
|
+
*/
|
|
145
288
|
export function differenceInCalendarMonths(
|
|
146
289
|
dateLeft: DayInput,
|
|
147
290
|
dateRight: DayInput,
|
|
148
291
|
): number
|
|
292
|
+
/**
|
|
293
|
+
* Counts by `addYears`, the same rule `differenceInMonths` uses, so the round-trip law holds.
|
|
294
|
+
* @example differenceInYears('2026-02-28', '2024-02-29') // 2 addYears clamps to here
|
|
295
|
+
*/
|
|
149
296
|
export function differenceInYears(dateLeft: DayInput, dateRight: DayInput): number
|
|
297
|
+
/**
|
|
298
|
+
* Boundaries crossed, not whole years.
|
|
299
|
+
* @example differenceInCalendarYears('2026-01-01', '2025-12-31') // 1 one day apart
|
|
300
|
+
*/
|
|
150
301
|
export function differenceInCalendarYears(dateLeft: DayInput, dateRight: DayInput): number
|
|
302
|
+
/** Counts by `addQuarters`. @example differenceInQuarters('2026-07-01', '2026-01-01') // 2 */
|
|
151
303
|
export function differenceInQuarters(dateLeft: DayInput, dateRight: DayInput): number
|
|
304
|
+
/**
|
|
305
|
+
* Quarter boundaries crossed, not whole quarters.
|
|
306
|
+
* @example differenceInCalendarQuarters('2026-07-01', '2026-06-30') // 1 one day apart
|
|
307
|
+
*/
|
|
152
308
|
export function differenceInCalendarQuarters(
|
|
153
309
|
dateLeft: DayInput,
|
|
154
310
|
dateRight: DayInput,
|
|
155
311
|
): number
|
|
156
312
|
|
|
313
|
+
/**
|
|
314
|
+
* Strictly before; an equal pair is `false`.
|
|
315
|
+
* @example isBefore('2026-08-01', '2026-08-08') // true
|
|
316
|
+
* @example isBefore('2026-08-08', '2026-08-08') // false not strictly before
|
|
317
|
+
*/
|
|
157
318
|
export function isBefore(date: DayInput, dateToCompare: DayInput): boolean
|
|
319
|
+
/** Strictly after. @example isAfter('2026-08-01', '2026-08-08') // false */
|
|
158
320
|
export function isAfter(date: DayInput, dateToCompare: DayInput): boolean
|
|
159
|
-
/**
|
|
321
|
+
/**
|
|
322
|
+
* Same calendar day, and the calendar label is ignored. Temporal's own `equals`
|
|
323
|
+
* compares the calendar too, so it answers `false` for one day written two ways;
|
|
324
|
+
* daymath compares the day alone and answers `true`.
|
|
325
|
+
* @example isEqual('2026-01-31[u-ca=buddhist]', '2026-01-31') // true same day
|
|
326
|
+
*/
|
|
160
327
|
export function isEqual(dateLeft: DayInput, dateRight: DayInput): boolean
|
|
161
|
-
/**
|
|
328
|
+
/**
|
|
329
|
+
* Alias of `isEqual` (date-fns name), and it ignores the calendar label the same way.
|
|
330
|
+
* @example isSameDay('2026-01-31[u-ca=buddhist]', '2026-01-31') // true same day
|
|
331
|
+
*/
|
|
162
332
|
export const isSameDay: typeof isEqual
|
|
163
333
|
|
|
334
|
+
/**
|
|
335
|
+
* `weekStartsOn` defaults to 7 (Sunday), so a Saturday and the Sunday after it are DIFFERENT weeks.
|
|
336
|
+
* @example isSameWeek('2026-08-08', '2026-08-09') // false Sat then Sun
|
|
337
|
+
* @example isSameWeek('2026-08-08', '2026-08-09', { weekStartsOn: 1 }) // true Monday weeks
|
|
338
|
+
*/
|
|
164
339
|
export function isSameWeek(
|
|
165
340
|
dateLeft: DayInput,
|
|
166
341
|
dateRight: DayInput,
|
|
167
342
|
options?: WeekOptions,
|
|
168
343
|
): boolean
|
|
344
|
+
/** Same month AND year. @example isSameMonth('2026-08-01', '2026-08-31') // true */
|
|
169
345
|
export function isSameMonth(dateLeft: DayInput, dateRight: DayInput): boolean
|
|
346
|
+
/** @example isSameYear('2026-01-01', '2026-12-31') // true */
|
|
170
347
|
export function isSameYear(dateLeft: DayInput, dateRight: DayInput): boolean
|
|
348
|
+
/** @example isSameQuarter('2026-07-01', '2026-09-30') // true */
|
|
171
349
|
export function isSameQuarter(dateLeft: DayInput, dateRight: DayInput): boolean
|
|
172
350
|
|
|
351
|
+
/**
|
|
352
|
+
* Comparator for `Array.prototype.sort`, oldest first.
|
|
353
|
+
* @example compareAsc('2026-01-01', '2026-08-08') // -1
|
|
354
|
+
*/
|
|
173
355
|
export function compareAsc(dateLeft: DayInput, dateRight: DayInput): -1 | 0 | 1
|
|
356
|
+
/** Newest first. @example compareDesc('2026-01-01', '2026-08-08') // 1 */
|
|
174
357
|
export function compareDesc(dateLeft: DayInput, dateRight: DayInput): -1 | 0 | 1
|
|
175
358
|
|
|
359
|
+
/**
|
|
360
|
+
* Takes an **array**, not a rest argument.
|
|
361
|
+
* @example min(['2026-08-08', '2026-01-01']) // '2026-01-01'
|
|
362
|
+
*/
|
|
176
363
|
export function min(dates: DayInput[]): string
|
|
364
|
+
/**
|
|
365
|
+
* Takes an **array**, not a rest argument, exactly as `min` does.
|
|
366
|
+
* @example max(['2026-01-01', '2026-08-08']) // '2026-08-08'
|
|
367
|
+
*/
|
|
177
368
|
export function max(dates: DayInput[]): string
|
|
178
369
|
|
|
370
|
+
/** ISO weekday 7. @example isSunday('2026-08-09') // true */
|
|
179
371
|
export function isSunday(date: DayInput): boolean
|
|
372
|
+
/** ISO weekday 1. @example isMonday('2026-08-10') // true */
|
|
180
373
|
export function isMonday(date: DayInput): boolean
|
|
374
|
+
/** ISO weekday 2. @example isTuesday('2026-08-11') // true */
|
|
181
375
|
export function isTuesday(date: DayInput): boolean
|
|
376
|
+
/** ISO weekday 3. @example isWednesday('2026-08-12') // true */
|
|
182
377
|
export function isWednesday(date: DayInput): boolean
|
|
378
|
+
/** ISO weekday 4. @example isThursday('2026-08-13') // true */
|
|
183
379
|
export function isThursday(date: DayInput): boolean
|
|
380
|
+
/** ISO weekday 5. @example isFriday('2026-08-14') // true */
|
|
184
381
|
export function isFriday(date: DayInput): boolean
|
|
382
|
+
/** ISO weekday 6. @example isSaturday('2026-08-08') // true */
|
|
185
383
|
export function isSaturday(date: DayInput): boolean
|
|
384
|
+
/**
|
|
385
|
+
* ISO Saturday and Sunday (6 and 7). Not configurable, and no holiday calendar.
|
|
386
|
+
* @example isWeekend('2026-08-08') // true a Saturday
|
|
387
|
+
* @example isWeekend('2026-08-10') // false a Monday
|
|
388
|
+
*/
|
|
186
389
|
export function isWeekend(date: DayInput): boolean
|
|
390
|
+
/** @example isFirstDayOfMonth('2026-08-01') // true */
|
|
187
391
|
export function isFirstDayOfMonth(date: DayInput): boolean
|
|
392
|
+
/** @example isLastDayOfMonth('2024-02-29') // true leap year */
|
|
188
393
|
export function isLastDayOfMonth(date: DayInput): boolean
|
|
189
394
|
|
|
395
|
+
/**
|
|
396
|
+
* Both ends **inclusive**, so a one-day interval returns one day.
|
|
397
|
+
* @example eachDayOfInterval({ start: '2026-08-08', end: '2026-08-10' })
|
|
398
|
+
* // ['2026-08-08', '2026-08-09', '2026-08-10']
|
|
399
|
+
*/
|
|
190
400
|
export function eachDayOfInterval(interval: Interval): string[]
|
|
401
|
+
/**
|
|
402
|
+
* The FIRST of each month touched, both ends inclusive.
|
|
403
|
+
* @example eachMonthOfInterval({ start: '2026-01-15', end: '2026-03-02' })
|
|
404
|
+
* // ['2026-01-01', '2026-02-01', '2026-03-01']
|
|
405
|
+
*/
|
|
191
406
|
export function eachMonthOfInterval(interval: Interval): string[]
|
|
407
|
+
/**
|
|
408
|
+
* The FIRST of January of each year touched, both ends inclusive.
|
|
409
|
+
* @example eachYearOfInterval({ start: '2025-06-01', end: '2026-02-01' })
|
|
410
|
+
* // ['2025-01-01', '2026-01-01']
|
|
411
|
+
*/
|
|
192
412
|
export function eachYearOfInterval(interval: Interval): string[]
|
|
413
|
+
/**
|
|
414
|
+
* Both ends **inclusive**, so a date equal to an endpoint is within.
|
|
415
|
+
* @example isWithinInterval('2026-08-10', { start: '2026-08-08', end: '2026-08-10' }) // true
|
|
416
|
+
*/
|
|
193
417
|
export function isWithinInterval(date: DayInput, interval: Interval): boolean
|
|
418
|
+
/**
|
|
419
|
+
* Pull a day inside the interval, or return it unchanged if it is already inside.
|
|
420
|
+
* @example clamp('2026-12-25', { start: '2026-08-08', end: '2026-08-10' }) // '2026-08-10'
|
|
421
|
+
*/
|
|
194
422
|
export function clamp(date: DayInput, interval: Interval): string
|
|
195
423
|
/**
|
|
196
424
|
* date-fns default: `inclusive: false` (touching endpoints only is not overlap).
|
|
197
425
|
* Pass `{ inclusive: true }` for closed intervals.
|
|
426
|
+
* @example areIntervalsOverlapping({ start: '2026-08-01', end: '2026-08-08' }, { start: '2026-08-08', end: '2026-08-10' }) // false
|
|
427
|
+
* @example areIntervalsOverlapping({ start: '2026-08-01', end: '2026-08-08' }, { start: '2026-08-08', end: '2026-08-10' }, { inclusive: true }) // true
|
|
198
428
|
*/
|
|
199
429
|
export function areIntervalsOverlapping(
|
|
200
430
|
intervalLeft: Interval,
|
package/index.js
CHANGED
|
@@ -598,16 +598,16 @@ function toInterval(interval) {
|
|
|
598
598
|
* annotation is accepted on input and dropped from the result. Every other export carries it.
|
|
599
599
|
* @throws {TypeError} If `moment` is not one of the accepted shapes
|
|
600
600
|
* @throws {RangeError} On an Invalid Date, a non-finite number, or an unknown zone
|
|
601
|
-
* @example day() //
|
|
602
|
-
* @example day('Asia/Tokyo') //
|
|
603
|
-
* @example day(row.createdAt) //
|
|
604
|
-
* @example day(row.createdAt, 'America/New_York') // '
|
|
601
|
+
* @example day() // today, in UTC
|
|
602
|
+
* @example day('Asia/Tokyo') // today in Tokyo
|
|
603
|
+
* @example day(row.createdAt) // a Date, read in UTC
|
|
604
|
+
* @example day(row.createdAt, 'America/New_York') // the same instant, New York's day
|
|
605
605
|
* @example day(1761616161771) // '2025-10-28' epoch ms
|
|
606
606
|
* @example day('1999-01-01T00:00:00Z') // '1999-01-01' an ISO timestamp
|
|
607
607
|
* @example day(zdt.toString()) // the zone in the string wins
|
|
608
|
-
* @example day(row.created_at) //
|
|
609
|
-
* @example day('2026-08-08 12:00:00', 'utc') // throws
|
|
610
|
-
* @example addDays(day(), 2) //
|
|
608
|
+
* @example day(row.created_at) // a SQLite DATETIME
|
|
609
|
+
* @example day('2026-08-08 12:00:00', 'utc') // throws TypeError, the clock names no zone
|
|
610
|
+
* @example addDays(day(), 2) // two days from today
|
|
611
611
|
*/
|
|
612
612
|
export function day(moment, tz) {
|
|
613
613
|
// Already a day, in every accepted spelling. `bareDay` is the same predicate
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "daymath",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"description": "Calendar date math (ISO 8601 day / PlainDate). date-fns-shaped. No Date. No time zones.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.js",
|
|
@@ -29,11 +29,13 @@
|
|
|
29
29
|
"test:runtimes": "node scripts/cross-runtime.mjs",
|
|
30
30
|
"test:runtimes:write": "node scripts/cross-runtime.mjs --write",
|
|
31
31
|
"test:intl-day": "node scripts/intl-day.mjs",
|
|
32
|
+
"test:examples": "node scripts/examples.mjs",
|
|
33
|
+
"test:examples:write": "node scripts/examples.mjs --write",
|
|
32
34
|
"test:intl-day:sweep": "node scripts/intl-day.mjs --sweep",
|
|
33
35
|
"size": "node scripts/bundle-size.mjs --run",
|
|
34
36
|
"size:check": "node scripts/bundle-size.mjs --check",
|
|
35
37
|
"size:write": "node scripts/bundle-size.mjs --write",
|
|
36
|
-
"prepublishOnly": "npm run test:coverage",
|
|
38
|
+
"prepublishOnly": "npm run test:coverage && npm run test:examples",
|
|
37
39
|
"publish:github": "node scripts/publish-github-packages.mjs"
|
|
38
40
|
},
|
|
39
41
|
"keywords": [
|