moment-timezone
moment-timezone copied to clipboard
Inconsistent date result between constructor and set methods around DST switch
I was debugging a bug recently and realized that depending on how I create a moment I get different results. Apparently the logic used by the setters is different than the constructor arguments. This seems like a bug?
const timezone = 'Asia/Beirut';
const first = moment.tz([2020, 2, 29], timezone).toDate();
const second = moment.tz([1900, 0, 1], timezone).year(2020).month(2).date(29).toDate();
console.log('first', first); // first 2020-03-28T22:00:00.000Z
console.log('second', second); // second 2020-03-28T21:00:00.000Z
console.log('date of first', moment.tz(first, timezone).date()); // 29
console.log('date of first', moment.tz(second, timezone).date()); // 28
[email protected] moment-timezone@^0.5.28
It is a bit hard to work around generically since the get methods are a much more forgiving when it comes to handling offsets/bubbling/rollover
@jason-codaio I believe this is due to DST change on March 29, 2020 at this timezone, and maybe some weirdness behind date set. When you set year, month, date on a moment object, it actually does some math to add the time to create the new date.

Luxon handles it correctly, and they explains the math for DST very well.

OK, there is a serious bug in there, this timezone skips midnight on 29th Mar, so 23:59:59 -> 01:00:00, so the first
object is correct, and the second one is messed up beyond repair. Will need to investigate:
> moment.tz([1900, 0, 1], timezone).year(2020).month(2).date(29).format()
'2020-03-29T00:00:00+03:00'
> moment.tz([1900, 0, 1], timezone).year(2020).month(2).date(29).add(1, 'min').format()
'2020-03-28T23:00:00+02:00'
> moment.tz([1900, 0, 1], timezone).year(2020).month(2).date(29).add(-1, 'min').format()
'2020-03-28T23:00:00+02:00'
> moment.tz([1900, 0, 1], timezone).year(2020).month(2).date(29).add(-10, 'min').format()
'2020-03-28T23:00:00+02:00'
> moment.tz([1900, 0, 1], timezone).year(2020).month(2).date(29).add(-20, 'min').format()
'2020-03-28T23:00:00+02:00'