@@ -11,6 +11,7 @@ const NumberIsNaN = Number.isNaN;
11
11
const NumberIsFinite = Number . isFinite ;
12
12
const NumberCtor = Number ;
13
13
const StringCtor = String ;
14
+ const StringPrototypeSlice = String . prototype . slice ;
14
15
const NumberMaxSafeInteger = Number . MAX_SAFE_INTEGER ;
15
16
const ObjectAssign = Object . assign ;
16
17
const ObjectCreate = Object . create ;
@@ -477,15 +478,19 @@ export function ParseTemporalTimeString(isoString: string) {
477
478
if ( / [ t T ] [ 0 - 9 ] [ 0 - 9 ] / . test ( isoString ) ) {
478
479
return { hour, minute, second, millisecond, microsecond, nanosecond, calendar } ;
479
480
}
480
- // slow but non-grammar-dependent way to ensure that time-only strings that
481
- // are also valid PlainMonthDay and PlainYearMonth throw. corresponds to
482
- // assertion in spec text
481
+ // Reject strings that are ambiguous with PlainMonthDay or PlainYearMonth.
482
+ // The calendar suffix is `[u-ca=${calendar}]`, i.e. calendar plus 7 characters,
483
+ // and must be stripped so presence of a calendar doesn't result in interpretation
484
+ // of otherwise ambiguous input as a time.
485
+ const isoStringWithoutCalendar = calendar
486
+ ? StringPrototypeSlice . call ( isoString , 0 , isoString . length - calendar . length - 7 )
487
+ : isoString ;
483
488
try {
484
- const { month, day } = ParseTemporalMonthDayString ( isoString ) ;
489
+ const { month, day } = ParseTemporalMonthDayString ( isoStringWithoutCalendar ) ;
485
490
RejectISODate ( 1972 , month , day ) ;
486
491
} catch {
487
492
try {
488
- const { year, month } = ParseTemporalYearMonthString ( isoString ) ;
493
+ const { year, month } = ParseTemporalYearMonthString ( isoStringWithoutCalendar ) ;
489
494
RejectISODate ( year , month , 1 ) ;
490
495
} catch {
491
496
return { hour, minute, second, millisecond, microsecond, nanosecond, calendar } ;
0 commit comments