@internationalized/date 3.12.0 → 3.12.2
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/index.cjs +113 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +45 -0
- package/dist/index.mjs.map +1 -0
- package/dist/private/CalendarDate.cjs +272 -0
- package/dist/private/CalendarDate.cjs.map +1 -0
- package/dist/private/CalendarDate.js +282 -0
- package/dist/private/CalendarDate.js.map +1 -0
- package/dist/private/CalendarDate.mjs +264 -0
- package/dist/private/CalendarDate.mjs.map +1 -0
- package/dist/{DateFormatter.main.js → private/DateFormatter.cjs} +31 -28
- package/dist/private/DateFormatter.cjs.map +1 -0
- package/dist/{DateFormatter.module.js → private/DateFormatter.js} +27 -24
- package/dist/private/DateFormatter.js.map +1 -0
- package/dist/{DateFormatter.mjs → private/DateFormatter.mjs} +31 -28
- package/dist/private/DateFormatter.mjs.map +1 -0
- package/dist/{BuddhistCalendar.main.js → private/calendars/BuddhistCalendar.cjs} +13 -13
- package/dist/{BuddhistCalendar.main.js.map → private/calendars/BuddhistCalendar.cjs.map} +1 -1
- package/dist/{BuddhistCalendar.module.js → private/calendars/BuddhistCalendar.js} +13 -13
- package/dist/{BuddhistCalendar.module.js.map → private/calendars/BuddhistCalendar.js.map} +1 -1
- package/dist/{BuddhistCalendar.mjs → private/calendars/BuddhistCalendar.mjs} +13 -13
- package/dist/private/calendars/BuddhistCalendar.mjs.map +1 -0
- package/dist/{EthiopicCalendar.main.js → private/calendars/EthiopicCalendar.cjs} +37 -37
- package/dist/private/calendars/EthiopicCalendar.cjs.map +1 -0
- package/dist/{EthiopicCalendar.module.js → private/calendars/EthiopicCalendar.js} +35 -35
- package/dist/private/calendars/EthiopicCalendar.js.map +1 -0
- package/dist/{EthiopicCalendar.mjs → private/calendars/EthiopicCalendar.mjs} +35 -35
- package/dist/private/calendars/EthiopicCalendar.mjs.map +1 -0
- package/dist/{GregorianCalendar.main.js → private/calendars/GregorianCalendar.cjs} +31 -31
- package/dist/private/calendars/GregorianCalendar.cjs.map +1 -0
- package/dist/{GregorianCalendar.module.js → private/calendars/GregorianCalendar.js} +27 -27
- package/dist/private/calendars/GregorianCalendar.js.map +1 -0
- package/dist/{GregorianCalendar.mjs → private/calendars/GregorianCalendar.mjs} +27 -27
- package/dist/private/calendars/GregorianCalendar.mjs.map +1 -0
- package/dist/{HebrewCalendar.main.js → private/calendars/HebrewCalendar.cjs} +44 -44
- package/dist/private/calendars/HebrewCalendar.cjs.map +1 -0
- package/dist/{HebrewCalendar.module.js → private/calendars/HebrewCalendar.js} +44 -44
- package/dist/private/calendars/HebrewCalendar.js.map +1 -0
- package/dist/{HebrewCalendar.mjs → private/calendars/HebrewCalendar.mjs} +44 -44
- package/dist/private/calendars/HebrewCalendar.mjs.map +1 -0
- package/dist/{IndianCalendar.main.js → private/calendars/IndianCalendar.cjs} +20 -20
- package/dist/private/calendars/IndianCalendar.cjs.map +1 -0
- package/dist/{IndianCalendar.module.js → private/calendars/IndianCalendar.js} +20 -20
- package/dist/private/calendars/IndianCalendar.js.map +1 -0
- package/dist/{IndianCalendar.mjs → private/calendars/IndianCalendar.mjs} +20 -20
- package/dist/private/calendars/IndianCalendar.mjs.map +1 -0
- package/dist/private/calendars/IslamicCalendar.cjs +168 -0
- package/dist/private/calendars/IslamicCalendar.cjs.map +1 -0
- package/dist/private/calendars/IslamicCalendar.js +161 -0
- package/dist/private/calendars/IslamicCalendar.js.map +1 -0
- package/dist/private/calendars/IslamicCalendar.mjs +161 -0
- package/dist/private/calendars/IslamicCalendar.mjs.map +1 -0
- package/dist/{JapaneseCalendar.main.js → private/calendars/JapaneseCalendar.cjs} +37 -37
- package/dist/private/calendars/JapaneseCalendar.cjs.map +1 -0
- package/dist/{JapaneseCalendar.module.js → private/calendars/JapaneseCalendar.js} +37 -37
- package/dist/private/calendars/JapaneseCalendar.js.map +1 -0
- package/dist/{JapaneseCalendar.mjs → private/calendars/JapaneseCalendar.mjs} +37 -37
- package/dist/private/calendars/JapaneseCalendar.mjs.map +1 -0
- package/dist/{PersianCalendar.main.js → private/calendars/PersianCalendar.cjs} +13 -13
- package/dist/private/calendars/PersianCalendar.cjs.map +1 -0
- package/dist/{PersianCalendar.module.js → private/calendars/PersianCalendar.js} +13 -13
- package/dist/private/calendars/PersianCalendar.js.map +1 -0
- package/dist/{PersianCalendar.mjs → private/calendars/PersianCalendar.mjs} +13 -13
- package/dist/private/calendars/PersianCalendar.mjs.map +1 -0
- package/dist/{TaiwanCalendar.main.js → private/calendars/TaiwanCalendar.cjs} +20 -20
- package/dist/{TaiwanCalendar.main.js.map → private/calendars/TaiwanCalendar.cjs.map} +1 -1
- package/dist/private/calendars/TaiwanCalendar.js +75 -0
- package/dist/{TaiwanCalendar.module.js.map → private/calendars/TaiwanCalendar.js.map} +1 -1
- package/dist/{TaiwanCalendar.mjs → private/calendars/TaiwanCalendar.mjs} +20 -20
- package/dist/private/calendars/TaiwanCalendar.mjs.map +1 -0
- package/dist/{conversion.main.js → private/conversion.cjs} +85 -85
- package/dist/private/conversion.cjs.map +1 -0
- package/dist/{conversion.module.js → private/conversion.js} +71 -71
- package/dist/private/conversion.js.map +1 -0
- package/dist/{conversion.mjs → private/conversion.mjs} +71 -71
- package/dist/private/conversion.mjs.map +1 -0
- package/dist/private/createCalendar.cjs +69 -0
- package/dist/private/createCalendar.cjs.map +1 -0
- package/dist/private/createCalendar.js +64 -0
- package/dist/private/createCalendar.js.map +1 -0
- package/dist/private/createCalendar.mjs +64 -0
- package/dist/private/createCalendar.mjs.map +1 -0
- package/dist/{manipulation.main.js → private/manipulation.cjs} +106 -109
- package/dist/private/manipulation.cjs.map +1 -0
- package/dist/{manipulation.mjs → private/manipulation.js} +88 -88
- package/dist/private/manipulation.js.map +1 -0
- package/dist/{manipulation.module.js → private/manipulation.mjs} +93 -96
- package/dist/private/manipulation.mjs.map +1 -0
- package/dist/private/queries.cjs +359 -0
- package/dist/private/queries.cjs.map +1 -0
- package/dist/private/queries.js +326 -0
- package/dist/private/queries.js.map +1 -0
- package/dist/private/queries.mjs +324 -0
- package/dist/private/queries.mjs.map +1 -0
- package/dist/private/string.cjs +181 -0
- package/dist/private/string.cjs.map +1 -0
- package/dist/{string.mjs → private/string.js} +64 -64
- package/dist/private/string.js.map +1 -0
- package/dist/private/string.mjs +166 -0
- package/dist/private/string.mjs.map +1 -0
- package/dist/{utils.main.js → private/utils.cjs} +3 -3
- package/dist/{utils.main.js.map → private/utils.cjs.map} +1 -1
- package/dist/{utils.module.js → private/utils.js} +3 -3
- package/dist/{utils.module.js.map → private/utils.js.map} +1 -1
- package/dist/{utils.mjs → private/utils.mjs} +3 -3
- package/dist/private/utils.mjs.map +1 -0
- package/dist/{weekStartData.main.js → private/weekStartData.cjs} +3 -3
- package/dist/{weekStartData.main.js.map → private/weekStartData.cjs.map} +1 -1
- package/dist/{weekStartData.module.js → private/weekStartData.js} +3 -3
- package/dist/{weekStartData.module.js.map → private/weekStartData.js.map} +1 -1
- package/dist/{weekStartData.mjs → private/weekStartData.mjs} +3 -3
- package/dist/private/weekStartData.mjs.map +1 -0
- package/dist/types/src/CalendarDate.d.ts +207 -0
- package/dist/types/src/DateFormatter.d.ts +24 -0
- package/dist/types/src/calendars/BuddhistCalendar.d.ts +16 -0
- package/dist/types/src/calendars/EthiopicCalendar.d.ts +45 -0
- package/dist/types/src/calendars/GregorianCalendar.d.ts +26 -0
- package/dist/types/src/calendars/HebrewCalendar.d.ts +21 -0
- package/dist/types/src/calendars/IndianCalendar.d.ts +17 -0
- package/dist/types/src/calendars/IslamicCalendar.d.ts +51 -0
- package/dist/types/src/calendars/JapaneseCalendar.d.ts +22 -0
- package/dist/types/src/calendars/PersianCalendar.d.ts +19 -0
- package/dist/types/src/calendars/TaiwanCalendar.d.ts +19 -0
- package/dist/types/src/conversion.d.ts +45 -0
- package/dist/types/src/createCalendar.d.ts +3 -0
- package/dist/types/src/index.d.ts +17 -0
- package/dist/types/src/manipulation.d.ts +25 -0
- package/dist/types/src/queries.d.ts +93 -0
- package/dist/types/src/string.d.ts +36 -0
- package/dist/types/src/types.d.ts +136 -0
- package/dist/types/src/utils.d.ts +4 -0
- package/dist/types/src/weekStartData.d.ts +97 -0
- package/package.json +33 -18
- package/src/CalendarDate.ts +215 -35
- package/src/DateFormatter.ts +36 -16
- package/src/calendars/BuddhistCalendar.ts +1 -6
- package/src/calendars/EthiopicCalendar.ts +6 -5
- package/src/calendars/GregorianCalendar.ts +11 -4
- package/src/calendars/HebrewCalendar.ts +8 -4
- package/src/calendars/IndianCalendar.ts +8 -3
- package/src/calendars/IslamicCalendar.ts +40 -25
- package/src/calendars/JapaneseCalendar.ts +18 -10
- package/src/calendars/PersianCalendar.ts +2 -4
- package/src/calendars/TaiwanCalendar.ts +2 -9
- package/src/conversion.ts +98 -25
- package/src/createCalendar.ts +10 -2
- package/src/index.ts +11 -2
- package/src/manipulation.ts +133 -30
- package/src/queries.ts +57 -15
- package/src/string.ts +52 -25
- package/src/types.ts +73 -51
- package/src/utils.ts +1 -1
- package/dist/CalendarDate.main.js +0 -260
- package/dist/CalendarDate.main.js.map +0 -1
- package/dist/CalendarDate.mjs +0 -252
- package/dist/CalendarDate.module.js +0 -252
- package/dist/CalendarDate.module.js.map +0 -1
- package/dist/DateFormatter.main.js.map +0 -1
- package/dist/DateFormatter.module.js.map +0 -1
- package/dist/EthiopicCalendar.main.js.map +0 -1
- package/dist/EthiopicCalendar.module.js.map +0 -1
- package/dist/GregorianCalendar.main.js.map +0 -1
- package/dist/GregorianCalendar.module.js.map +0 -1
- package/dist/HebrewCalendar.main.js.map +0 -1
- package/dist/HebrewCalendar.module.js.map +0 -1
- package/dist/IndianCalendar.main.js.map +0 -1
- package/dist/IndianCalendar.module.js.map +0 -1
- package/dist/IslamicCalendar.main.js +0 -168
- package/dist/IslamicCalendar.main.js.map +0 -1
- package/dist/IslamicCalendar.mjs +0 -161
- package/dist/IslamicCalendar.module.js +0 -161
- package/dist/IslamicCalendar.module.js.map +0 -1
- package/dist/JapaneseCalendar.main.js.map +0 -1
- package/dist/JapaneseCalendar.module.js.map +0 -1
- package/dist/PersianCalendar.main.js.map +0 -1
- package/dist/PersianCalendar.module.js.map +0 -1
- package/dist/TaiwanCalendar.module.js +0 -75
- package/dist/conversion.main.js.map +0 -1
- package/dist/conversion.module.js.map +0 -1
- package/dist/createCalendar.main.js +0 -69
- package/dist/createCalendar.main.js.map +0 -1
- package/dist/createCalendar.mjs +0 -64
- package/dist/createCalendar.module.js +0 -64
- package/dist/createCalendar.module.js.map +0 -1
- package/dist/import.mjs +0 -45
- package/dist/main.js +0 -113
- package/dist/main.js.map +0 -1
- package/dist/manipulation.main.js.map +0 -1
- package/dist/manipulation.module.js.map +0 -1
- package/dist/module.js +0 -45
- package/dist/module.js.map +0 -1
- package/dist/queries.main.js +0 -361
- package/dist/queries.main.js.map +0 -1
- package/dist/queries.mjs +0 -326
- package/dist/queries.module.js +0 -326
- package/dist/queries.module.js.map +0 -1
- package/dist/string.main.js +0 -190
- package/dist/string.main.js.map +0 -1
- package/dist/string.module.js +0 -175
- package/dist/string.module.js.map +0 -1
- package/dist/types.d.ts +0 -672
- package/dist/types.d.ts.map +0 -1
package/src/manipulation.ts
CHANGED
|
@@ -10,9 +10,29 @@
|
|
|
10
10
|
* governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
AnyCalendarDate,
|
|
15
|
+
AnyDateTime,
|
|
16
|
+
AnyTime,
|
|
17
|
+
CycleOptions,
|
|
18
|
+
CycleTimeOptions,
|
|
19
|
+
DateDuration,
|
|
20
|
+
DateField,
|
|
21
|
+
DateFields,
|
|
22
|
+
DateTimeDuration,
|
|
23
|
+
Disambiguation,
|
|
24
|
+
TimeDuration,
|
|
25
|
+
TimeField,
|
|
26
|
+
TimeFields
|
|
27
|
+
} from './types';
|
|
14
28
|
import {CalendarDate, CalendarDateTime, Time, ZonedDateTime} from './CalendarDate';
|
|
15
|
-
import {
|
|
29
|
+
import {
|
|
30
|
+
epochFromDate,
|
|
31
|
+
fromAbsolute,
|
|
32
|
+
toAbsolute,
|
|
33
|
+
toCalendar,
|
|
34
|
+
toCalendarDateTime
|
|
35
|
+
} from './conversion';
|
|
16
36
|
import {GregorianCalendar} from './calendars/GregorianCalendar';
|
|
17
37
|
import {Mutable} from './utils';
|
|
18
38
|
|
|
@@ -20,8 +40,14 @@ const ONE_HOUR = 3600000;
|
|
|
20
40
|
|
|
21
41
|
export function add(date: CalendarDateTime, duration: DateTimeDuration): CalendarDateTime;
|
|
22
42
|
export function add(date: CalendarDate, duration: DateDuration): CalendarDate;
|
|
23
|
-
export function add(
|
|
24
|
-
|
|
43
|
+
export function add(
|
|
44
|
+
date: CalendarDate | CalendarDateTime,
|
|
45
|
+
duration: DateTimeDuration
|
|
46
|
+
): CalendarDate | CalendarDateTime;
|
|
47
|
+
export function add(
|
|
48
|
+
date: CalendarDate | CalendarDateTime,
|
|
49
|
+
duration: DateTimeDuration
|
|
50
|
+
): Mutable<AnyCalendarDate | AnyDateTime> {
|
|
25
51
|
let mutableDate: Mutable<AnyCalendarDate | AnyDateTime> = date.copy();
|
|
26
52
|
let days = 'hour' in mutableDate ? addTimeFields(mutableDate, duration) : 0;
|
|
27
53
|
|
|
@@ -74,7 +100,10 @@ export function add(date: CalendarDate | CalendarDateTime, duration: DateTimeDur
|
|
|
74
100
|
mutableDate.day = mutableDate.calendar.getDaysInMonth(mutableDate);
|
|
75
101
|
}
|
|
76
102
|
|
|
77
|
-
mutableDate.day = Math.max(
|
|
103
|
+
mutableDate.day = Math.max(
|
|
104
|
+
1,
|
|
105
|
+
Math.min(mutableDate.calendar.getDaysInMonth(mutableDate), mutableDate.day)
|
|
106
|
+
);
|
|
78
107
|
return mutableDate;
|
|
79
108
|
}
|
|
80
109
|
|
|
@@ -140,13 +169,19 @@ export function invertDuration(duration: DateTimeDuration): DateTimeDuration {
|
|
|
140
169
|
|
|
141
170
|
export function subtract(date: CalendarDateTime, duration: DateTimeDuration): CalendarDateTime;
|
|
142
171
|
export function subtract(date: CalendarDate, duration: DateDuration): CalendarDate;
|
|
143
|
-
export function subtract(
|
|
172
|
+
export function subtract(
|
|
173
|
+
date: CalendarDate | CalendarDateTime,
|
|
174
|
+
duration: DateTimeDuration
|
|
175
|
+
): CalendarDate | CalendarDateTime {
|
|
144
176
|
return add(date, invertDuration(duration));
|
|
145
177
|
}
|
|
146
178
|
|
|
147
179
|
export function set(date: CalendarDateTime, fields: DateFields): CalendarDateTime;
|
|
148
180
|
export function set(date: CalendarDate, fields: DateFields): CalendarDate;
|
|
149
|
-
export function set(
|
|
181
|
+
export function set(
|
|
182
|
+
date: CalendarDate | CalendarDateTime,
|
|
183
|
+
fields: DateFields
|
|
184
|
+
): Mutable<AnyCalendarDate> {
|
|
150
185
|
let mutableDate: Mutable<AnyCalendarDate> = date.copy();
|
|
151
186
|
|
|
152
187
|
if (fields.era != null) {
|
|
@@ -171,7 +206,10 @@ export function set(date: CalendarDate | CalendarDateTime, fields: DateFields):
|
|
|
171
206
|
|
|
172
207
|
export function setTime(value: CalendarDateTime, fields: TimeFields): CalendarDateTime;
|
|
173
208
|
export function setTime(value: Time, fields: TimeFields): Time;
|
|
174
|
-
export function setTime(
|
|
209
|
+
export function setTime(
|
|
210
|
+
value: Time | CalendarDateTime,
|
|
211
|
+
fields: TimeFields
|
|
212
|
+
): Mutable<Time | CalendarDateTime> {
|
|
175
213
|
let mutableValue: Mutable<Time | CalendarDateTime> = value.copy();
|
|
176
214
|
|
|
177
215
|
if (fields.hour != null) {
|
|
@@ -243,9 +281,24 @@ export function subtractTime(time: Time, duration: TimeDuration): Time {
|
|
|
243
281
|
return addTime(time, invertDuration(duration));
|
|
244
282
|
}
|
|
245
283
|
|
|
246
|
-
export function cycleDate(
|
|
247
|
-
|
|
248
|
-
|
|
284
|
+
export function cycleDate(
|
|
285
|
+
value: CalendarDateTime,
|
|
286
|
+
field: DateField,
|
|
287
|
+
amount: number,
|
|
288
|
+
options?: CycleOptions
|
|
289
|
+
): CalendarDateTime;
|
|
290
|
+
export function cycleDate(
|
|
291
|
+
value: CalendarDate,
|
|
292
|
+
field: DateField,
|
|
293
|
+
amount: number,
|
|
294
|
+
options?: CycleOptions
|
|
295
|
+
): CalendarDate;
|
|
296
|
+
export function cycleDate(
|
|
297
|
+
value: CalendarDate | CalendarDateTime,
|
|
298
|
+
field: DateField,
|
|
299
|
+
amount: number,
|
|
300
|
+
options?: CycleOptions
|
|
301
|
+
): Mutable<CalendarDate | CalendarDateTime> {
|
|
249
302
|
let mutable: Mutable<CalendarDate | CalendarDateTime> = value.copy();
|
|
250
303
|
|
|
251
304
|
switch (field) {
|
|
@@ -281,10 +334,22 @@ export function cycleDate(value: CalendarDate | CalendarDateTime, field: DateFie
|
|
|
281
334
|
break;
|
|
282
335
|
}
|
|
283
336
|
case 'month':
|
|
284
|
-
mutable.month = cycleValue(
|
|
337
|
+
mutable.month = cycleValue(
|
|
338
|
+
value.month,
|
|
339
|
+
amount,
|
|
340
|
+
1,
|
|
341
|
+
value.calendar.getMonthsInYear(value),
|
|
342
|
+
options?.round
|
|
343
|
+
);
|
|
285
344
|
break;
|
|
286
345
|
case 'day':
|
|
287
|
-
mutable.day = cycleValue(
|
|
346
|
+
mutable.day = cycleValue(
|
|
347
|
+
value.day,
|
|
348
|
+
amount,
|
|
349
|
+
1,
|
|
350
|
+
value.calendar.getDaysInMonth(value),
|
|
351
|
+
options?.round
|
|
352
|
+
);
|
|
288
353
|
break;
|
|
289
354
|
default:
|
|
290
355
|
throw new Error('Unsupported field ' + field);
|
|
@@ -298,9 +363,24 @@ export function cycleDate(value: CalendarDate | CalendarDateTime, field: DateFie
|
|
|
298
363
|
return mutable;
|
|
299
364
|
}
|
|
300
365
|
|
|
301
|
-
export function cycleTime(
|
|
302
|
-
|
|
303
|
-
|
|
366
|
+
export function cycleTime(
|
|
367
|
+
value: CalendarDateTime,
|
|
368
|
+
field: TimeField,
|
|
369
|
+
amount: number,
|
|
370
|
+
options?: CycleTimeOptions
|
|
371
|
+
): CalendarDateTime;
|
|
372
|
+
export function cycleTime(
|
|
373
|
+
value: Time,
|
|
374
|
+
field: TimeField,
|
|
375
|
+
amount: number,
|
|
376
|
+
options?: CycleTimeOptions
|
|
377
|
+
): Time;
|
|
378
|
+
export function cycleTime(
|
|
379
|
+
value: Time | CalendarDateTime,
|
|
380
|
+
field: TimeField,
|
|
381
|
+
amount: number,
|
|
382
|
+
options?: CycleTimeOptions
|
|
383
|
+
): Mutable<Time | CalendarDateTime> {
|
|
304
384
|
let mutable: Mutable<Time | CalendarDateTime> = value.copy();
|
|
305
385
|
|
|
306
386
|
switch (field) {
|
|
@@ -364,7 +444,12 @@ function cycleValue(value: number, amount: number, min: number, max: number, rou
|
|
|
364
444
|
|
|
365
445
|
export function addZoned(dateTime: ZonedDateTime, duration: DateTimeDuration): ZonedDateTime {
|
|
366
446
|
let ms: number;
|
|
367
|
-
if (
|
|
447
|
+
if (
|
|
448
|
+
(duration.years != null && duration.years !== 0) ||
|
|
449
|
+
(duration.months != null && duration.months !== 0) ||
|
|
450
|
+
(duration.weeks != null && duration.weeks !== 0) ||
|
|
451
|
+
(duration.days != null && duration.days !== 0)
|
|
452
|
+
) {
|
|
368
453
|
let res = add(toCalendarDateTime(dateTime), {
|
|
369
454
|
years: duration.years,
|
|
370
455
|
months: duration.months,
|
|
@@ -396,7 +481,12 @@ export function subtractZoned(dateTime: ZonedDateTime, duration: DateTimeDuratio
|
|
|
396
481
|
return addZoned(dateTime, invertDuration(duration));
|
|
397
482
|
}
|
|
398
483
|
|
|
399
|
-
export function cycleZoned(
|
|
484
|
+
export function cycleZoned(
|
|
485
|
+
dateTime: ZonedDateTime,
|
|
486
|
+
field: DateField | TimeField,
|
|
487
|
+
amount: number,
|
|
488
|
+
options?: CycleTimeOptions
|
|
489
|
+
): ZonedDateTime {
|
|
400
490
|
// For date fields, we want the time to remain consistent and the UTC offset to potentially change to account for DST changes.
|
|
401
491
|
// For time fields, we want the time to change by the amount given. This may result in the hour field staying the same, but the UTC
|
|
402
492
|
// offset changing in the case of a backward DST transition, or skipping an hour in the case of a forward DST transition.
|
|
@@ -417,12 +507,18 @@ export function cycleZoned(dateTime: ZonedDateTime, field: DateField | TimeField
|
|
|
417
507
|
// that is within the current day.
|
|
418
508
|
let plainDateTime = toCalendarDateTime(dateTime);
|
|
419
509
|
let minDate = toCalendar(setTime(plainDateTime, {hour: min}), new GregorianCalendar());
|
|
420
|
-
let minAbsolute = [
|
|
421
|
-
|
|
510
|
+
let minAbsolute = [
|
|
511
|
+
toAbsolute(minDate, dateTime.timeZone, 'earlier'),
|
|
512
|
+
toAbsolute(minDate, dateTime.timeZone, 'later')
|
|
513
|
+
].filter(ms => fromAbsolute(ms, dateTime.timeZone).day === minDate.day)[0];
|
|
422
514
|
|
|
423
515
|
let maxDate = toCalendar(setTime(plainDateTime, {hour: max}), new GregorianCalendar());
|
|
424
|
-
let maxAbsolute = [
|
|
425
|
-
|
|
516
|
+
let maxAbsolute = [
|
|
517
|
+
toAbsolute(maxDate, dateTime.timeZone, 'earlier'),
|
|
518
|
+
toAbsolute(maxDate, dateTime.timeZone, 'later')
|
|
519
|
+
]
|
|
520
|
+
.filter(ms => fromAbsolute(ms, dateTime.timeZone).day === maxDate.day)
|
|
521
|
+
.pop()!;
|
|
426
522
|
|
|
427
523
|
// Since hours may repeat, we need to operate on the absolute time in milliseconds.
|
|
428
524
|
// This is done in hours from the Unix epoch so that cycleValue works correctly,
|
|
@@ -430,13 +526,16 @@ export function cycleZoned(dateTime: ZonedDateTime, field: DateField | TimeField
|
|
|
430
526
|
let ms = epochFromDate(dateTime) - dateTime.offset;
|
|
431
527
|
let hours = Math.floor(ms / ONE_HOUR);
|
|
432
528
|
let remainder = ms % ONE_HOUR;
|
|
433
|
-
ms =
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
529
|
+
ms =
|
|
530
|
+
cycleValue(
|
|
531
|
+
hours,
|
|
532
|
+
amount,
|
|
533
|
+
Math.floor(minAbsolute / ONE_HOUR),
|
|
534
|
+
Math.floor(maxAbsolute / ONE_HOUR),
|
|
535
|
+
options?.round
|
|
536
|
+
) *
|
|
537
|
+
ONE_HOUR +
|
|
538
|
+
remainder;
|
|
440
539
|
|
|
441
540
|
// Now compute the new timezone offset, and convert the absolute time back to local time.
|
|
442
541
|
return toCalendar(fromAbsolute(ms, dateTime.timeZone), dateTime.calendar);
|
|
@@ -459,7 +558,11 @@ export function cycleZoned(dateTime: ZonedDateTime, field: DateField | TimeField
|
|
|
459
558
|
}
|
|
460
559
|
}
|
|
461
560
|
|
|
462
|
-
export function setZoned(
|
|
561
|
+
export function setZoned(
|
|
562
|
+
dateTime: ZonedDateTime,
|
|
563
|
+
fields: DateFields & TimeFields,
|
|
564
|
+
disambiguation?: Disambiguation
|
|
565
|
+
): ZonedDateTime {
|
|
463
566
|
// Set the date/time fields, and recompute the UTC offset to account for DST changes.
|
|
464
567
|
// We also need to validate by converting back to a local time in case hours are skipped during forward DST transitions.
|
|
465
568
|
let plainDateTime = toCalendarDateTime(dateTime);
|
package/src/queries.ts
CHANGED
|
@@ -11,19 +11,20 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import {AnyCalendarDate, AnyTime, Calendar} from './types';
|
|
14
|
-
import {CalendarDate, CalendarDateTime, ZonedDateTime} from './CalendarDate';
|
|
14
|
+
import {CalendarDate, CalendarDateTime, DateValue, ZonedDateTime} from './CalendarDate';
|
|
15
15
|
import {fromAbsolute, toAbsolute, toCalendar, toCalendarDate} from './conversion';
|
|
16
16
|
import {weekStartData} from './weekStartData';
|
|
17
17
|
|
|
18
|
-
type DateValue = CalendarDate | CalendarDateTime | ZonedDateTime;
|
|
19
|
-
|
|
20
18
|
/** Returns whether the given dates occur on the same day, regardless of the time or calendar system. */
|
|
21
19
|
export function isSameDay(a: DateValue, b: DateValue): boolean {
|
|
22
20
|
b = toCalendar(b, a.calendar);
|
|
23
21
|
return a.era === b.era && a.year === b.year && a.month === b.month && a.day === b.day;
|
|
24
22
|
}
|
|
25
23
|
|
|
26
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* Returns whether the given dates occur in the same month, using the calendar system of the first
|
|
26
|
+
* date.
|
|
27
|
+
*/
|
|
27
28
|
export function isSameMonth(a: DateValue, b: DateValue): boolean {
|
|
28
29
|
b = toCalendar(b, a.calendar);
|
|
29
30
|
// In the Japanese calendar, months can span multiple eras/years, so only compare the first of the month.
|
|
@@ -32,7 +33,10 @@ export function isSameMonth(a: DateValue, b: DateValue): boolean {
|
|
|
32
33
|
return a.era === b.era && a.year === b.year && a.month === b.month;
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* Returns whether the given dates occur in the same year, using the calendar system of the first
|
|
38
|
+
* date.
|
|
39
|
+
*/
|
|
36
40
|
export function isSameYear(a: DateValue, b: DateValue): boolean {
|
|
37
41
|
b = toCalendar(b, a.calendar);
|
|
38
42
|
a = startOfYear(a);
|
|
@@ -212,19 +216,47 @@ export function getMinimumDayInMonth(date: AnyCalendarDate): number {
|
|
|
212
216
|
}
|
|
213
217
|
|
|
214
218
|
/** Returns the first date of the week for the given date and locale. */
|
|
215
|
-
export function startOfWeek(
|
|
216
|
-
|
|
217
|
-
|
|
219
|
+
export function startOfWeek(
|
|
220
|
+
date: ZonedDateTime,
|
|
221
|
+
locale: string,
|
|
222
|
+
firstDayOfWeek?: DayOfWeek
|
|
223
|
+
): ZonedDateTime;
|
|
224
|
+
export function startOfWeek(
|
|
225
|
+
date: CalendarDateTime,
|
|
226
|
+
locale: string,
|
|
227
|
+
firstDayOfWeek?: DayOfWeek
|
|
228
|
+
): CalendarDateTime;
|
|
229
|
+
export function startOfWeek(
|
|
230
|
+
date: CalendarDate,
|
|
231
|
+
locale: string,
|
|
232
|
+
firstDayOfWeek?: DayOfWeek
|
|
233
|
+
): CalendarDate;
|
|
218
234
|
export function startOfWeek(date: DateValue, locale: string, firstDayOfWeek?: DayOfWeek): DateValue;
|
|
219
|
-
export function startOfWeek(
|
|
235
|
+
export function startOfWeek(
|
|
236
|
+
date: DateValue,
|
|
237
|
+
locale: string,
|
|
238
|
+
firstDayOfWeek?: DayOfWeek
|
|
239
|
+
): DateValue {
|
|
220
240
|
let dayOfWeek = getDayOfWeek(date, locale, firstDayOfWeek);
|
|
221
241
|
return date.subtract({days: dayOfWeek});
|
|
222
242
|
}
|
|
223
243
|
|
|
224
244
|
/** Returns the last date of the week for the given date and locale. */
|
|
225
|
-
export function endOfWeek(
|
|
226
|
-
|
|
227
|
-
|
|
245
|
+
export function endOfWeek(
|
|
246
|
+
date: ZonedDateTime,
|
|
247
|
+
locale: string,
|
|
248
|
+
firstDayOfWeek?: DayOfWeek
|
|
249
|
+
): ZonedDateTime;
|
|
250
|
+
export function endOfWeek(
|
|
251
|
+
date: CalendarDateTime,
|
|
252
|
+
locale: string,
|
|
253
|
+
firstDayOfWeek?: DayOfWeek
|
|
254
|
+
): CalendarDateTime;
|
|
255
|
+
export function endOfWeek(
|
|
256
|
+
date: CalendarDate,
|
|
257
|
+
locale: string,
|
|
258
|
+
firstDayOfWeek?: DayOfWeek
|
|
259
|
+
): CalendarDate;
|
|
228
260
|
export function endOfWeek(date: DateValue, locale: string, firstDayOfWeek?: DayOfWeek): DateValue;
|
|
229
261
|
export function endOfWeek(date: DateValue, locale: string, firstDayOfWeek?: DayOfWeek): DateValue {
|
|
230
262
|
return startOfWeek(date, locale, firstDayOfWeek).add({days: 6});
|
|
@@ -306,13 +338,20 @@ function getWeekStart(locale: string): number {
|
|
|
306
338
|
}
|
|
307
339
|
|
|
308
340
|
/** Returns the number of weeks in the given month and locale. */
|
|
309
|
-
export function getWeeksInMonth(
|
|
341
|
+
export function getWeeksInMonth(
|
|
342
|
+
date: DateValue,
|
|
343
|
+
locale: string,
|
|
344
|
+
firstDayOfWeek?: DayOfWeek
|
|
345
|
+
): number {
|
|
310
346
|
let days = date.calendar.getDaysInMonth(date);
|
|
311
347
|
return Math.ceil((getDayOfWeek(startOfMonth(date), locale, firstDayOfWeek) + days) / 7);
|
|
312
348
|
}
|
|
313
349
|
|
|
314
350
|
/** Returns the lesser of the two provider dates. */
|
|
315
|
-
export function minDate<A extends DateValue, B extends DateValue>(
|
|
351
|
+
export function minDate<A extends DateValue, B extends DateValue>(
|
|
352
|
+
a?: A | null,
|
|
353
|
+
b?: B | null
|
|
354
|
+
): A | B | null | undefined {
|
|
316
355
|
if (a && b) {
|
|
317
356
|
return a.compare(b) <= 0 ? a : b;
|
|
318
357
|
}
|
|
@@ -321,7 +360,10 @@ export function minDate<A extends DateValue, B extends DateValue>(a?: A | null,
|
|
|
321
360
|
}
|
|
322
361
|
|
|
323
362
|
/** Returns the greater of the two provider dates. */
|
|
324
|
-
export function maxDate<A extends DateValue, B extends DateValue>(
|
|
363
|
+
export function maxDate<A extends DateValue, B extends DateValue>(
|
|
364
|
+
a?: A | null,
|
|
365
|
+
b?: B | null
|
|
366
|
+
): A | B | null | undefined {
|
|
325
367
|
if (a && b) {
|
|
326
368
|
return a.compare(b) >= 0 ? a : b;
|
|
327
369
|
}
|
package/src/string.ts
CHANGED
|
@@ -12,18 +12,29 @@
|
|
|
12
12
|
|
|
13
13
|
import {AnyDateTime, DateTimeDuration, Disambiguation} from './types';
|
|
14
14
|
import {CalendarDate, CalendarDateTime, Time, ZonedDateTime} from './CalendarDate';
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
epochFromDate,
|
|
17
|
+
fromAbsolute,
|
|
18
|
+
possibleAbsolutes,
|
|
19
|
+
toAbsolute,
|
|
20
|
+
toCalendar,
|
|
21
|
+
toCalendarDateTime,
|
|
22
|
+
toTimeZone
|
|
23
|
+
} from './conversion';
|
|
16
24
|
import {getLocalTimeZone} from './queries';
|
|
17
25
|
import {GregorianCalendar} from './calendars/GregorianCalendar';
|
|
18
26
|
import {Mutable} from './utils';
|
|
19
27
|
|
|
20
28
|
const TIME_RE = /^(\d{2})(?::(\d{2}))?(?::(\d{2}))?(\.\d+)?$/;
|
|
21
29
|
const DATE_RE = /^([+-]\d{6}|\d{4})-(\d{2})-(\d{2})$/;
|
|
22
|
-
const DATE_TIME_RE =
|
|
23
|
-
|
|
24
|
-
const
|
|
30
|
+
const DATE_TIME_RE =
|
|
31
|
+
/^([+-]\d{6}|\d{4})-(\d{2})-(\d{2})(?:T(\d{2}))?(?::(\d{2}))?(?::(\d{2}))?(\.\d+)?$/;
|
|
32
|
+
const ZONED_DATE_TIME_RE =
|
|
33
|
+
/^([+-]\d{6}|\d{4})-(\d{2})-(\d{2})(?:T(\d{2}))?(?::(\d{2}))?(?::(\d{2}))?(\.\d+)?(?:([+-]\d{2})(?::?(\d{2}))?(?::?(\d{2}))?)?\[(.*?)\]$/;
|
|
34
|
+
const ABSOLUTE_RE =
|
|
35
|
+
/^([+-]\d{6}|\d{4})-(\d{2})-(\d{2})(?:T(\d{2}))?(?::(\d{2}))?(?::(\d{2}))?(\.\d+)?(?:(?:([+-]\d{2})(?::?(\d{2}))?)|Z)$/;
|
|
25
36
|
const DATE_TIME_DURATION_RE =
|
|
26
|
-
|
|
37
|
+
/^((?<negative>-)|\+)?P((?<years>\d*)Y)?((?<months>\d*)M)?((?<weeks>\d*)W)?((?<days>\d*)D)?((?<time>T)((?<hours>\d*[.,]?\d{1,9})H)?((?<minutes>\d*[.,]?\d{1,9})M)?((?<seconds>\d*[.,]?\d{1,9})S)?)?$/;
|
|
27
38
|
const requiredDurationTimeGroups = ['hours', 'minutes', 'seconds'];
|
|
28
39
|
const requiredDurationGroups = ['years', 'months', 'weeks', 'days', ...requiredDurationTimeGroups];
|
|
29
40
|
|
|
@@ -91,10 +102,10 @@ export function parseDateTime(value: string): CalendarDateTime {
|
|
|
91
102
|
}
|
|
92
103
|
|
|
93
104
|
/**
|
|
94
|
-
* Parses an ISO 8601 date and time string with a time zone extension and optional UTC offset
|
|
95
|
-
*
|
|
96
|
-
* Ambiguous times due to daylight saving time transitions are resolved according to the
|
|
97
|
-
* parameter.
|
|
105
|
+
* Parses an ISO 8601 date and time string with a time zone extension and optional UTC offset (e.g.
|
|
106
|
+
* "2021-11-07T00:45[America/Los_Angeles]" or "2021-11-07T00:45-07:00[America/Los_Angeles]").
|
|
107
|
+
* Ambiguous times due to daylight saving time transitions are resolved according to the
|
|
108
|
+
* `disambiguation` parameter.
|
|
98
109
|
*/
|
|
99
110
|
export function parseZonedDateTime(value: string, disambiguation?: Disambiguation): ZonedDateTime {
|
|
100
111
|
let m = value.match(ZONED_DATE_TIME_RE);
|
|
@@ -125,13 +136,19 @@ export function parseZonedDateTime(value: string, disambiguation?: Disambiguatio
|
|
|
125
136
|
let ms: number;
|
|
126
137
|
if (m[8]) {
|
|
127
138
|
let hourOffset = parseNumber(m[8], -23, 23);
|
|
128
|
-
date.offset =
|
|
139
|
+
date.offset =
|
|
140
|
+
Math.sign(hourOffset) *
|
|
141
|
+
(Math.abs(hourOffset) * 60 * 60 * 1000 +
|
|
142
|
+
parseNumber(m[9] ?? '0', 0, 59) * 60 * 1000 +
|
|
143
|
+
parseNumber(m[10] ?? '0', 0, 59) * 1000);
|
|
129
144
|
ms = epochFromDate(date as ZonedDateTime) - date.offset;
|
|
130
145
|
|
|
131
146
|
// Validate offset against parsed date.
|
|
132
147
|
let absolutes = possibleAbsolutes(plainDateTime, date.timeZone);
|
|
133
148
|
if (!absolutes.includes(ms)) {
|
|
134
|
-
throw new Error(
|
|
149
|
+
throw new Error(
|
|
150
|
+
`Offset ${offsetToString(date.offset)} is invalid for ${dateTimeToString(date)} in ${date.timeZone}`
|
|
151
|
+
);
|
|
135
152
|
}
|
|
136
153
|
} else {
|
|
137
154
|
// Convert to absolute and back to fix invalid times due to DST.
|
|
@@ -170,7 +187,8 @@ export function parseAbsolute(value: string, timeZone: string): ZonedDateTime {
|
|
|
170
187
|
date.day = parseNumber(m[3], 0, date.calendar.getDaysInMonth(date));
|
|
171
188
|
|
|
172
189
|
if (m[8]) {
|
|
173
|
-
date.offset =
|
|
190
|
+
date.offset =
|
|
191
|
+
parseNumber(m[8], -23, 23) * 60 * 60 * 1000 + parseNumber(m[9] ?? '0', 0, 59) * 60 * 1000;
|
|
174
192
|
}
|
|
175
193
|
|
|
176
194
|
return toTimeZone(date as ZonedDateTime, timeZone);
|
|
@@ -201,9 +219,10 @@ export function dateToString(date: CalendarDate): string {
|
|
|
201
219
|
let gregorianDate = toCalendar(date, new GregorianCalendar());
|
|
202
220
|
let year: string;
|
|
203
221
|
if (gregorianDate.era === 'BC') {
|
|
204
|
-
year =
|
|
205
|
-
|
|
206
|
-
|
|
222
|
+
year =
|
|
223
|
+
gregorianDate.year === 1
|
|
224
|
+
? '0000'
|
|
225
|
+
: '-' + String(Math.abs(1 - gregorianDate.year)).padStart(6, '00');
|
|
207
226
|
} else {
|
|
208
227
|
year = String(gregorianDate.year).padStart(4, '0');
|
|
209
228
|
}
|
|
@@ -220,7 +239,7 @@ function offsetToString(offset: number) {
|
|
|
220
239
|
offset = Math.abs(offset);
|
|
221
240
|
let offsetHours = Math.floor(offset / (60 * 60 * 1000));
|
|
222
241
|
let offsetMinutes = Math.floor((offset % (60 * 60 * 1000)) / (60 * 1000));
|
|
223
|
-
let offsetSeconds = Math.floor((offset % (60 * 60 * 1000)) % (60 * 1000) / 1000);
|
|
242
|
+
let offsetSeconds = Math.floor(((offset % (60 * 60 * 1000)) % (60 * 1000)) / 1000);
|
|
224
243
|
let stringOffset = `${sign}${String(offsetHours).padStart(2, '0')}:${String(offsetMinutes).padStart(2, '0')}`;
|
|
225
244
|
if (offsetSeconds !== 0) {
|
|
226
245
|
stringOffset += `:${String(offsetSeconds).padStart(2, '0')}`;
|
|
@@ -235,6 +254,7 @@ export function zonedDateTimeToString(date: ZonedDateTime): string {
|
|
|
235
254
|
|
|
236
255
|
/**
|
|
237
256
|
* Parses an ISO 8601 duration string (e.g. "P3Y6M6W4DT12H30M5S").
|
|
257
|
+
*
|
|
238
258
|
* @param value An ISO 8601 duration string.
|
|
239
259
|
* @returns A DateTimeDuration object.
|
|
240
260
|
*/
|
|
@@ -245,10 +265,7 @@ export function parseDuration(value: string): Required<DateTimeDuration> {
|
|
|
245
265
|
throw new Error(`Invalid ISO 8601 Duration string: ${value}`);
|
|
246
266
|
}
|
|
247
267
|
|
|
248
|
-
const parseDurationGroup = (
|
|
249
|
-
group: string | undefined,
|
|
250
|
-
isNegative: boolean
|
|
251
|
-
): number => {
|
|
268
|
+
const parseDurationGroup = (group: string | undefined, isNegative: boolean): number => {
|
|
252
269
|
if (!group) {
|
|
253
270
|
return 0;
|
|
254
271
|
}
|
|
@@ -271,7 +288,9 @@ export function parseDuration(value: string): Required<DateTimeDuration> {
|
|
|
271
288
|
const durationStringIncludesTime = match.groups?.time;
|
|
272
289
|
|
|
273
290
|
if (durationStringIncludesTime) {
|
|
274
|
-
const hasRequiredDurationTimeGroups = requiredDurationTimeGroups.some(
|
|
291
|
+
const hasRequiredDurationTimeGroups = requiredDurationTimeGroups.some(
|
|
292
|
+
group => match.groups?.[group]
|
|
293
|
+
);
|
|
275
294
|
if (!hasRequiredDurationTimeGroups) {
|
|
276
295
|
throw new Error(`Invalid ISO 8601 Duration string: ${value}`);
|
|
277
296
|
}
|
|
@@ -287,12 +306,20 @@ export function parseDuration(value: string): Required<DateTimeDuration> {
|
|
|
287
306
|
seconds: parseDurationGroup(match.groups?.seconds, isNegative)
|
|
288
307
|
};
|
|
289
308
|
|
|
290
|
-
if (
|
|
291
|
-
|
|
309
|
+
if (
|
|
310
|
+
duration.hours !== undefined &&
|
|
311
|
+
duration.hours % 1 !== 0 &&
|
|
312
|
+
(duration.minutes || duration.seconds)
|
|
313
|
+
) {
|
|
314
|
+
throw new Error(
|
|
315
|
+
`Invalid ISO 8601 Duration string: ${value} - only the smallest unit can be fractional`
|
|
316
|
+
);
|
|
292
317
|
}
|
|
293
318
|
|
|
294
|
-
if (duration.minutes !== undefined &&
|
|
295
|
-
throw new Error(
|
|
319
|
+
if (duration.minutes !== undefined && duration.minutes % 1 !== 0 && duration.seconds) {
|
|
320
|
+
throw new Error(
|
|
321
|
+
`Invalid ISO 8601 Duration string: ${value} - only the smallest unit can be fractional`
|
|
322
|
+
);
|
|
296
323
|
}
|
|
297
324
|
|
|
298
325
|
return duration as Required<DateTimeDuration>;
|