@@ -6,6 +6,7 @@ import { CALENDAR_ID, ISO_YEAR, ISO_MONTH, ISO_DAY, CreateSlots, GetSlot, HasSlo
6
6
7
7
const ArrayIncludes = Array . prototype . includes ;
8
8
const ArrayPrototypePush = Array . prototype . push ;
9
+ const IntlDateTimeFormat = globalThis . Intl . DateTimeFormat ;
9
10
const MathAbs = Math . abs ;
10
11
const MathFloor = Math . floor ;
11
12
const ObjectAssign = Object . assign ;
@@ -430,19 +431,31 @@ function simpleDateDiff(one, two) {
430
431
*/
431
432
const nonIsoHelperBase = {
432
433
// The properties and methods below here should be the same for all lunar/lunisolar calendars.
434
+ getFormatter ( ) {
435
+ // `new Intl.DateTimeFormat()` is amazingly slow and chews up RAM. Per
436
+ // https://bugs.chromium.org/p/v8/issues/detail?id=6528#c4, we cache one
437
+ // DateTimeFormat instance per calendar. Caching is lazy so we only pay for
438
+ // calendars that are used. Note that the nonIsoHelperBase object is spread
439
+ // into each each calendar's implementation before any cache is created, so
440
+ // each calendar gets its own separate cached formatter.
441
+ if ( typeof this . formatter === 'undefined' ) {
442
+ this . formatter = new IntlDateTimeFormat ( `en-US-u-ca-${ this . id } ` , {
443
+ day : 'numeric' ,
444
+ month : 'numeric' ,
445
+ year : 'numeric' ,
446
+ era : this . eraLength ,
447
+ timeZone : 'UTC'
448
+ } ) ;
449
+ }
450
+ return this . formatter ;
451
+ } ,
433
452
isoToCalendarDate ( isoDate , cache ) {
434
453
let { year : isoYear , month : isoMonth , day : isoDay } = isoDate ;
435
454
const key = JSON . stringify ( { func : 'isoToCalendarDate' , isoYear, isoMonth, isoDay, id : this . id } ) ;
436
455
const cached = cache . get ( key ) ;
437
456
if ( cached ) return cached ;
438
457
439
- const dateTimeFormat = new Intl . DateTimeFormat ( `en-US-u-ca-${ this . id } ` , {
440
- day : 'numeric' ,
441
- month : 'numeric' ,
442
- year : 'numeric' ,
443
- era : this . eraLength ,
444
- timeZone : 'UTC'
445
- } ) ;
458
+ const dateTimeFormat = this . getFormatter ( ) ;
446
459
let parts , isoString ;
447
460
try {
448
461
isoString = toUtcIsoDateString ( { isoYear, isoMonth, isoDay } ) ;
@@ -1604,14 +1617,7 @@ const helperChinese = ObjectAssign({}, nonIsoHelperBase, {
1604
1617
const key = JSON . stringify ( { func : 'getMonthList' , calendarYear, id : this . id } ) ;
1605
1618
const cached = cache . get ( key ) ;
1606
1619
if ( cached ) return cached ;
1607
- const dateTimeFormat = new Intl . DateTimeFormat ( `en-US-u-ca-${ this . id } ` , {
1608
- day : 'numeric' ,
1609
- month : 'numeric' ,
1610
- year : 'numeric' ,
1611
- era : 'short' ,
1612
- timeZone : 'UTC'
1613
- } ) ;
1614
-
1620
+ const dateTimeFormat = this . getFormatter ( ) ;
1615
1621
const getCalendarDate = ( isoYear , daysPastFeb1 ) => {
1616
1622
const isoStringFeb1 = toUtcIsoDateString ( { isoYear, isoMonth : 2 , isoDay : 1 } ) ;
1617
1623
const legacyDate = new Date ( isoStringFeb1 ) ;
0 commit comments