moment-timezone
moment-timezone copied to clipboard
Display issue on DST transition day
const moment1 = moment('2018-03-25')
.startOf('day')
.hour(12);
const moment2 = moment('2018-03-25')
.startOf('day')
.minute(12 * 60); // Here I'm adding 12 hours in minutes
Output:
moment1: Sun Mar 25 2018 12:00:00 GMT+0200
moment2: Sun Mar 25 2018 13:00:00 GMT+0200
2018-03-25 is the day when the summertime will be activated. Why is the output different? When using 2018-03-25 (the day after), both dates are exactly the same.
Is there a difference between using the .hour
and .minute
method?
Hi @guidsen! These methods - .hour()
and .minute()
are for setting hours and minutes exactly to values you provide, not for adding hours and minutes to the original date.
So, this
moment('2018-03-25').startOf('day').hour(12)
returns exactly 12:00 on Mar 25
Sun Mar 25 2018 12:00:00 GMT+0200
because explicitly provided .hour(12)
means that user wants exacly 12:00
local time.
To add hours or minutes, you should use .add()
. Functions .add(12, 'hour')
and .add(12 * 60, 'minute')
both return the same date - Sun Mar 25 2018 13:00:00 GMT+0200
Of course it's still confusing that that .minute()
behaves differently, but I think .minute()
was supposed to be used with values from 0 to 59
similar issue occurs with add
as well.
day.tz();
"America/Santiago"
day.format();
"2018-08-11T00:00:00-04:00" // shift day
day.add(1, 'day').format();
"2018-08-11T23:00:00-04:00"
The same issue that @Romanior mentioned is what I brought up here:
- https://github.com/moment/moment/issues/4743
The America/Santiago
timezone causes lots of issues in code, even infinite loops when certain assumptions are made.
Workaround for m.add(x, 'days'):
function switchZone(m, zone) {
let arr = [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second()];
if(zone) {
return moment.tz(arr, zone);
}
return moment(arr);
}
function safeAddDays(m, days) {
let oldZone = m.tz();
let utc = switchZone(m, 'UTC');
utc.add(days, 'days');
return switchZone(utc, oldZone);
}