import {describe, it, assert} from 'vitest'; import {ZonedDateTime} from '@/'; describe('ZonedDateTime', () => { describe('#until', () => { it('calculates difference for minutes', async function () { let one = new ZonedDateTime(Date.UTC(2024, 4, 12, 20, 54, 0), 'Europe/Berlin'); let two = new ZonedDateTime(Date.UTC(2024, 4, 12, 20, 55, 0), 'Europe/Berlin'); assert.equal(one.until(two).toJSON(), 'PT1M'); assert.equal(two.until(one).toJSON(), '-PT1M'); }); it('calculates difference for minutes', async function () { let one = new ZonedDateTime(Date.UTC(2024, 4, 12, 20, 54, 0), 'Europe/Berlin'); let two = new ZonedDateTime(Date.UTC(2024, 4, 12, 20, 55, 30), 'Europe/Berlin'); assert.equal(one.until(two, {smallestUnit: 'minute'}).toJSON(), 'PT1M'); }); it('calculates difference for hours and minutes', function () { let one = new ZonedDateTime(Date.UTC(2024, 4, 12, 20, 54, 0), 'Europe/Oslo'); let two = new ZonedDateTime(Date.UTC(2024, 4, 12, 23, 55, 0), 'Europe/Oslo'); assert.equal(one.until(two).toJSON(), 'PT3H1M'); assert.equal(two.until(one).toJSON(), '-PT3H1M'); assert.equal(one.until(two, {smallestUnit: 'hour'}).toJSON(), 'PT3H'); assert.equal(one.until(two, {smallestUnit: 'hour', roundingMode: 'ceil'}).toJSON(), 'PT4H'); }); it('calculates difference for hours and overflowing minutes', function () { let one = new ZonedDateTime(Date.UTC(2024, 4, 12, 20, 54, 0), 'Europe/Oslo'); let two = new ZonedDateTime(Date.UTC(2024, 4, 12, 23, 53, 0), 'Europe/Oslo'); assert.equal(one.until(two).toJSON(), 'PT2H59M'); assert.equal(two.until(one).toJSON(), '-PT2H59M'); assert.equal(one.until(two, {smallestUnit: 'hour', roundingMode: 'halfExpand'}).toJSON(), 'PT3H'); }); it('calculates difference for overflowing minutes and overflowing hours', function () { let one = new ZonedDateTime(Date.UTC(2024, 4, 12, 20, 54, 0), 'Europe/Oslo'); let two = new ZonedDateTime(Date.UTC(2024, 4, 13, 5, 40, 0), 'Europe/Oslo'); assert.equal(one.until(two).toJSON(), 'PT8H46M'); assert.equal(two.until(one).toJSON(), '-PT8H46M'); }); it('calculates difference when expanding DST cutoff', function () { let one = new ZonedDateTime(Date.UTC(2024, 2, 31, 0, 0, 0), 'Europe/Oslo'); let two = new ZonedDateTime(Date.UTC(2024, 3, 2, 23, 0, 0), 'Europe/Oslo'); assert.equal(one.until(two, {largestUnit: 'year'}).toJSON(), 'P3D'); assert.equal(two.until(one, {largestUnit: 'year'}).toJSON(), '-P3D'); }); it('calculates difference when expanding DST cutoff (less than 24 hours)', function () { let one = new ZonedDateTime(Date.UTC(2024, 2, 31, 0, 0, 0), 'Europe/Oslo'); let two = new ZonedDateTime(Date.UTC(2024, 2, 31, 1, 0, 0), 'Europe/Oslo'); assert.equal(one.until(two).toJSON(), 'PT1H'); assert.equal(two.until(one).toJSON(), '-PT1H'); }); it('calculates difference when expanding DST-end cutoff (less than 24 hours)', function () { let one = new ZonedDateTime(Date.UTC(2024, 9, 27, 0, 0, 0), 'Europe/Oslo'); let two = new ZonedDateTime(Date.UTC(2024, 9, 27, 2, 0, 0), 'Europe/Oslo'); assert.equal(one.until(two).toJSON(), 'PT2H'); assert.equal(two.until(one).toJSON(), '-PT2H'); }); it('calculates difference when expanding DST-start cutoff (less than 24 hours)', function () { let one = new ZonedDateTime(Date.UTC(2024, 2, 30, 23, 0, 0), 'Europe/Oslo'); let two = new ZonedDateTime(Date.UTC(2024, 2, 31, 21, 0, 0), 'Europe/Oslo'); let three = new ZonedDateTime(Date.UTC(2024, 2, 31, 22, 0, 0), 'Europe/Oslo'); assert.equal(one.until(two).toJSON(), 'PT22H'); assert.equal(two.until(one).toJSON(), '-PT22H'); assert.equal(one.until(three, {largestUnit: 'day'}).toJSON(), 'P1D'); assert.equal(three.until(one, {largestUnit: 'day'}).toJSON(), '-P1D'); }); it('calculates difference when expanding DST-end cutoff (less than 24 hours)', function () { let one = new ZonedDateTime(Date.UTC(2024, 9, 26, 22, 0, 0), 'Europe/Oslo'); let two = new ZonedDateTime(Date.UTC(2024, 9, 27, 22, 0, 0), 'Europe/Oslo'); assert.equal(one.until(two).toJSON(), 'PT24H'); assert.equal(two.until(one).toJSON(), '-PT24H'); }); it('calculates difference when expanding DST-end (over 1 day)', function () { let one = new ZonedDateTime(Date.UTC(2024, 9, 27, 0, 0, 0), 'Europe/Oslo'); let two = new ZonedDateTime(Date.UTC(2024, 9, 29, 1, 0, 0), 'Europe/Oslo'); assert.equal(one.until(two, {largestUnit: 'year'}).toJSON(), 'P2D'); assert.equal(two.until(one, {largestUnit: 'year'}).toJSON(), '-P2D'); }); it('same year, same month, different days (date only)', function () { let one = new ZonedDateTime(Date.UTC(2024, 4, 12, 20, 54, 0), 'Europe/Oslo'); let two = new ZonedDateTime(Date.UTC(2024, 4, 14, 20, 54, 0), 'Europe/Oslo'); assert.equal(one.until(two, {largestUnit: 'day'}).toJSON(), 'P2D'); assert.equal(two.until(one, {largestUnit: 'day'}).toJSON(), '-P2D'); }); it('same year, same month, different days (wraps month)', function () { let one = new ZonedDateTime(Date.UTC(2024, 4, 12, 20, 54, 0), 'Europe/Oslo'); let two = new ZonedDateTime(Date.UTC(2024, 5, 8, 20, 54, 0), 'Europe/Oslo'); assert.equal(one.until(two, {largestUnit: 'day'}).toJSON(), 'P27D'); assert.equal(two.until(one, {largestUnit: 'day'}).toJSON(), '-P27D'); }); it('same year, same month, different days (wraps month with leap year)', function () { let one = new ZonedDateTime(Date.UTC(2024, 1, 12, 20, 54, 0), 'Europe/Oslo'); let two = new ZonedDateTime(Date.UTC(2024, 2, 8, 20, 54, 0), 'Europe/Oslo'); assert.equal(one.until(two, {largestUnit: 'day'}).toJSON(), 'P25D'); assert.equal(two.until(one, {largestUnit: 'day'}).toJSON(), '-P25D'); }); it('same year, same month, different days (wraps month without leap year)', function () { let one = new ZonedDateTime(Date.UTC(2023, 1, 12, 20, 54, 0), 'Europe/Oslo'); let two = new ZonedDateTime(Date.UTC(2023, 2, 8, 20, 54, 0), 'Europe/Oslo'); assert.equal(one.until(two, {largestUnit: 'day'}).toJSON(), 'P24D'); assert.equal(two.until(one, {largestUnit: 'day'}).toJSON(), '-P24D'); }); it('same year, different month, same days', function () { let one = new ZonedDateTime(Date.UTC(2024, 4, 12, 20, 54, 0), 'Europe/Oslo'); let two = new ZonedDateTime(Date.UTC(2024, 5, 12, 20, 54, 0), 'Europe/Oslo'); assert.equal(one.until(two, {largestUnit: 'month'}).toJSON(), 'P1M'); assert.equal(two.until(one, {largestUnit: 'month'}).toJSON(), '-P1M'); }); it('different year, same month, same days', function () { let one = new ZonedDateTime(Date.UTC(2023, 5, 12, 20, 54, 0), 'Europe/Oslo'); let two = new ZonedDateTime(Date.UTC(2024, 5, 12, 20, 54, 0), 'Europe/Oslo'); assert.equal(one.until(two, {largestUnit: 'year'}).toJSON(), 'P1Y'); assert.equal(two.until(one, {largestUnit: 'year'}).toJSON(), '-P1Y'); }); it('different year, different month, same days (less than a year)', function () { let one = new ZonedDateTime(Date.UTC(2023, 5, 12, 20, 54, 0), 'Europe/Oslo'); let two = new ZonedDateTime(Date.UTC(2024, 2, 12, 20, 54, 0), 'Europe/Oslo'); assert.equal(one.until(two, {largestUnit: 'month'}).toJSON(), 'P8M28DT23H'); assert.equal(two.until(one, {largestUnit: 'month'}).toJSON(), '-P8M29DT23H'); }); it('different year, different month, same days (more than a year)', function () { let one = new ZonedDateTime(Date.UTC(2023, 5, 12, 20, 54, 0), 'Europe/Oslo'); let two = new ZonedDateTime(Date.UTC(2024, 6, 12, 20, 54, 0), 'Europe/Oslo'); assert.equal(one.until(two, {largestUnit: 'year'}).toJSON(), 'P1Y1M'); assert.equal(two.until(one, {largestUnit: 'year'}).toJSON(), '-P1Y1M'); }); it('different year, different month, different days (less than a year and less than a month)', function () { let one = new ZonedDateTime(Date.UTC(2023, 5, 12, 20, 54, 0), 'Europe/Oslo'); let two = new ZonedDateTime(Date.UTC(2024, 4, 2, 20, 54, 0), 'Europe/Oslo'); assert.equal(one.until(two, {largestUnit: 'year'}).toJSON(), 'P10M20D'); assert.equal(two.until(one, {largestUnit: 'year'}).toJSON(), '-P10M20D'); }); it('different year, different month, different days (more than a year and more than a month)', function () { let one = new ZonedDateTime(Date.UTC(2023, 5, 12, 20, 54, 0), 'Europe/Oslo'); let two = new ZonedDateTime(Date.UTC(2024, 6, 14, 20, 54, 0), 'Europe/Oslo'); assert.equal(one.until(two, {largestUnit: 'year'}).toJSON(), 'P1Y1M2D'); assert.equal(two.until(one, {largestUnit: 'year'}).toJSON(), '-P1Y1M2D'); }); it('More than a year regression', function () { let from = Date.parse('2023-06-15T12:59:07.580Z'); let to = Date.parse('2024-06-03T14:00:27.568Z'); let one = new ZonedDateTime(from, 'Europe/Oslo'); let two = new ZonedDateTime(to, 'Europe/Oslo'); assert.equal(one.until(two, {largestUnit: 'year', smallestUnit: 'second'}).toJSON(), 'P11M19DT1H1M19S'); assert.equal(two.until(one, {largestUnit: 'year', smallestUnit: 'second'}).toJSON(), '-P11M18DT1H1M19S'); }); }); });