import {Duration, PlainDate, ZonedDateTime} from '@/'; import {describe, it, assert} from 'vitest'; let dayMilliseconds = 24 * 3600 * 1000; let fullDays = 5; let fullMilliseconds = fullDays * dayMilliseconds + 5 * 3600_000 + 5 * 60_000 + 5000 + 5; let partialDayMilliseconds = fullMilliseconds - fullDays * dayMilliseconds; let fractionalDay = partialDayMilliseconds / dayMilliseconds; type DurationTotalParameters = Parameters[0]; let relativeToDayMilliseconds = 24 * 3600 * 1000; let relativeToFullYears = 5; let relativeToFullMonths = relativeToFullYears * 12 + 5 + 1; let relativeToFullDays = 366 + 365 + 365 + 365 + 366 + 31 + 28 + 31 + 30 + 31 + 5 * 7 + 5; let relativeToFullMilliseconds = relativeToFullDays * relativeToDayMilliseconds + 5 * 3600_000 + 5 * 60_000 + 5000 + 5; let relativeToPartialDayMilliseconds = relativeToFullMilliseconds - relativeToFullDays * relativeToDayMilliseconds; let relativeToFractionalDay = relativeToPartialDayMilliseconds / relativeToDayMilliseconds; let relativeToPartialYearDays = relativeToFullDays - (relativeToFullYears * 365 + 2); let relativeToFractionalYear = relativeToPartialYearDays / 365 + relativeToFractionalDay / 365; let relativeToFractionalMonths = (10 /* = 2025-07-11 - 2025-07-01 */ * relativeToDayMilliseconds + relativeToPartialDayMilliseconds) / (31 * relativeToDayMilliseconds); let duration = new Duration(5, 5, 5, 5, 5, 5, 5, 5); let plainRelativeTo = new PlainDate(2000, 1, 1); let zonedRelativeTo = new ZonedDateTime(63072000_000, 'UTC'); let testCases: [Duration, DurationTotalParameters, number][] = [ [new Duration(0, 0, 0, 5, 5, 5, 5, 5), 'day', fullDays + fractionalDay], [new Duration(0, 0, 0, 5, 5, 5, 5, 5), 'hour', fullDays * 24 + partialDayMilliseconds / 3600000], [new Duration(0, 0, 0, 5, 5, 5, 5, 5), 'minute', fullDays * 24 * 60 + partialDayMilliseconds / 60000], [new Duration(0, 0, 0, 5, 5, 5, 5, 5), 'second', fullDays * 24 * 60 * 60 + partialDayMilliseconds / 1000], [new Duration(0, 0, 0, 5, 5, 5, 5, 5), 'millisecond', fullMilliseconds], [duration, {unit: 'year', relativeTo: plainRelativeTo}, relativeToFullYears + relativeToFractionalYear], [duration, {unit: 'month', relativeTo: plainRelativeTo}, relativeToFullMonths + relativeToFractionalMonths], // [ // duration, // {unit: 'week', relativeTo: plainRelativeTo}, // Math.floor(relativeToFullDays / 7) + (2 + relativeToFractionalDay) / 7, // ], [duration, {unit: 'day', relativeTo: plainRelativeTo}, relativeToFullDays + relativeToFractionalDay], [ duration, {unit: 'hour', relativeTo: plainRelativeTo}, relativeToFullDays * 24 + relativeToPartialDayMilliseconds / 3600000, ], [ duration, {unit: 'minute', relativeTo: plainRelativeTo}, relativeToFullDays * 24 * 60 + relativeToPartialDayMilliseconds / 60000, ], [ duration, {unit: 'second', relativeTo: plainRelativeTo}, relativeToFullDays * 24 * 60 * 60 + relativeToPartialDayMilliseconds / 1000, ], [duration, {unit: 'millisecond', relativeTo: plainRelativeTo}, relativeToFullMilliseconds], [duration, {unit: 'year', relativeTo: zonedRelativeTo}, relativeToFullYears + relativeToFractionalYear], [duration, {unit: 'month', relativeTo: zonedRelativeTo}, relativeToFullMonths + relativeToFractionalMonths], // [ // duration, // {unit: 'week', relativeTo: zonedRelativeTo}, // Math.floor(relativeToFullDays / 7) + (2 + relativeToFractionalDay) / 7, // ], [duration, {unit: 'day', relativeTo: zonedRelativeTo}, relativeToFullDays + relativeToFractionalDay], [ duration, {unit: 'hour', relativeTo: zonedRelativeTo}, relativeToFullDays * 24 + relativeToPartialDayMilliseconds / 3600000, ], [ duration, {unit: 'minute', relativeTo: zonedRelativeTo}, relativeToFullDays * 24 * 60 + relativeToPartialDayMilliseconds / 60000, ], [ duration, {unit: 'second', relativeTo: zonedRelativeTo}, relativeToFullDays * 24 * 60 * 60 + relativeToPartialDayMilliseconds / 1000, ], [duration, {unit: 'millisecond', relativeTo: zonedRelativeTo}, relativeToFullMilliseconds], ]; describe('Duration', () => { describe('Duration#total', () => { it.each(testCases)('%j total(%j) -> %j', (duration, parameters, expected) => { let result = duration.total(parameters); assert.equal(result, expected); }); }); });