@@ -21,7 +21,8 @@ const TIME = Symbol('time');
2121const DATETIME = Symbol ( 'datetime' ) ;
2222const INST = Symbol ( 'instant' ) ;
2323const ORIGINAL = Symbol ( 'original' ) ;
24- const TZ_RESOLVED = Symbol ( 'timezone' ) ;
24+ const TZ_CANONICAL = Symbol ( 'timezone-canonical' ) ;
25+ const TZ_ORIGINAL = Symbol ( 'timezone-original' ) ;
2526const CAL_ID = Symbol ( 'calendar-id' ) ;
2627const LOCALE = Symbol ( 'locale' ) ;
2728const OPTIONS = Symbol ( 'options' ) ;
@@ -81,14 +82,33 @@ export function DateTimeFormat(locale = undefined, options = undefined) {
8182
8283 this [ LOCALE ] = ro . locale ;
8384 this [ ORIGINAL ] = original ;
84- this [ TZ_RESOLVED ] = ro . timeZone ;
85+ this [ TZ_CANONICAL ] = ro . timeZone ;
8586 this [ CAL_ID ] = ro . calendar ;
8687 this [ DATE ] = dateAmend ;
8788 this [ YM ] = yearMonthAmend ;
8889 this [ MD ] = monthDayAmend ;
8990 this [ TIME ] = timeAmend ;
9091 this [ DATETIME ] = datetimeAmend ;
9192 this [ INST ] = instantAmend ;
93+
94+ // Save the original time zone, for a few reasons:
95+ // - Clearer error messages
96+ // - More clearly follows the spec for InitializeDateTimeFormat
97+ // - Because it follows the spec more closely, will make it easier to integrate
98+ // support of offset strings and other potential changes like proposal-canonical-tz.
99+ const timeZoneOption = hasOptions ? options . timeZone : undefined ;
100+ if ( timeZoneOption === undefined ) {
101+ this [ TZ_ORIGINAL ] = ro . timeZone ;
102+ } else {
103+ const id = ES . ToString ( timeZoneOption ) ;
104+ if ( ES . IsTimeZoneOffsetString ( id ) ) {
105+ // Note: https://github.com/tc39/ecma402/issues/683 will remove this
106+ throw new RangeError ( 'Intl.DateTimeFormat does not currently support offset time zones' ) ;
107+ }
108+ const record = ES . GetAvailableNamedTimeZoneIdentifier ( id ) ;
109+ if ( ! record ) throw new RangeError ( `Intl.DateTimeFormat formats built-in time zones, not ${ id } ` ) ;
110+ this [ TZ_ORIGINAL ] = record . primaryIdentifier ;
111+ }
92112}
93113
94114DateTimeFormat . supportedLocalesOf = function ( ...args ) {
@@ -118,7 +138,9 @@ Object.defineProperty(DateTimeFormat, 'prototype', {
118138} ) ;
119139
120140function resolvedOptions ( ) {
121- return this [ ORIGINAL ] . resolvedOptions ( ) ;
141+ const resolved = this [ ORIGINAL ] . resolvedOptions ( ) ;
142+ resolved . timeZone = this [ TZ_ORIGINAL ] ;
143+ return resolved ;
122144}
123145
124146function format ( datetime , ...rest ) {
@@ -335,7 +357,7 @@ function extractOverrides(temporalObj, main) {
335357 const nanosecond = GetSlot ( temporalObj , ISO_NANOSECOND ) ;
336358 const datetime = new DateTime ( 1970 , 1 , 1 , hour , minute , second , millisecond , microsecond , nanosecond , main [ CAL_ID ] ) ;
337359 return {
338- instant : ES . GetInstantFor ( main [ TZ_RESOLVED ] , datetime , 'compatible' ) ,
360+ instant : ES . GetInstantFor ( main [ TZ_CANONICAL ] , datetime , 'compatible' ) ,
339361 formatter : getPropLazy ( main , TIME )
340362 } ;
341363 }
@@ -352,7 +374,7 @@ function extractOverrides(temporalObj, main) {
352374 }
353375 const datetime = new DateTime ( isoYear , isoMonth , referenceISODay , 12 , 0 , 0 , 0 , 0 , 0 , calendar ) ;
354376 return {
355- instant : ES . GetInstantFor ( main [ TZ_RESOLVED ] , datetime , 'compatible' ) ,
377+ instant : ES . GetInstantFor ( main [ TZ_CANONICAL ] , datetime , 'compatible' ) ,
356378 formatter : getPropLazy ( main , YM )
357379 } ;
358380 }
@@ -369,7 +391,7 @@ function extractOverrides(temporalObj, main) {
369391 }
370392 const datetime = new DateTime ( referenceISOYear , isoMonth , isoDay , 12 , 0 , 0 , 0 , 0 , 0 , calendar ) ;
371393 return {
372- instant : ES . GetInstantFor ( main [ TZ_RESOLVED ] , datetime , 'compatible' ) ,
394+ instant : ES . GetInstantFor ( main [ TZ_CANONICAL ] , datetime , 'compatible' ) ,
373395 formatter : getPropLazy ( main , MD )
374396 } ;
375397 }
@@ -384,7 +406,7 @@ function extractOverrides(temporalObj, main) {
384406 }
385407 const datetime = new DateTime ( isoYear , isoMonth , isoDay , 12 , 0 , 0 , 0 , 0 , 0 , main [ CAL_ID ] ) ;
386408 return {
387- instant : ES . GetInstantFor ( main [ TZ_RESOLVED ] , datetime , 'compatible' ) ,
409+ instant : ES . GetInstantFor ( main [ TZ_CANONICAL ] , datetime , 'compatible' ) ,
388410 formatter : getPropLazy ( main , DATE )
389411 } ;
390412 }
@@ -421,7 +443,7 @@ function extractOverrides(temporalObj, main) {
421443 ) ;
422444 }
423445 return {
424- instant : ES . GetInstantFor ( main [ TZ_RESOLVED ] , datetime , 'compatible' ) ,
446+ instant : ES . GetInstantFor ( main [ TZ_CANONICAL ] , datetime , 'compatible' ) ,
425447 formatter : getPropLazy ( main , DATETIME )
426448 } ;
427449 }
0 commit comments