diff --git a/src/plugin/duration/index.js b/src/plugin/duration/index.js index 5aaacee21..d1f09c90c 100644 --- a/src/plugin/duration/index.js +++ b/src/plugin/duration/index.js @@ -84,7 +84,9 @@ class Duration { const d = input.match(DURATION_REGEX_PARSE) if (d) { const properties = d.slice(2) - const numberD = properties.map(value => (value != null ? Number(value) : 0)); + const signMultiplier = d[1] === '-' ? -1 : 1 + const numberD = properties.map(value => + (value != null ? Number(value) * signMultiplier : 0)); [ this.$d.years, this.$d.months, diff --git a/test/plugin/duration.test.js b/test/plugin/duration.test.js index f9a4c7cf4..e9ce74c16 100644 --- a/test/plugin/duration.test.js +++ b/test/plugin/duration.test.js @@ -108,6 +108,13 @@ describe('Parse ISO string', () => { it('Invalid ISO string', () => { expect(dayjs.duration('Invalid').toISOString()).toBe('P0D') }) + it('Negative ISO string round-trips', () => { + expect(dayjs.duration('-P1Y').asYears()).toBe(-1) + expect(dayjs.duration('-P1DT2H').asHours()).toBe(-26) + expect(dayjs.duration('-PT59S').toISOString()).toBe('-PT59S') + const d = dayjs.duration(-1, 'years') + expect(dayjs.duration(d.toISOString()).asMilliseconds()).toBe(d.asMilliseconds()) + }) }) it('Is duration', () => {