iamkun / iamkun/dayjs

Inconsistent behavior when updating date across DST change

Open
#2,210 0 comments 1 reaction 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**
Using e.g. the `.hour(h)` setter on a date that is during Daylight Saving Time, and changes it to a time when DST was not in effect, seems to have different behavior depending on how the original date was constructed.

I am using the `timezone` plugin, and the dates are in a specific timezone.

Example:
```
const dayjs = require('dayjs');
const timezone = require('dayjs/plugin/timezone');
const utc = require('dayjs/plugin/utc');

dayjs.extend(timezone);
dayjs.extend(utc);

const noon1 = dayjs.tz(new Date('2023-03-12T19:00:00Z'), 'America/Los_Angeles');
console.log('noon1:', noon1.toISOString());
// noon1: 2023-03-12T19:00:00.000Z
const midnight1 = noon1.hour(0);
console.log('midnight1:', midnight1.toISOString());
// midnight1: 2023-03-12T07:00:00.000Z
console.log('Difference:', (noon1.unix() - midnight1.unix()) / 3600, 'hours');
// Difference: 12 hours

const noon2 = dayjs.tz('2023-03-12T12:00:00', 'America/Los_Angeles');
console.log('noon2:', noon2.toISOString());
// noon2: 2023-03-12T19:00:00.000Z
const midnight2 = noon2.hour(0);
console.log('midnight2:', midnight2.toISOString());
// midnight2: 2023-03-12T08:00:00.000Z
console.log('Difference:', (noon2.unix() - midnight2.unix()) / 3600, 'hours');
// Difference: 11 hours
```
The output of each log statement is shown in the comment below it. Note that the first "Difference" output is 12 hours, and the second is 11 hours, although the two starting dates represent the same time in the same timezone (noon on March 12, 2023, US Pacific time).

(March 23, 2023 is the day when DST starts in this timezone. So at noon DST is in effect, but at midnight it wasn't. The time between midnight and noon is 11 hours.)

**Expected behavior**
I would expect the two "Difference" outputs above to have the same value. I *think* I would expect it to be 11 hours, not 12, although I'm not sure I really understand the intended semantics of the timezone plugin. It may even be that this is working as intended, but if so, I'd love to see an explanation of why.

**Information**
- Day.js Version: 1.11.7
- OS: Ubuntu 20.04 (running under Windows Subsystem for Linux on Windows 10)
- Browser: No browser, using Node.js v19.4.0
- Time zone: I am in USA Eastern Standard Time (America/New_York), although the above example uses Pacific Standard Time.

Contributor guide

Open the contributing guide

Research direction

Start with the timezone and utc plugins and the .hour(h) setter, then reproduce the two constructions from the issue in Node.js. Compare their intermediate timezone and offset values across the DST transition. Done means the intended semantics are established and the two equivalent starting dates behave consistently, with regression coverage if the behavior is changed.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
api
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.