Skip to content

Subtract method incorrect for weeks and milliseconds #3042

@sherlock1982

Description

@sherlock1982

Describe the bug
When you have duration in weeks or milliseconds it doesn't properly subtract

Expected behavior
It should subtract

Information

  • Day.js Version 1.11.19

Attaching file to demonstrate the issue

import { describe, it, expect } from 'vitest';
import dayjs from 'dayjs';

// Baseline: 2018-06-27T00:00:00.000Z (mocked in vitest.config via setSystemTime elsewhere,
// but here we use a fixed reference date to keep tests self-contained)
const BASE = dayjs.utc('2018-06-27T00:00:00.000Z');

function subtracted(duration: ReturnType<typeof dayjs.duration>) {
    return BASE.subtract(duration).toISOString();
}

describe('dayjs subtract with duration object', () => {
    // dayjs bug: milliseconds are silently ignored by subtract(duration)
    it.skip('milliseconds: 1000', () => {
        expect(subtracted(dayjs.duration({ milliseconds: 1000 }))).toBe('2018-06-26T23:59:59.000Z');
    });

    it('seconds: 60', () => {
        expect(subtracted(dayjs.duration({ seconds: 60 }))).toBe('2018-06-26T23:59:00.000Z');
    });

    it('minutes: 60', () => {
        expect(subtracted(dayjs.duration({ minutes: 60 }))).toBe('2018-06-26T23:00:00.000Z');
    });

    it('hours: 24', () => {
        expect(subtracted(dayjs.duration({ hours: 24 }))).toBe('2018-06-26T00:00:00.000Z');
    });

    it('days: 14', () => {
        expect(subtracted(dayjs.duration({ days: 14 }))).toBe('2018-06-13T00:00:00.000Z');
    });

    // dayjs bug: weeks are silently ignored by subtract(duration)
    it.skip('weeks: 2', () => {
        expect(subtracted(dayjs.duration({ weeks: 2 }))).toBe('2018-06-13T00:00:00.000Z');
    });

    it('months: 1', () => {
        expect(subtracted(dayjs.duration({ months: 1 }))).toBe('2018-05-27T00:00:00.000Z');
    });

    it('years: 1', () => {
        expect(subtracted(dayjs.duration({ years: 1 }))).toBe('2017-06-27T00:00:00.000Z');
    });

    // dayjs bug: weeks component is silently ignored, only days are subtracted
    it.skip('mixed: 1 week + 3 days', () => {
        expect(subtracted(dayjs.duration({ weeks: 1, days: 3 }))).toBe('2018-06-17T00:00:00.000Z');
    });

    it('mixed: 1 hour + 30 minutes', () => {
        expect(subtracted(dayjs.duration({ hours: 1, minutes: 30 }))).toBe('2018-06-26T22:30:00.000Z');
    });
});

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions