moment / luxon

⏱ A library for working with dates and times in JS
https://moment.github.io/luxon
MIT License
15.31k stars 729 forks source link

Start of day issue if on boundary of DST change #1636

Closed PaulAtST closed 4 months ago

PaulAtST commented 4 months ago

Describe the bug Using startOf('day') or setting hour, min, sec, and millisecond to 0 .set({hour: 0, minute: 0, second: 0, millisecond: 0}) seam to give me the previous day if the day is on the border of a DST change.

To Reproduce

 let dayStart = DateTime.fromMillis(1712494860000).setZone('Australia/Sydney') 
 console.log(dayStart.ts) // > 1712494860000 =  UTC Sun Apr 07 2024 13:01:00

 dayStart = dayStart.startOf('day')
 console.log(dayStart.ts) // > 1712408400000 = UTC Sat Apr 06 2024 13:00:00

or

 let dayStart = DateTime.fromMillis(1712494860000).setZone('Australia/Sydney') 
 console.log(dayStart.ts) // > 1712494860000 =  UTC Sun Apr 07 2024 13:01:00

dayStart = dayStart.set({
        hour: 0,
        minute: 0, 
        second: 0,
        millisecond: 0
 })

 console.log(dayStart.ts) // > 1712408400000 = UTC Sat Apr 06 2024 13:00:00

Actual vs Expected behavior Actual: Returns previous day Expected Returns current day start

Desktop (please complete the following information):

diesieben07 commented 4 months ago

startOf operates in the DateTime's time zone. If you use toISO (or toObject or any other output format that doesn't convert to UTC) you will see that it produces the correct result.

Your first example:

let dayStart = DateTime.fromMillis(1712494860000).setZone('Australia/Sydney')
console.log(dayStart.toISO()) // 2024-04-07T23:01:00.000+10:00

dayStart = dayStart.startOf('day')
console.log(dayStart.toISO()) // 2024-04-07T00:00:00.000+11:00

The same happens with your second example:

let dayStart = DateTime.fromMillis(1712494860000).setZone('Australia/Sydney')
console.log(dayStart.toISO()) // 2024-04-07T23:01:00.000+10:00

dayStart = dayStart.set({
  hour: 0,
  minute: 0,
  second: 0,
  millisecond: 0
})

console.log(dayStart.toISO()) // 2024-04-07T00:00:00.000+11:00
PaulAtST commented 4 months ago

Thanks for the info. Going to need to dive in deeper, but I think it pointed me in the with direction and it's not a luxon issue.

Incase anyone else runs into this. The issue I found is when going from Sat Apr 06 20024 to Sun Apr 07 20024 in Australia/Sydney the clocks fell back so you have a 25 hour day to account for. So taking Apr 06 20024 UTC + 24 hours UTC and then doing start of day keeps me at Apr 06 20024 UTC, which is technically correct. So if I take Apr 06 20024 UTC + 25 hours UTC and then do start of day I correctly get the start time for Sun Apr 07 20024.