From 93c64e244baf54b5cfbe9aece22fee473071bd8c Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Fri, 14 Aug 2020 18:44:50 -0700 Subject: [PATCH] Allow unicode minus sign (U+2212) in negative durations as well See: #814 --- polyfill/lib/ecmascript.mjs | 2 +- polyfill/lib/regex.mjs | 2 +- polyfill/test/duration.mjs | 4 ++++ polyfill/test/validStrings.mjs | 2 +- spec/abstractops.html | 2 +- 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/polyfill/lib/ecmascript.mjs b/polyfill/lib/ecmascript.mjs index 820d113bd2..289a11cc5a 100644 --- a/polyfill/lib/ecmascript.mjs +++ b/polyfill/lib/ecmascript.mjs @@ -213,7 +213,7 @@ export const ES = ObjectAssign({}, ES2019, { if (match.slice(2).every((element) => element === undefined)) { throw new RangeError(`invalid duration: ${isoString}`); } - const sign = match[1] === '-' ? -1 : 1; + const sign = match[1] === '-' || match[1] === '\u2212' ? -1 : 1; const years = ES.ToInteger(match[2]) * sign; const months = ES.ToInteger(match[3]) * sign; const weeks = ES.ToInteger(match[4]) * sign; diff --git a/polyfill/lib/regex.mjs b/polyfill/lib/regex.mjs index 82f6365224..b7c13c11b1 100644 --- a/polyfill/lib/regex.mjs +++ b/polyfill/lib/regex.mjs @@ -24,4 +24,4 @@ export const time = new RegExp(`^${timesplit.source}(?:${zonesplit.source})?(?:$ export const yearmonth = new RegExp(`^(${yearpart.source})-?(\\d{2})$`); export const monthday = /^(?:--)?(\d{2})-?(\d{2})$/; -export const duration = /^([+-])?P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)W)?(?:(\d+)D)?(?:T(?!$)(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)(?:[.,](\d{1,9}))?S)?)?$/i; +export const duration = /^([+-\u2212])?P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)W)?(?:(\d+)D)?(?:T(?!$)(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)(?:[.,](\d{1,9}))?S)?)?$/i; diff --git a/polyfill/test/duration.mjs b/polyfill/test/duration.mjs index 209eb7cf7c..514c57bf99 100644 --- a/polyfill/test/duration.mjs +++ b/polyfill/test/duration.mjs @@ -146,6 +146,10 @@ describe('Duration', () => { const d = Duration.from('-P1D'); equal(d.days, -1); }); + it('variant minus sign', () => { + const d = Duration.from('\u2212P1D'); + equal(d.days, -1); + }); it('all units have the same sign', () => { const d = Duration.from('-P1Y1M1W1DT1H1M1.123456789S'); equal(d.years, -1); diff --git a/polyfill/test/validStrings.mjs b/polyfill/test/validStrings.mjs index 8499f3a59d..d7557c8485 100644 --- a/polyfill/test/validStrings.mjs +++ b/polyfill/test/validStrings.mjs @@ -275,7 +275,7 @@ const durationYears = seq( ); const durationDate = seq(choice(durationYears, durationMonths, durationWeeks, durationDays), [durationTime]); const duration = seq( - withCode([sign], (data, result) => (data.factor = result === '-' ? -1 : 1)), + withCode([sign], (data, result) => (data.factor = result === '-' || result === '\u2212' ? -1 : 1)), durationDesignator, choice(durationDate, durationTime) ); diff --git a/spec/abstractops.html b/spec/abstractops.html index 9d5fabd37f..2644049f2c 100644 --- a/spec/abstractops.html +++ b/spec/abstractops.html @@ -561,7 +561,7 @@

ParseTemporalDurationString ( _isoString_ )

1. If _isoString_ does not satisfy the syntax of a |TemporalDurationString| (see ), then 1. Throw a *RangeError* exception. 1. Let _sign_, _years_, _months_, _weeks_, _days_, _hours_, _minutes_, _seconds_, and _fraction_ be the parts of _isoString_ produced respectively by the |Sign|, |DurationYears|, |DurationMonths|, |DurationWeeks|, |DurationDays|, |DurationHours|, |DurationMinutes|, |DurationSeconds|, and |TimeFractionalPart| productions, or *undefined* if not present. - 1. If _sign_ is *"-"*, then + 1. If _sign_ is the code unit 0x002D (HYPHEN-MINUS) or 0x2212 (MINUS SIGN), then 1. Let _factor_ be −1;. 1. Else, 1. Let _factor_ be 1.