iamkun / iamkun/dayjs

Subtract method incorrect for weeks and milliseconds

Open
#3,042 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
48.7k
Forks
2.5k
PR merge metrics
No merged PRs in 30d

Description

**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) {
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');
});
});

```

Contributor guide

Open the contributing guide

Research direction

Start with the attached Vitest reproduction and run the duration-object subtraction cases for milliseconds, weeks, and mixed weeks plus days. Trace the Day.js subtract(duration) entry point to find where those duration components are handled; done means the skipped cases pass without breaking the existing seconds, minutes, hours, days, months, years, and mixed-hour cases.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.