dayjs
dayjs copied to clipboard
Adding days across daylight savings time in GMT timezone has unexpected result
Describe the bug
I am using version 1.11.6 of dayjs.
I have a simple test case for what I think is a dayjs bug. I add 2 days to a day in GMT/UTC timezone and get something that is not on a day boundary. It probably has something to do with daylight savings time because this is when daylight savings time happens in US. However, why its it a 2 hour difference, and why does it happen in GMT/UTC time? This change did not happen when we used moment.js.
it('should be exactly two days later when adding two days', function () {
const day1 = dayjs.tz({ year: 2018, month: 2, day: 10 }, 'GMT');
const day2 = day1.add(2, 'day');
expect(day2.valueOf()).toEqual(dayjs.tz({ year: 2018, month: 2, day: 12, hour: 2 }, 'GMT').valueOf());
});
Expected behavior
This version of the test should pass. We should not need to add two hours to the expected result.
it('should be exactly two days later when adding two days', function () { const day1 = dayjs.tz({ year: 2018, month: 2, day: 10 }, 'GMT'); const day2 = day1.add(2, 'day'); expect(day2.valueOf()).toEqual(dayjs.tz({ year: 2018, month: 2, day: 12 }, 'GMT').valueOf()); });
Information
- Day.js Version 1.11.6
- OS: IOS/mac
- Browser N/A
- Time zone: GMT. My local machine TZ is PST and that might affect the test result.
I also don't understand why these 2 things are not equal
expect(dayjs.utc({ year: 2018, month: 2, day: 10 }).valueOf())
.toEqual(dayjs.tz({ year: 2018, month: 2, day: 10 }, 'UTC').valueOf());
Some other related issues: https://github.com/iamkun/dayjs/issues/1271 https://github.com/iamkun/dayjs/issues/586
I just ran into what I think is the same issue while adding hours to a date. When that date is midnight on daylight savings day I get a different result than any other day.
dayjs('2023-03-12').startOf('day').add(7, 'hours') => 2023-03-12T13:00:00.000Z
dayjs('2023-03-13').startOf('day').add(7, 'hours') => 2023-03-13T12:00:00.000Z
I think in my case with hours it might be justified to work this way but was definitely confusing. I am able to work around it by using this instead:
dayjs('2023-03-12').startOf('day').hour(7) => 2023-03-12T12:00:00.000Z
dayjs('2023-03-13').startOf('day').hour(7) => 2023-03-13T12:00:00.000Z
I'm not sure this would be helpful with whole days @bbecker-te but maybe, but it appears to be the same underlying issue
Also affected by time one. was working as expected only this month started giving weird results. we are trying to get the utc date+time for the next midnight in the specifed timezone
I have an issue with timezone not changing.
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc.js'
import timezone from 'dayjs/plugin/timezone.js'
dayjs.extend(utc)
dayjs.extend(timezone)
const todayDateInUTC = dayjs().utc()
const customTimezone = dayjs().utc().tz('America/Chicago')
console.log(todayDateInUTC.toDate()) // => 2023-02-16T09:19:50.295Z
console.log(customTimezone.toDate()) // => 2023-02-16T09:19:50.299Z
running on:
- nodejs v18.5.0
- dayjs 1.11.2
@hadyrashwan That's expected, when converting toDate()
you'll always see the underlying UTC value even if the dayjs objects had different timezone settings.
@bbecker-te Does this happen in other UTC+0 timezones, like "Europe/London"? I've noticed when using those timezones that the UTC flag is set, which it shouldn't be. This causes a lot of issues with arithmetic since the system's TZ ends up getting used for formatting. I submitted https://github.com/iamkun/dayjs/issues/2254 with more details & examples.
@bbecker-te I let this comment on another issue that probably will help you to solve this issue as well.
https://github.com/iamkun/dayjs/issues/1271#issuecomment-1921945845
Let me know if it helped.