@@ -28,6 +28,8 @@ const ORIGINAL = Symbol('original');
28
28
const TZ_RESOLVED = Symbol ( 'timezone' ) ;
29
29
const TZ_GIVEN = Symbol ( 'timezone-id-given' ) ;
30
30
const CAL_ID = Symbol ( 'calendar-id' ) ;
31
+ const LOCALE = Symbol ( 'locale' ) ;
32
+ const OPTIONS = Symbol ( 'options' ) ;
31
33
32
34
const descriptor = ( value ) => {
33
35
return {
@@ -41,21 +43,44 @@ const descriptor = (value) => {
41
43
const IntlDateTimeFormat = globalThis . Intl . DateTimeFormat ;
42
44
const ObjectAssign = Object . assign ;
43
45
44
- export function DateTimeFormat ( locale = IntlDateTimeFormat ( ) . resolvedOptions ( ) . locale , options = { } ) {
46
+ // Construction of built-in Intl.DateTimeFormat objects is sloooooow,
47
+ // so we'll only create those instances when we need them.
48
+ // See https://bugs.chromium.org/p/v8/issues/detail?id=6528
49
+ function getPropLazy ( obj , prop ) {
50
+ let val = obj [ prop ] ;
51
+ if ( prop === TZ_RESOLVED ) {
52
+ // for TimeZone, the initializer is a string, not a function
53
+ if ( typeof val === 'string' ) {
54
+ val = new TimeZone ( val ) ;
55
+ obj [ prop ] = val ;
56
+ }
57
+ } else if ( typeof val === 'function' ) {
58
+ val = new IntlDateTimeFormat ( obj [ LOCALE ] , val ( obj [ OPTIONS ] ) ) ;
59
+ obj [ prop ] = val ;
60
+ }
61
+ return val ;
62
+ }
63
+
64
+ export function DateTimeFormat ( locale , options ) {
45
65
if ( ! ( this instanceof DateTimeFormat ) ) return new DateTimeFormat ( locale , options ) ;
66
+ const original = new IntlDateTimeFormat ( locale , options ) ;
67
+ const ro = original . resolvedOptions ( ) ;
68
+ options = typeof options === 'undefined' ? { } : ObjectAssign ( { } , options ) ;
46
69
47
70
this [ TZ_GIVEN ] = options . timeZone ? options . timeZone : null ;
48
-
49
- this [ ORIGINAL ] = new IntlDateTimeFormat ( locale , options ) ;
50
- this [ TZ_RESOLVED ] = new TimeZone ( this . resolvedOptions ( ) . timeZone ) ;
51
- this [ CAL_ID ] = this . resolvedOptions ( ) . calendar ;
52
- this [ DATE ] = new IntlDateTimeFormat ( locale , dateAmend ( options ) ) ;
53
- this [ YM ] = new IntlDateTimeFormat ( locale , yearMonthAmend ( options ) ) ;
54
- this [ MD ] = new IntlDateTimeFormat ( locale , monthDayAmend ( options ) ) ;
55
- this [ TIME ] = new IntlDateTimeFormat ( locale , timeAmend ( options ) ) ;
56
- this [ DATETIME ] = new IntlDateTimeFormat ( locale , datetimeAmend ( options ) ) ;
57
- this [ ZONED ] = new IntlDateTimeFormat ( locale , zonedDateTimeAmend ( options ) ) ;
58
- this [ INST ] = new IntlDateTimeFormat ( locale , instantAmend ( options ) ) ;
71
+ this [ OPTIONS ] = options ;
72
+ this [ LOCALE ] = typeof locale === 'undefined' ? ro . locale : locale ;
73
+
74
+ this [ ORIGINAL ] = original ;
75
+ this [ TZ_RESOLVED ] = ro . timeZone ;
76
+ this [ CAL_ID ] = ro . calendar ;
77
+ this [ DATE ] = dateAmend ;
78
+ this [ YM ] = yearMonthAmend ;
79
+ this [ MD ] = monthDayAmend ;
80
+ this [ TIME ] = timeAmend ;
81
+ this [ DATETIME ] = datetimeAmend ;
82
+ this [ ZONED ] = zonedDateTimeAmend ;
83
+ this [ INST ] = instantAmend ;
59
84
}
60
85
61
86
DateTimeFormat . supportedLocalesOf = function ( ...args ) {
@@ -85,6 +110,7 @@ function resolvedOptions() {
85
110
function adjustFormatterTimeZone ( formatter , timeZone ) {
86
111
if ( ! timeZone ) return formatter ;
87
112
const options = formatter . resolvedOptions ( ) ;
113
+ if ( options . timeZone === timeZone ) return formatter ;
88
114
return new IntlDateTimeFormat ( options . locale , { ...options , timeZone } ) ;
89
115
}
90
116
@@ -327,8 +353,8 @@ function extractOverrides(temporalObj, main) {
327
353
const nanosecond = GetSlot ( temporalObj , ISO_NANOSECOND ) ;
328
354
const datetime = new DateTime ( 1970 , 1 , 1 , hour , minute , second , millisecond , microsecond , nanosecond , main [ CAL_ID ] ) ;
329
355
return {
330
- instant : ES . BuiltinTimeZoneGetInstantFor ( main [ TZ_RESOLVED ] , datetime , 'compatible' ) ,
331
- formatter : main [ TIME ]
356
+ instant : ES . BuiltinTimeZoneGetInstantFor ( getPropLazy ( main , TZ_RESOLVED ) , datetime , 'compatible' ) ,
357
+ formatter : getPropLazy ( main , TIME )
332
358
} ;
333
359
}
334
360
@@ -344,8 +370,8 @@ function extractOverrides(temporalObj, main) {
344
370
}
345
371
const datetime = new DateTime ( isoYear , isoMonth , referenceISODay , 12 , 0 , 0 , 0 , 0 , 0 , calendar ) ;
346
372
return {
347
- instant : ES . BuiltinTimeZoneGetInstantFor ( main [ TZ_RESOLVED ] , datetime , 'compatible' ) ,
348
- formatter : main [ YM ]
373
+ instant : ES . BuiltinTimeZoneGetInstantFor ( getPropLazy ( main , TZ_RESOLVED ) , datetime , 'compatible' ) ,
374
+ formatter : getPropLazy ( main , YM )
349
375
} ;
350
376
}
351
377
@@ -361,8 +387,8 @@ function extractOverrides(temporalObj, main) {
361
387
}
362
388
const datetime = new DateTime ( referenceISOYear , isoMonth , isoDay , 12 , 0 , 0 , 0 , 0 , 0 , calendar ) ;
363
389
return {
364
- instant : ES . BuiltinTimeZoneGetInstantFor ( main [ TZ_RESOLVED ] , datetime , 'compatible' ) ,
365
- formatter : main [ MD ]
390
+ instant : ES . BuiltinTimeZoneGetInstantFor ( getPropLazy ( main , TZ_RESOLVED ) , datetime , 'compatible' ) ,
391
+ formatter : getPropLazy ( main , MD )
366
392
} ;
367
393
}
368
394
@@ -376,8 +402,8 @@ function extractOverrides(temporalObj, main) {
376
402
}
377
403
const datetime = new DateTime ( isoYear , isoMonth , isoDay , 12 , 0 , 0 , 0 , 0 , 0 , main [ CAL_ID ] ) ;
378
404
return {
379
- instant : ES . BuiltinTimeZoneGetInstantFor ( main [ TZ_RESOLVED ] , datetime , 'compatible' ) ,
380
- formatter : main [ DATE ]
405
+ instant : ES . BuiltinTimeZoneGetInstantFor ( getPropLazy ( main , TZ_RESOLVED ) , datetime , 'compatible' ) ,
406
+ formatter : getPropLazy ( main , DATE )
381
407
} ;
382
408
}
383
409
@@ -413,8 +439,8 @@ function extractOverrides(temporalObj, main) {
413
439
) ;
414
440
}
415
441
return {
416
- instant : ES . BuiltinTimeZoneGetInstantFor ( main [ TZ_RESOLVED ] , datetime , 'compatible' ) ,
417
- formatter : main [ DATETIME ]
442
+ instant : ES . BuiltinTimeZoneGetInstantFor ( getPropLazy ( main , TZ_RESOLVED ) , datetime , 'compatible' ) ,
443
+ formatter : getPropLazy ( main , DATETIME )
418
444
} ;
419
445
}
420
446
@@ -434,15 +460,15 @@ function extractOverrides(temporalObj, main) {
434
460
435
461
return {
436
462
instant : GetSlot ( temporalObj , INSTANT ) ,
437
- formatter : main [ ZONED ] ,
463
+ formatter : getPropLazy ( main , ZONED ) ,
438
464
timeZone : objTimeZone
439
465
} ;
440
466
}
441
467
442
468
if ( ES . IsTemporalInstant ( temporalObj ) ) {
443
469
return {
444
470
instant : temporalObj ,
445
- formatter : main [ INST ]
471
+ formatter : getPropLazy ( main , INST )
446
472
} ;
447
473
}
448
474
0 commit comments