dayjs icon indicating copy to clipboard operation
dayjs copied to clipboard

Getting wrong startOf('day') and endOf('day') in a different timezone

Open ehduardu opened this issue 2 years ago • 6 comments

Describe the bug The functions startOf('day') and endOf('day') are returning the wrong day when I change the timezone from UTC (GMT).

Code example:

dayjs('2023-09-01').tz('America/Sao_Paulo').startOf('day')

Result: Thu, 31 Aug 2023 03:00:00 GMT

Expected behavior Fri, 01 Sep 2023 03:00:00 GMT

Information

  • Day.js Version: ^1.11.3
  • OS: Ubuntu 22.04.3 LTS
  • Browser: Node JS 16
  • Time zone: UTC (GMT)

ehduardu avatar Oct 02 '23 13:10 ehduardu

Extra info: I did this to return the expected dayjs(dayjs('2023-09-01').endOf('day')).tz('America/Sao_Paulo').startOf('day')

ehduardu avatar Oct 02 '23 13:10 ehduardu

It seems the keepLocalTime flag solves that dayjs('2023-09-01').tz('America/Sao_Paulo', true).startOf('day')

But how can I use this flag when I using the tz.setDefault() (without passing the timezone again)?

ehduardu avatar Oct 02 '23 13:10 ehduardu

Moreover:

  const summerLondon = dayjs('2023-09-29T00:00:00.000Z', { utc: true }).tz('Europe/London');
  const winterLondon = dayjs('2023-11-29T00:00:00.000Z', { utc: true }).tz('Europe/London');
  console.info(`winterLondon`, winterLondon.toISOString());
  console.info(
    `winterLondon.startOf('d')`,
    winterLondon.startOf('d').toISOString(),
  );
  console.info(
    `winterLondon.startOf('d').startOf('d')`,
    winterLondon.startOf('d').startOf('d').toISOString(),
  );
  console.info(
    `winterLondon.startOf('d').startOf('d').startOf('d')`,
    winterLondon.startOf('d').startOf('d').startOf('d').toISOString(),
  );
  console.info(`summerLondon`, summerLondon.toISOString());
  console.info(
    `summerLondon.startOf('d')`,
    summerLondon.startOf('d').toISOString(),
  );
  console.info(
    `summerLondon.startOf('d').startOf('d')`,
    summerLondon.startOf('d').startOf('d').toISOString(),
  );
  console.info(
    `summerLondon.startOf('d').startOf('d').startOf('d')`,
    summerLondon.startOf('d').startOf('d').startOf('d').toISOString(),
  );

the output:

winterLondon 2023-11-29T00:00:00.000Z
winterLondon.startOf('d') 2023-11-29T00:00:00.000Z
winterLondon.startOf('d').startOf('d') 2023-11-28T00:00:00.000Z
winterLondon.startOf('d').startOf('d').startOf('d') 2023-11-27T00:00:00.000Z
summerLondon 2023-09-29T00:00:00.000Z
summerLondon.startOf('d') 2023-09-28T23:00:00.000Z
summerLondon.startOf('d').startOf('d') 2023-09-28T23:00:00.000Z
summerLondon.startOf('d').startOf('d').startOf('d') 2023-09-28T23:00:00.000Z

aivanov-noveo avatar Oct 18 '23 14:10 aivanov-noveo

Also facing this problem and it is a really bad problem because I just notice that every single filter I made so far was wrong.

This made me question a lot if dayjs is even an option to use because if I do:

console.log(dayjs()), it logs: "Wed, 29 Nov 2023 21:39:14 GMT". meanwhile, moment is logging the right timezone I am right now: "Wed Nov 29 2023 18:40:19 GMT-0300"

NathanAP avatar Nov 29 '23 21:11 NathanAP

Here's another discussion on this issue going back to 2020 - https://github.com/iamkun/dayjs/issues/1219 I commented this codesandbox reproducing the issue https://codesandbox.io/p/sandbox/new-grass-hfmczy

chrisjagoda avatar Nov 30 '23 23:11 chrisjagoda

I changed to date-fns. No reason to go for dayjs in my opinion, moment as legacy is better and more trustable.

NathanAP avatar Nov 30 '23 23:11 NathanAP