Skip to content

Commit

Permalink
Make applyDuration reversible.
Browse files Browse the repository at this point in the history
  • Loading branch information
leduyquang753 committed Dec 30, 2024
1 parent a80c1bf commit d37caed
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 14 deletions.
33 changes: 27 additions & 6 deletions src/duration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,35 @@ export class Duration {
}
}

const durationApplicationActionsForward = [
(r: Date, duration: Duration) => {
r.setUTCFullYear(r.getUTCFullYear() + duration.years)
},
(r: Date, duration: Duration) => {
r.setUTCMonth(r.getUTCMonth() + duration.months)
},
(r: Date, duration: Duration) => {
r.setUTCDate(r.getUTCDate() + duration.weeks * 7 + duration.days)
},
(r: Date, duration: Duration) => {
r.setUTCHours(r.getUTCHours() + duration.hours)
},
(r: Date, duration: Duration) => {
r.setUTCMinutes(r.getUTCMinutes() + duration.minutes)
},
(r: Date, duration: Duration) => {
r.setUTCSeconds(r.getUTCSeconds() + duration.seconds)
},
]
const durationApplicationActionsBackward = [...durationApplicationActionsForward].reverse()

export function applyDuration(date: Date | number, duration: Duration): Date {
const r = new Date(date)
r.setFullYear(r.getFullYear() + duration.years)
r.setMonth(r.getMonth() + duration.months)
r.setDate(r.getDate() + duration.weeks * 7 + duration.days)
r.setHours(r.getHours() + duration.hours)
r.setMinutes(r.getMinutes() + duration.minutes)
r.setSeconds(r.getSeconds() + duration.seconds)
if (duration.sign < 0) {
for (const action of durationApplicationActionsBackward) action(r, duration)
} else {
for (const action of durationApplicationActionsForward) action(r, duration)
}
return r
}

Expand Down
19 changes: 11 additions & 8 deletions test/duration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,16 +81,19 @@ suite('duration', function () {
})

suite('applyDuration', function () {
const referenceDate = '2022-10-21T16:48:44.104Z'
const tests = new Set([
{input: 'P4Y', expected: '2026-10-21T16:48:44.104Z'},
{input: '-P4Y', expected: '2018-10-21T16:48:44.104Z'},
{input: '-P3MT5M', expected: '2022-07-21T16:43:44.104Z'},
{input: 'P1Y2M3DT4H5M6S', expected: '2023-12-24T20:53:50.104Z'},
{input: 'P5W', expected: '2022-11-25T16:48:44.104Z'},
{input: '-P5W', expected: '2022-09-16T16:48:44.104Z'},
{referenceDate: '2022-10-21T16:48:44.104Z', input: 'P5W', expected: '2022-11-25T16:48:44.104Z'},
{referenceDate: '2022-11-25T16:48:44.104Z', input: '-P5W', expected: '2022-10-21T16:48:44.104Z'},
{referenceDate: '2022-07-21T16:43:44.104Z', input: 'P3MT5M', expected: '2022-10-21T16:48:44.104Z'},
{referenceDate: '2022-10-21T16:48:44.104Z', input: '-P3MT5M', expected: '2022-07-21T16:43:44.104Z'},
{referenceDate: '2022-10-21T16:48:44.104Z', input: 'P4Y', expected: '2026-10-21T16:48:44.104Z'},
{referenceDate: '2026-10-21T16:48:44.104Z', input: '-P4Y', expected: '2022-10-21T16:48:44.104Z'},
{referenceDate: '2022-10-21T16:48:44.104Z', input: 'P1Y2M3DT4H5M6S', expected: '2023-12-24T20:53:50.104Z'},
{referenceDate: '2023-12-24T20:53:50.104Z', input: '-P1Y2M3DT4H5M6S', expected: '2022-10-21T16:48:44.104Z'},
{referenceDate: '2023-08-15T00:00:00.000Z', input: 'P1Y3M25D', expected: '2024-12-10T00:00:00.000Z'},
{referenceDate: '2024-12-10T00:00:00.000Z', input: '-P1Y3M25D', expected: '2023-08-15T00:00:00.000Z'},
])
for (const {input, expected} of tests) {
for (const {referenceDate, input, expected} of tests) {
test(`${referenceDate} -> ${input} -> ${expected}`, () => {
assert.equal(applyDuration(new Date(referenceDate), Duration.from(input))?.toISOString(), expected)
})
Expand Down

0 comments on commit d37caed

Please sign in to comment.