moment: endOf('day') fails on days that don't start at midnight

Consider:

moment("2016-10-16").endOf('day').format("YYYY-MM-DD HH:mm:ss")

In most time zones, this will return "2016-10-16 23:59:59". However, in Brazil, this will return "2016-10-17 00:59:59". This is incorrect, because only the hour from 00:00 to 00:59 on 2016-10-16 is missing. The end of 2016-10-16 is still 23:59:59 on the same date.

This is also reproducible with moment-timezone:

moment.tz("2016-10-16","America/Sao_Paulo").endOf('day').format("YYYY-MM-DD HH:mm:ss")

The problem is in the endOf method. To compute the end of the day, we take the start of the day, add one day, then subtract one millisecond. That logic is flawed when the day doesn’t start at midnight. Instead of adding one day, we need to add the exact duration length of the particular day.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 6
  • Comments: 15 (10 by maintainers)

Commits related to this issue

Most upvoted comments

I have tested the #4164 and this looks like be fixed on it. Waiting for merge.

In chrome with the windows timezone of Brasillia:

moment("2016-10-15").startOf('day').format()
"2016-10-15T00:00:00-03:00"
moment("2016-10-15").startOf('day').add(1, 'day').format()
"2016-10-16T01:00:00-02:00"

In chrome with my timezone using Moment Timezone:

moment.tz("2016-10-15","America/Sao_Paulo").startOf('day').format()
"2016-10-15T00:00:00-03:00"
moment.tz("2016-10-15","America/Sao_Paulo").startOf('day').add(1, 'day').format()
"2016-10-15T23:00:00-03:00"

COOL!

Something up with moment timezone? I don’t really know that code so it’s hard to say. Doesn’t seem like the browser if the first works though.