@internationalized/date 3.12.1 → 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.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/private/CalendarDate.cjs +40 -10
- package/dist/private/CalendarDate.cjs.map +1 -1
- package/dist/private/CalendarDate.js +40 -10
- package/dist/private/CalendarDate.js.map +1 -1
- package/dist/private/CalendarDate.mjs +40 -10
- package/dist/private/CalendarDate.mjs.map +1 -1
- package/dist/private/DateFormatter.cjs +4 -1
- package/dist/private/DateFormatter.cjs.map +1 -1
- package/dist/private/DateFormatter.js +4 -1
- package/dist/private/DateFormatter.js.map +1 -1
- package/dist/private/DateFormatter.mjs +4 -1
- package/dist/private/DateFormatter.mjs.map +1 -1
- package/dist/private/calendars/BuddhistCalendar.cjs.map +1 -1
- package/dist/private/calendars/BuddhistCalendar.js.map +1 -1
- package/dist/private/calendars/BuddhistCalendar.mjs.map +1 -1
- package/dist/private/calendars/EthiopicCalendar.cjs +5 -5
- package/dist/private/calendars/EthiopicCalendar.cjs.map +1 -1
- package/dist/private/calendars/EthiopicCalendar.js +5 -5
- package/dist/private/calendars/EthiopicCalendar.js.map +1 -1
- package/dist/private/calendars/EthiopicCalendar.mjs +5 -5
- package/dist/private/calendars/EthiopicCalendar.mjs.map +1 -1
- package/dist/private/calendars/GregorianCalendar.cjs.map +1 -1
- package/dist/private/calendars/GregorianCalendar.js.map +1 -1
- package/dist/private/calendars/GregorianCalendar.mjs.map +1 -1
- package/dist/private/calendars/HebrewCalendar.cjs.map +1 -1
- package/dist/private/calendars/HebrewCalendar.js.map +1 -1
- package/dist/private/calendars/HebrewCalendar.mjs.map +1 -1
- package/dist/private/calendars/IndianCalendar.cjs.map +1 -1
- package/dist/private/calendars/IndianCalendar.js.map +1 -1
- package/dist/private/calendars/IndianCalendar.mjs.map +1 -1
- package/dist/private/calendars/IslamicCalendar.cjs.map +1 -1
- package/dist/private/calendars/IslamicCalendar.js.map +1 -1
- package/dist/private/calendars/IslamicCalendar.mjs.map +1 -1
- package/dist/private/calendars/JapaneseCalendar.cjs.map +1 -1
- package/dist/private/calendars/JapaneseCalendar.js.map +1 -1
- package/dist/private/calendars/JapaneseCalendar.mjs.map +1 -1
- package/dist/private/calendars/PersianCalendar.cjs.map +1 -1
- package/dist/private/calendars/PersianCalendar.js.map +1 -1
- package/dist/private/calendars/PersianCalendar.mjs.map +1 -1
- package/dist/private/calendars/TaiwanCalendar.cjs.map +1 -1
- package/dist/private/calendars/TaiwanCalendar.js.map +1 -1
- package/dist/private/calendars/TaiwanCalendar.mjs.map +1 -1
- package/dist/private/conversion.cjs.map +1 -1
- package/dist/private/conversion.js.map +1 -1
- package/dist/private/conversion.mjs.map +1 -1
- package/dist/private/createCalendar.cjs.map +1 -1
- package/dist/private/createCalendar.js.map +1 -1
- package/dist/private/createCalendar.mjs.map +1 -1
- package/dist/private/manipulation.cjs.map +1 -1
- package/dist/private/manipulation.js.map +1 -1
- package/dist/private/manipulation.mjs.map +1 -1
- package/dist/private/queries.cjs.map +1 -1
- package/dist/private/queries.js.map +1 -1
- package/dist/private/queries.mjs.map +1 -1
- package/dist/private/string.cjs.map +1 -1
- package/dist/private/string.js.map +1 -1
- package/dist/private/string.mjs.map +1 -1
- package/dist/private/utils.cjs.map +1 -1
- package/dist/private/utils.js.map +1 -1
- package/dist/private/utils.mjs.map +1 -1
- package/dist/types/src/CalendarDate.d.ts +40 -10
- package/dist/types/src/DateFormatter.d.ts +4 -1
- package/dist/types/src/calendars/GregorianCalendar.d.ts +3 -2
- package/dist/types/src/calendars/IslamicCalendar.d.ts +18 -15
- package/dist/types/src/calendars/JapaneseCalendar.d.ts +4 -3
- package/dist/types/src/conversion.d.ts +8 -5
- package/dist/types/src/queries.d.ts +8 -2
- package/dist/types/src/string.d.ts +5 -4
- package/dist/types/src/types.d.ts +7 -3
- package/package.json +16 -16
- package/src/CalendarDate.ts +213 -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 +10 -2
- package/src/manipulation.ts +133 -30
- package/src/queries.ts +56 -12
- package/src/string.ts +52 -25
- package/src/types.ts +73 -51
- package/src/utils.ts +1 -1
package/src/CalendarDate.ts
CHANGED
|
@@ -10,8 +10,37 @@
|
|
|
10
10
|
* governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import {
|
|
14
|
-
|
|
13
|
+
import {
|
|
14
|
+
add,
|
|
15
|
+
addTime,
|
|
16
|
+
addZoned,
|
|
17
|
+
constrain,
|
|
18
|
+
constrainTime,
|
|
19
|
+
cycleDate,
|
|
20
|
+
cycleTime,
|
|
21
|
+
cycleZoned,
|
|
22
|
+
set,
|
|
23
|
+
setTime,
|
|
24
|
+
setZoned,
|
|
25
|
+
subtract,
|
|
26
|
+
subtractTime,
|
|
27
|
+
subtractZoned
|
|
28
|
+
} from './manipulation';
|
|
29
|
+
import {
|
|
30
|
+
AnyCalendarDate,
|
|
31
|
+
AnyTime,
|
|
32
|
+
Calendar,
|
|
33
|
+
CycleOptions,
|
|
34
|
+
CycleTimeOptions,
|
|
35
|
+
DateDuration,
|
|
36
|
+
DateField,
|
|
37
|
+
DateFields,
|
|
38
|
+
DateTimeDuration,
|
|
39
|
+
Disambiguation,
|
|
40
|
+
TimeDuration,
|
|
41
|
+
TimeField,
|
|
42
|
+
TimeFields
|
|
43
|
+
} from './types';
|
|
15
44
|
import {compareDate, compareTime} from './queries';
|
|
16
45
|
import {dateTimeToString, dateToString, timeToString, zonedDateTimeToString} from './string';
|
|
17
46
|
import {GregorianCalendar} from './calendars/GregorianCalendar';
|
|
@@ -20,9 +49,7 @@ import {toCalendarDateTime, toDate, toZoned, zonedToDate} from './conversion';
|
|
|
20
49
|
export type DateValue = CalendarDate | CalendarDateTime | ZonedDateTime;
|
|
21
50
|
|
|
22
51
|
function shiftArgs(args: any[]) {
|
|
23
|
-
let calendar: Calendar = typeof args[0] === 'object'
|
|
24
|
-
? args.shift()
|
|
25
|
-
: new GregorianCalendar();
|
|
52
|
+
let calendar: Calendar = typeof args[0] === 'object' ? args.shift() : new GregorianCalendar();
|
|
26
53
|
|
|
27
54
|
let era: string;
|
|
28
55
|
if (typeof args[0] === 'string') {
|
|
@@ -95,7 +122,10 @@ export class CalendarDate {
|
|
|
95
122
|
return subtract(this, duration);
|
|
96
123
|
}
|
|
97
124
|
|
|
98
|
-
/**
|
|
125
|
+
/**
|
|
126
|
+
* Returns a new `CalendarDate` with the given fields set to the provided values. Other fields
|
|
127
|
+
* will be constrained accordingly.
|
|
128
|
+
*/
|
|
99
129
|
set(fields: DateFields): CalendarDate {
|
|
100
130
|
return set(this, fields);
|
|
101
131
|
}
|
|
@@ -108,7 +138,10 @@ export class CalendarDate {
|
|
|
108
138
|
return cycleDate(this, field, amount, options);
|
|
109
139
|
}
|
|
110
140
|
|
|
111
|
-
/**
|
|
141
|
+
/**
|
|
142
|
+
* Converts the date to a native JavaScript Date object, with the time set to midnight in the
|
|
143
|
+
* given time zone.
|
|
144
|
+
*/
|
|
112
145
|
toDate(timeZone: string): Date {
|
|
113
146
|
return toDate(this, timeZone);
|
|
114
147
|
}
|
|
@@ -118,7 +151,10 @@ export class CalendarDate {
|
|
|
118
151
|
return dateToString(this);
|
|
119
152
|
}
|
|
120
153
|
|
|
121
|
-
/**
|
|
154
|
+
/**
|
|
155
|
+
* Compares this date with another. A negative result indicates that this date is before the given
|
|
156
|
+
* one, and a positive date indicates that it is after.
|
|
157
|
+
*/
|
|
122
158
|
compare(b: AnyCalendarDate): number {
|
|
123
159
|
return compareDate(this, b);
|
|
124
160
|
}
|
|
@@ -138,12 +174,7 @@ export class Time {
|
|
|
138
174
|
/** The millisecond in the second. */
|
|
139
175
|
public readonly millisecond: number;
|
|
140
176
|
|
|
141
|
-
constructor(
|
|
142
|
-
hour: number = 0,
|
|
143
|
-
minute: number = 0,
|
|
144
|
-
second: number = 0,
|
|
145
|
-
millisecond: number = 0
|
|
146
|
-
) {
|
|
177
|
+
constructor(hour: number = 0, minute: number = 0, second: number = 0, millisecond: number = 0) {
|
|
147
178
|
this.hour = hour;
|
|
148
179
|
this.minute = minute;
|
|
149
180
|
this.second = second;
|
|
@@ -166,7 +197,10 @@ export class Time {
|
|
|
166
197
|
return subtractTime(this, duration);
|
|
167
198
|
}
|
|
168
199
|
|
|
169
|
-
/**
|
|
200
|
+
/**
|
|
201
|
+
* Returns a new `Time` with the given fields set to the provided values. Other fields will be
|
|
202
|
+
* constrained accordingly.
|
|
203
|
+
*/
|
|
170
204
|
set(fields: TimeFields): Time {
|
|
171
205
|
return setTime(this, fields);
|
|
172
206
|
}
|
|
@@ -184,7 +218,10 @@ export class Time {
|
|
|
184
218
|
return timeToString(this);
|
|
185
219
|
}
|
|
186
220
|
|
|
187
|
-
/**
|
|
221
|
+
/**
|
|
222
|
+
* Compares this time with another. A negative result indicates that this time is before the given
|
|
223
|
+
* one, and a positive time indicates that it is after.
|
|
224
|
+
*/
|
|
188
225
|
compare(b: AnyTime): number {
|
|
189
226
|
return compareTime(this, b);
|
|
190
227
|
}
|
|
@@ -218,10 +255,46 @@ export class CalendarDateTime {
|
|
|
218
255
|
/** The millisecond in the second. */
|
|
219
256
|
public readonly millisecond: number;
|
|
220
257
|
|
|
221
|
-
constructor(
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
258
|
+
constructor(
|
|
259
|
+
year: number,
|
|
260
|
+
month: number,
|
|
261
|
+
day: number,
|
|
262
|
+
hour?: number,
|
|
263
|
+
minute?: number,
|
|
264
|
+
second?: number,
|
|
265
|
+
millisecond?: number
|
|
266
|
+
);
|
|
267
|
+
constructor(
|
|
268
|
+
era: string,
|
|
269
|
+
year: number,
|
|
270
|
+
month: number,
|
|
271
|
+
day: number,
|
|
272
|
+
hour?: number,
|
|
273
|
+
minute?: number,
|
|
274
|
+
second?: number,
|
|
275
|
+
millisecond?: number
|
|
276
|
+
);
|
|
277
|
+
constructor(
|
|
278
|
+
calendar: Calendar,
|
|
279
|
+
year: number,
|
|
280
|
+
month: number,
|
|
281
|
+
day: number,
|
|
282
|
+
hour?: number,
|
|
283
|
+
minute?: number,
|
|
284
|
+
second?: number,
|
|
285
|
+
millisecond?: number
|
|
286
|
+
);
|
|
287
|
+
constructor(
|
|
288
|
+
calendar: Calendar,
|
|
289
|
+
era: string,
|
|
290
|
+
year: number,
|
|
291
|
+
month: number,
|
|
292
|
+
day: number,
|
|
293
|
+
hour?: number,
|
|
294
|
+
minute?: number,
|
|
295
|
+
second?: number,
|
|
296
|
+
millisecond?: number
|
|
297
|
+
);
|
|
225
298
|
constructor(...args: any[]) {
|
|
226
299
|
let [calendar, era, year, month, day] = shiftArgs(args);
|
|
227
300
|
this.calendar = calendar;
|
|
@@ -240,9 +313,28 @@ export class CalendarDateTime {
|
|
|
240
313
|
/** Returns a copy of this date. */
|
|
241
314
|
copy(): CalendarDateTime {
|
|
242
315
|
if (this.era) {
|
|
243
|
-
return new CalendarDateTime(
|
|
316
|
+
return new CalendarDateTime(
|
|
317
|
+
this.calendar,
|
|
318
|
+
this.era,
|
|
319
|
+
this.year,
|
|
320
|
+
this.month,
|
|
321
|
+
this.day,
|
|
322
|
+
this.hour,
|
|
323
|
+
this.minute,
|
|
324
|
+
this.second,
|
|
325
|
+
this.millisecond
|
|
326
|
+
);
|
|
244
327
|
} else {
|
|
245
|
-
return new CalendarDateTime(
|
|
328
|
+
return new CalendarDateTime(
|
|
329
|
+
this.calendar,
|
|
330
|
+
this.year,
|
|
331
|
+
this.month,
|
|
332
|
+
this.day,
|
|
333
|
+
this.hour,
|
|
334
|
+
this.minute,
|
|
335
|
+
this.second,
|
|
336
|
+
this.millisecond
|
|
337
|
+
);
|
|
246
338
|
}
|
|
247
339
|
}
|
|
248
340
|
|
|
@@ -256,7 +348,10 @@ export class CalendarDateTime {
|
|
|
256
348
|
return subtract(this, duration);
|
|
257
349
|
}
|
|
258
350
|
|
|
259
|
-
/**
|
|
351
|
+
/**
|
|
352
|
+
* Returns a new `CalendarDateTime` with the given fields set to the provided values. Other fields
|
|
353
|
+
* will be constrained accordingly.
|
|
354
|
+
*/
|
|
260
355
|
set(fields: DateFields & TimeFields): CalendarDateTime {
|
|
261
356
|
return set(setTime(this, fields), fields);
|
|
262
357
|
}
|
|
@@ -265,7 +360,11 @@ export class CalendarDateTime {
|
|
|
265
360
|
* Returns a new `CalendarDateTime` with the given field adjusted by a specified amount.
|
|
266
361
|
* When the resulting value reaches the limits of the field, it wraps around.
|
|
267
362
|
*/
|
|
268
|
-
cycle(
|
|
363
|
+
cycle(
|
|
364
|
+
field: DateField | TimeField,
|
|
365
|
+
amount: number,
|
|
366
|
+
options?: CycleTimeOptions
|
|
367
|
+
): CalendarDateTime {
|
|
269
368
|
switch (field) {
|
|
270
369
|
case 'era':
|
|
271
370
|
case 'year':
|
|
@@ -287,7 +386,10 @@ export class CalendarDateTime {
|
|
|
287
386
|
return dateTimeToString(this);
|
|
288
387
|
}
|
|
289
388
|
|
|
290
|
-
/**
|
|
389
|
+
/**
|
|
390
|
+
* Compares this date with another. A negative result indicates that this date is before the given
|
|
391
|
+
* one, and a positive date indicates that it is after.
|
|
392
|
+
*/
|
|
291
393
|
compare(b: CalendarDate | CalendarDateTime | ZonedDateTime): number {
|
|
292
394
|
let res = compareDate(this, b);
|
|
293
395
|
if (res === 0) {
|
|
@@ -330,10 +432,54 @@ export class ZonedDateTime {
|
|
|
330
432
|
/** The UTC offset for this time, in milliseconds. */
|
|
331
433
|
public readonly offset: number;
|
|
332
434
|
|
|
333
|
-
constructor(
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
435
|
+
constructor(
|
|
436
|
+
year: number,
|
|
437
|
+
month: number,
|
|
438
|
+
day: number,
|
|
439
|
+
timeZone: string,
|
|
440
|
+
offset: number,
|
|
441
|
+
hour?: number,
|
|
442
|
+
minute?: number,
|
|
443
|
+
second?: number,
|
|
444
|
+
millisecond?: number
|
|
445
|
+
);
|
|
446
|
+
constructor(
|
|
447
|
+
era: string,
|
|
448
|
+
year: number,
|
|
449
|
+
month: number,
|
|
450
|
+
day: number,
|
|
451
|
+
timeZone: string,
|
|
452
|
+
offset: number,
|
|
453
|
+
hour?: number,
|
|
454
|
+
minute?: number,
|
|
455
|
+
second?: number,
|
|
456
|
+
millisecond?: number
|
|
457
|
+
);
|
|
458
|
+
constructor(
|
|
459
|
+
calendar: Calendar,
|
|
460
|
+
year: number,
|
|
461
|
+
month: number,
|
|
462
|
+
day: number,
|
|
463
|
+
timeZone: string,
|
|
464
|
+
offset: number,
|
|
465
|
+
hour?: number,
|
|
466
|
+
minute?: number,
|
|
467
|
+
second?: number,
|
|
468
|
+
millisecond?: number
|
|
469
|
+
);
|
|
470
|
+
constructor(
|
|
471
|
+
calendar: Calendar,
|
|
472
|
+
era: string,
|
|
473
|
+
year: number,
|
|
474
|
+
month: number,
|
|
475
|
+
day: number,
|
|
476
|
+
timeZone: string,
|
|
477
|
+
offset: number,
|
|
478
|
+
hour?: number,
|
|
479
|
+
minute?: number,
|
|
480
|
+
second?: number,
|
|
481
|
+
millisecond?: number
|
|
482
|
+
);
|
|
337
483
|
constructor(...args: any[]) {
|
|
338
484
|
let [calendar, era, year, month, day] = shiftArgs(args);
|
|
339
485
|
let timeZone = args.shift();
|
|
@@ -356,9 +502,32 @@ export class ZonedDateTime {
|
|
|
356
502
|
/** Returns a copy of this date. */
|
|
357
503
|
copy(): ZonedDateTime {
|
|
358
504
|
if (this.era) {
|
|
359
|
-
return new ZonedDateTime(
|
|
505
|
+
return new ZonedDateTime(
|
|
506
|
+
this.calendar,
|
|
507
|
+
this.era,
|
|
508
|
+
this.year,
|
|
509
|
+
this.month,
|
|
510
|
+
this.day,
|
|
511
|
+
this.timeZone,
|
|
512
|
+
this.offset,
|
|
513
|
+
this.hour,
|
|
514
|
+
this.minute,
|
|
515
|
+
this.second,
|
|
516
|
+
this.millisecond
|
|
517
|
+
);
|
|
360
518
|
} else {
|
|
361
|
-
return new ZonedDateTime(
|
|
519
|
+
return new ZonedDateTime(
|
|
520
|
+
this.calendar,
|
|
521
|
+
this.year,
|
|
522
|
+
this.month,
|
|
523
|
+
this.day,
|
|
524
|
+
this.timeZone,
|
|
525
|
+
this.offset,
|
|
526
|
+
this.hour,
|
|
527
|
+
this.minute,
|
|
528
|
+
this.second,
|
|
529
|
+
this.millisecond
|
|
530
|
+
);
|
|
362
531
|
}
|
|
363
532
|
}
|
|
364
533
|
|
|
@@ -372,7 +541,10 @@ export class ZonedDateTime {
|
|
|
372
541
|
return subtractZoned(this, duration);
|
|
373
542
|
}
|
|
374
543
|
|
|
375
|
-
/**
|
|
544
|
+
/**
|
|
545
|
+
* Returns a new `ZonedDateTime` with the given fields set to the provided values. Other fields
|
|
546
|
+
* will be constrained accordingly.
|
|
547
|
+
*/
|
|
376
548
|
set(fields: DateFields & TimeFields, disambiguation?: Disambiguation): ZonedDateTime {
|
|
377
549
|
return setZoned(this, fields, disambiguation);
|
|
378
550
|
}
|
|
@@ -390,17 +562,23 @@ export class ZonedDateTime {
|
|
|
390
562
|
return zonedToDate(this);
|
|
391
563
|
}
|
|
392
564
|
|
|
393
|
-
|
|
565
|
+
/**
|
|
566
|
+
* Converts the date to an ISO 8601 formatted string, including the UTC offset and time zone
|
|
567
|
+
* identifier.
|
|
568
|
+
*/
|
|
394
569
|
toString(): string {
|
|
395
570
|
return zonedDateTimeToString(this);
|
|
396
571
|
}
|
|
397
572
|
|
|
398
|
-
|
|
573
|
+
/** Converts the date to an ISO 8601 formatted string in UTC. */
|
|
399
574
|
toAbsoluteString(): string {
|
|
400
575
|
return this.toDate().toISOString();
|
|
401
576
|
}
|
|
402
577
|
|
|
403
|
-
/**
|
|
578
|
+
/**
|
|
579
|
+
* Compares this date with another. A negative result indicates that this date is before the given
|
|
580
|
+
* one, and a positive date indicates that it is after.
|
|
581
|
+
*/
|
|
404
582
|
compare(b: CalendarDate | CalendarDateTime | ZonedDateTime): number {
|
|
405
583
|
// TODO: Is this a bad idea??
|
|
406
584
|
return this.toDate().getTime() - toZoned(b, this.timeZone).toDate().getTime();
|
package/src/DateFormatter.ts
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
let formatterCache = new Map<string, Intl.DateTimeFormat>();
|
|
14
14
|
|
|
15
15
|
interface DateRangeFormatPart extends Intl.DateTimeFormatPart {
|
|
16
|
-
source: 'startRange' | 'endRange' | 'shared'
|
|
16
|
+
source: 'startRange' | 'endRange' | 'shared';
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/** A wrapper around Intl.DateTimeFormat that fixes various browser bugs, and polyfills new features. */
|
|
@@ -27,7 +27,10 @@ export class DateFormatter implements Intl.DateTimeFormat {
|
|
|
27
27
|
this.options = options;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
/**
|
|
30
|
+
/**
|
|
31
|
+
* Formats a date as a string according to the locale and format options passed to the
|
|
32
|
+
* constructor.
|
|
33
|
+
*/
|
|
31
34
|
format(value: Date): string {
|
|
32
35
|
return this.formatter.format(value);
|
|
33
36
|
}
|
|
@@ -68,9 +71,9 @@ export class DateFormatter implements Intl.DateTimeFormat {
|
|
|
68
71
|
let startParts = this.formatter.formatToParts(start);
|
|
69
72
|
let endParts = this.formatter.formatToParts(end);
|
|
70
73
|
return [
|
|
71
|
-
...startParts.map(p => ({...p, source: 'startRange'} as DateRangeFormatPart)
|
|
74
|
+
...startParts.map(p => ({...p, source: 'startRange'}) as DateRangeFormatPart),
|
|
72
75
|
{type: 'literal', value: ' – ', source: 'shared'},
|
|
73
|
-
...endParts.map(p => ({...p, source: 'endRange'} as DateRangeFormatPart)
|
|
76
|
+
...endParts.map(p => ({...p, source: 'endRange'}) as DateRangeFormatPart)
|
|
74
77
|
];
|
|
75
78
|
}
|
|
76
79
|
|
|
@@ -116,7 +119,10 @@ const hour12Preferences = {
|
|
|
116
119
|
}
|
|
117
120
|
};
|
|
118
121
|
|
|
119
|
-
function getCachedDateFormatter(
|
|
122
|
+
function getCachedDateFormatter(
|
|
123
|
+
locale: string,
|
|
124
|
+
options: Intl.DateTimeFormatOptions = {}
|
|
125
|
+
): Intl.DateTimeFormat {
|
|
120
126
|
// Work around buggy hour12 behavior in Chrome / ECMA 402 spec by using hourCycle instead.
|
|
121
127
|
// Only apply the workaround if the issue is detected, because the hourCycle option is buggy in Safari.
|
|
122
128
|
if (typeof options.hour12 === 'boolean' && hasBuggyHour12Behavior()) {
|
|
@@ -127,7 +133,13 @@ function getCachedDateFormatter(locale: string, options: Intl.DateTimeFormatOpti
|
|
|
127
133
|
delete options.hour12;
|
|
128
134
|
}
|
|
129
135
|
|
|
130
|
-
let cacheKey =
|
|
136
|
+
let cacheKey =
|
|
137
|
+
locale +
|
|
138
|
+
(options
|
|
139
|
+
? Object.entries(options)
|
|
140
|
+
.sort((a, b) => (a[0] < b[0] ? -1 : 1))
|
|
141
|
+
.join()
|
|
142
|
+
: '');
|
|
131
143
|
if (formatterCache.has(cacheKey)) {
|
|
132
144
|
return formatterCache.get(cacheKey)!;
|
|
133
145
|
}
|
|
@@ -140,10 +152,11 @@ function getCachedDateFormatter(locale: string, options: Intl.DateTimeFormatOpti
|
|
|
140
152
|
let _hasBuggyHour12Behavior: boolean | null = null;
|
|
141
153
|
function hasBuggyHour12Behavior() {
|
|
142
154
|
if (_hasBuggyHour12Behavior == null) {
|
|
143
|
-
_hasBuggyHour12Behavior =
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
155
|
+
_hasBuggyHour12Behavior =
|
|
156
|
+
new Intl.DateTimeFormat('en-US', {
|
|
157
|
+
hour: 'numeric',
|
|
158
|
+
hour12: false
|
|
159
|
+
}).format(new Date(2020, 2, 3, 0)) === '24';
|
|
147
160
|
}
|
|
148
161
|
|
|
149
162
|
return _hasBuggyHour12Behavior;
|
|
@@ -152,10 +165,11 @@ function hasBuggyHour12Behavior() {
|
|
|
152
165
|
let _hasBuggyResolvedHourCycle: boolean | null = null;
|
|
153
166
|
function hasBuggyResolvedHourCycle() {
|
|
154
167
|
if (_hasBuggyResolvedHourCycle == null) {
|
|
155
|
-
_hasBuggyResolvedHourCycle =
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
168
|
+
_hasBuggyResolvedHourCycle =
|
|
169
|
+
new Intl.DateTimeFormat('fr', {
|
|
170
|
+
hour: 'numeric',
|
|
171
|
+
hour12: false
|
|
172
|
+
}).resolvedOptions().hourCycle === 'h12';
|
|
159
173
|
}
|
|
160
174
|
|
|
161
175
|
return _hasBuggyResolvedHourCycle;
|
|
@@ -175,8 +189,14 @@ function getResolvedHourCycle(locale: string, options: Intl.DateTimeFormatOption
|
|
|
175
189
|
timeZone: undefined // use local timezone
|
|
176
190
|
});
|
|
177
191
|
|
|
178
|
-
let min = parseInt(
|
|
179
|
-
|
|
192
|
+
let min = parseInt(
|
|
193
|
+
formatter.formatToParts(new Date(2020, 2, 3, 0)).find(p => p.type === 'hour')!.value,
|
|
194
|
+
10
|
|
195
|
+
);
|
|
196
|
+
let max = parseInt(
|
|
197
|
+
formatter.formatToParts(new Date(2020, 2, 3, 23)).find(p => p.type === 'hour')!.value,
|
|
198
|
+
10
|
|
199
|
+
);
|
|
180
200
|
|
|
181
201
|
if (min === 0 && max === 23) {
|
|
182
202
|
return 'h23';
|
|
@@ -55,10 +55,5 @@ export class BuddhistCalendar extends GregorianCalendar {
|
|
|
55
55
|
|
|
56
56
|
function toGregorian(date: AnyCalendarDate) {
|
|
57
57
|
let [era, year] = fromExtendedYear(date.year + BUDDHIST_ERA_START);
|
|
58
|
-
return new CalendarDate(
|
|
59
|
-
era,
|
|
60
|
-
year,
|
|
61
|
-
date.month,
|
|
62
|
-
date.day
|
|
63
|
-
);
|
|
58
|
+
return new CalendarDate(era, year, date.month, date.day);
|
|
64
59
|
}
|
|
@@ -26,11 +26,12 @@ const AMETE_MIHRET_DELTA = 5500;
|
|
|
26
26
|
|
|
27
27
|
function ceToJulianDay(epoch: number, year: number, month: number, day: number): number {
|
|
28
28
|
return (
|
|
29
|
-
epoch
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
epoch + // difference from Julian epoch to 1,1,1
|
|
30
|
+
365 * year + // number of days from years
|
|
31
|
+
Math.floor(year / 4) + // extra day of leap year
|
|
32
|
+
30 * (month - 1) + // number of days from months (1 based)
|
|
33
|
+
day -
|
|
34
|
+
1 // number of days for present month (1 based)
|
|
34
35
|
);
|
|
35
36
|
}
|
|
36
37
|
|
|
@@ -18,7 +18,12 @@ import {CalendarDate} from '../CalendarDate';
|
|
|
18
18
|
import {mod, Mutable} from '../utils';
|
|
19
19
|
|
|
20
20
|
const EPOCH = 1721426; // 001/01/03 Julian C.E.
|
|
21
|
-
export function gregorianToJulianDay(
|
|
21
|
+
export function gregorianToJulianDay(
|
|
22
|
+
era: string,
|
|
23
|
+
year: number,
|
|
24
|
+
month: number,
|
|
25
|
+
day: number
|
|
26
|
+
): number {
|
|
22
27
|
year = getExtendedYear(era, year);
|
|
23
28
|
|
|
24
29
|
let y1 = year - 1;
|
|
@@ -64,8 +69,9 @@ const daysInMonth = {
|
|
|
64
69
|
};
|
|
65
70
|
|
|
66
71
|
/**
|
|
67
|
-
* The Gregorian calendar is the most commonly used calendar system in the world. It supports two
|
|
68
|
-
* Years always contain 12 months, and 365 or 366 days depending on whether it is
|
|
72
|
+
* The Gregorian calendar is the most commonly used calendar system in the world. It supports two
|
|
73
|
+
* eras: BC, and AD. Years always contain 12 months, and 365 or 366 days depending on whether it is
|
|
74
|
+
* a leap year.
|
|
69
75
|
*/
|
|
70
76
|
export class GregorianCalendar implements Calendar {
|
|
71
77
|
identifier: CalendarIdentifier = 'gregory';
|
|
@@ -81,7 +87,8 @@ export class GregorianCalendar implements Calendar {
|
|
|
81
87
|
let dquad = mod(dcent, 1461);
|
|
82
88
|
let yindex = Math.floor(dquad / 365);
|
|
83
89
|
|
|
84
|
-
let extendedYear =
|
|
90
|
+
let extendedYear =
|
|
91
|
+
quadricent * 400 + cent * 100 + quad * 4 + yindex + (cent !== 4 && yindex !== 4 ? 1 : 0);
|
|
85
92
|
let [era, year] = fromExtendedYear(extendedYear);
|
|
86
93
|
let yearDay = jd0 - gregorianToJulianDay(era, year, 1, 1);
|
|
87
94
|
let leapAdj = 2;
|
|
@@ -22,7 +22,7 @@ const HEBREW_EPOCH = 347997;
|
|
|
22
22
|
// Hebrew date calculations are performed in terms of days, hours, and
|
|
23
23
|
// "parts" (or halakim), which are 1/1080 of an hour, or 3 1/3 seconds.
|
|
24
24
|
const HOUR_PARTS = 1080;
|
|
25
|
-
const DAY_PARTS
|
|
25
|
+
const DAY_PARTS = 24 * HOUR_PARTS;
|
|
26
26
|
|
|
27
27
|
// An approximate value for the length of a lunar month.
|
|
28
28
|
// It is used to calculate the approximate year and month of a given
|
|
@@ -132,9 +132,9 @@ export class HebrewCalendar implements Calendar {
|
|
|
132
132
|
|
|
133
133
|
fromJulianDay(jd: number): CalendarDate {
|
|
134
134
|
let d = jd - HEBREW_EPOCH;
|
|
135
|
-
let m = (d * DAY_PARTS) / MONTH_PARTS;
|
|
135
|
+
let m = (d * DAY_PARTS) / MONTH_PARTS; // Months (approx)
|
|
136
136
|
let year = Math.floor((19 * m + 234) / 235) + 1; // Years (approx)
|
|
137
|
-
let ys = startOfYear(year);
|
|
137
|
+
let ys = startOfYear(year); // 1st day of year
|
|
138
138
|
let dayOfYear = Math.floor(d - ys);
|
|
139
139
|
|
|
140
140
|
// Because of the postponement rules, it's possible to guess wrong. Fix it.
|
|
@@ -202,7 +202,11 @@ export class HebrewCalendar implements Calendar {
|
|
|
202
202
|
if (previousDate.year !== date.year) {
|
|
203
203
|
if (isLeapYear(previousDate.year) && !isLeapYear(date.year) && previousDate.month > 6) {
|
|
204
204
|
date.month--;
|
|
205
|
-
} else if (
|
|
205
|
+
} else if (
|
|
206
|
+
!isLeapYear(previousDate.year) &&
|
|
207
|
+
isLeapYear(date.year) &&
|
|
208
|
+
previousDate.month > 6
|
|
209
|
+
) {
|
|
206
210
|
date.month++;
|
|
207
211
|
}
|
|
208
212
|
}
|
|
@@ -15,7 +15,12 @@
|
|
|
15
15
|
|
|
16
16
|
import {AnyCalendarDate, CalendarIdentifier} from '../types';
|
|
17
17
|
import {CalendarDate} from '../CalendarDate';
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
fromExtendedYear,
|
|
20
|
+
GregorianCalendar,
|
|
21
|
+
gregorianToJulianDay,
|
|
22
|
+
isLeapYear
|
|
23
|
+
} from './GregorianCalendar';
|
|
19
24
|
|
|
20
25
|
// Starts in 78 AD,
|
|
21
26
|
const INDIAN_ERA_START = 78;
|
|
@@ -48,7 +53,7 @@ export class IndianCalendar extends GregorianCalendar {
|
|
|
48
53
|
|
|
49
54
|
// Days in leapMonth this year, previous Gregorian year
|
|
50
55
|
leapMonth = isLeapYear(date.year - 1) ? 31 : 30;
|
|
51
|
-
yDay += leapMonth +
|
|
56
|
+
yDay += leapMonth + 31 * 5 + 30 * 3 + 10;
|
|
52
57
|
} else {
|
|
53
58
|
// Days in leapMonth this year
|
|
54
59
|
leapMonth = isLeapYear(date.year) ? 31 : 30;
|
|
@@ -62,7 +67,7 @@ export class IndianCalendar extends GregorianCalendar {
|
|
|
62
67
|
indianDay = yDay + 1;
|
|
63
68
|
} else {
|
|
64
69
|
let mDay = yDay - leapMonth;
|
|
65
|
-
if (mDay <
|
|
70
|
+
if (mDay < 31 * 5) {
|
|
66
71
|
indianMonth = Math.floor(mDay / 31) + 2;
|
|
67
72
|
indianDay = (mDay % 31) + 1;
|
|
68
73
|
} else {
|