Skip to content

Commit 0eda15b

Browse files
committed
Make applyDuration reversible.
1 parent b6dbae3 commit 0eda15b

File tree

2 files changed

+38
-14
lines changed

2 files changed

+38
-14
lines changed

src/duration.ts

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,35 @@ export class Duration {
8484
}
8585
}
8686

87+
const durationApplicationActionsForward = [
88+
(r: Date, duration: Duration) => {
89+
r.setUTCFullYear(r.getUTCFullYear() + duration.years)
90+
},
91+
(r: Date, duration: Duration) => {
92+
r.setUTCMonth(r.getUTCMonth() + duration.months)
93+
},
94+
(r: Date, duration: Duration) => {
95+
r.setUTCDate(r.getUTCDate() + duration.weeks * 7 + duration.days)
96+
},
97+
(r: Date, duration: Duration) => {
98+
r.setUTCHours(r.getUTCHours() + duration.hours)
99+
},
100+
(r: Date, duration: Duration) => {
101+
r.setUTCMinutes(r.getUTCMinutes() + duration.minutes)
102+
},
103+
(r: Date, duration: Duration) => {
104+
r.setUTCSeconds(r.getUTCSeconds() + duration.seconds)
105+
},
106+
]
107+
const durationApplicationActionsBackward = [...durationApplicationActionsForward].reverse()
108+
87109
export function applyDuration(date: Date | number, duration: Duration): Date {
88110
const r = new Date(date)
89-
r.setFullYear(r.getFullYear() + duration.years)
90-
r.setMonth(r.getMonth() + duration.months)
91-
r.setDate(r.getDate() + duration.weeks * 7 + duration.days)
92-
r.setHours(r.getHours() + duration.hours)
93-
r.setMinutes(r.getMinutes() + duration.minutes)
94-
r.setSeconds(r.getSeconds() + duration.seconds)
111+
if (duration.sign < 0) {
112+
for (const action of durationApplicationActionsBackward) action(r, duration)
113+
} else {
114+
for (const action of durationApplicationActionsForward) action(r, duration)
115+
}
95116
return r
96117
}
97118

test/duration.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,16 +81,19 @@ suite('duration', function () {
8181
})
8282

8383
suite('applyDuration', function () {
84-
const referenceDate = '2022-10-21T16:48:44.104Z'
8584
const tests = new Set([
86-
{input: 'P4Y', expected: '2026-10-21T16:48:44.104Z'},
87-
{input: '-P4Y', expected: '2018-10-21T16:48:44.104Z'},
88-
{input: '-P3MT5M', expected: '2022-07-21T16:43:44.104Z'},
89-
{input: 'P1Y2M3DT4H5M6S', expected: '2023-12-24T20:53:50.104Z'},
90-
{input: 'P5W', expected: '2022-11-25T16:48:44.104Z'},
91-
{input: '-P5W', expected: '2022-09-16T16:48:44.104Z'},
85+
{referenceDate: '2022-10-21T16:48:44.104Z', input: 'P5W', expected: '2022-11-25T16:48:44.104Z'},
86+
{referenceDate: '2022-11-25T16:48:44.104Z', input: '-P5W', expected: '2022-10-21T16:48:44.104Z'},
87+
{referenceDate: '2022-07-21T16:43:44.104Z', input: 'P3MT5M', expected: '2022-10-21T16:48:44.104Z'},
88+
{referenceDate: '2022-10-21T16:48:44.104Z', input: '-P3MT5M', expected: '2022-07-21T16:43:44.104Z'},
89+
{referenceDate: '2022-10-21T16:48:44.104Z', input: 'P4Y', expected: '2026-10-21T16:48:44.104Z'},
90+
{referenceDate: '2026-10-21T16:48:44.104Z', input: '-P4Y', expected: '2022-10-21T16:48:44.104Z'},
91+
{referenceDate: '2022-10-21T16:48:44.104Z', input: 'P1Y2M3DT4H5M6S', expected: '2023-12-24T20:53:50.104Z'},
92+
{referenceDate: '2023-12-24T20:53:50.104Z', input: '-P1Y2M3DT4H5M6S', expected: '2022-10-21T16:48:44.104Z'},
93+
{referenceDate: '2023-08-15T00:00:00.000Z', input: 'P1Y3M25D', expected: '2024-12-10T00:00:00.000Z'},
94+
{referenceDate: '2024-12-10T00:00:00.000Z', input: '-P1Y3M25D', expected: '2023-08-15T00:00:00.000Z'},
9295
])
93-
for (const {input, expected} of tests) {
96+
for (const {referenceDate, input, expected} of tests) {
9497
test(`${referenceDate} -> ${input} -> ${expected}`, () => {
9598
assert.equal(applyDuration(new Date(referenceDate), Duration.from(input))?.toISOString(), expected)
9699
})

0 commit comments

Comments
 (0)