From: Iskren Chernev Date: Sat, 29 Mar 2014 17:17:50 +0000 (-0700) Subject: Fix startOf issues across DST with updateOffset X-Git-Tag: 2.6.0~15^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3dd80ba2891a304511fb83da0ffb0ffa343b84c8;p=thirdparty%2Fmoment.git Fix startOf issues across DST with updateOffset --- diff --git a/moment.js b/moment.js index ee47cb120..df35d87aa 100644 --- a/moment.js +++ b/moment.js @@ -2224,7 +2224,11 @@ moment.fn.millisecond = moment.fn.milliseconds = makeAccessor('Milliseconds', false); moment.fn.second = moment.fn.seconds = makeAccessor('Seconds', false); moment.fn.minute = moment.fn.minutes = makeAccessor('Minutes', false); - moment.fn.hour = moment.fn.hours = makeAccessor('Hours', false); + // Setting the hour should keep the time, because the user explicitly + // specified which hour he wants. So trying to maintain the same hour (in + // a new timezone) makes sense. Adding/subtracting hours does not follow + // this rule. + moment.fn.hour = moment.fn.hours = makeAccessor('Hours', true); // moment.fn.month is defined separately moment.fn.date = makeAccessor('Date', true); moment.fn.dates = deprecate("dates accessor is deprecated. Use date instead.", makeAccessor('Date', true)); diff --git a/test/moment/sod_eod.js b/test/moment/sod_eod.js index 17b928956..6e8dcc3bf 100644 --- a/test/moment/sod_eod.js +++ b/test/moment/sod_eod.js @@ -300,6 +300,88 @@ exports.end_start_of = { test.equal(m.minutes(), 4, "keep the minutes"); test.equal(m.seconds(), 5, "keep the seconds"); test.equal(m.milliseconds(), 999, "set the seconds"); + test.done(); + }, + + "startOf across DST +1" : function (test) { + var oldUpdateOffset = moment.updateOffset, + // Based on a real story somewhere in America/Los_Angeles + dstAt = moment("2014-03-09T02:00:00-08:00").parseZone(), + m; + + moment.updateOffset = function (mom, keepTime) { + if (mom.isBefore(dstAt)) { + mom.zone(8, keepTime); + } else { + mom.zone(7, keepTime); + } + } + + m = moment("2014-03-15T00:00:00-07:00").parseZone(); + m.startOf('M') + test.equal(m.format(), "2014-03-01T00:00:00-08:00", + "startOf('month') across +1"); + + m = moment("2014-03-09T09:00:00-07:00").parseZone(); + m.startOf('d'); + test.equal(m.format(), "2014-03-09T00:00:00-08:00", + "startOf('day') across +1"); + + m = moment("2014-03-09T03:05:00-07:00").parseZone(); + m.startOf('h'); + test.equal(m.format(), "2014-03-09T03:00:00-07:00", + "startOf('hour') after +1"); + + m = moment("2014-03-09T01:35:00-08:00").parseZone(); + m.startOf('h'); + test.equal(m.format(), "2014-03-09T01:00:00-08:00", + "startOf('hour') before +1"); + + // There is no such time as 2:30-7 to try startOf('hour') across that + + moment.updateOffset = oldUpdateOffset; + + test.done(); + }, + + "startOf across DST -1" : function (test) { + var oldUpdateOffset = moment.updateOffset, + // Based on a real story somewhere in America/Los_Angeles + dstAt = moment("2014-11-02T02:00:00-07:00").parseZone(), + m; + + moment.updateOffset = function (mom, keepTime) { + if (mom.isBefore(dstAt)) { + mom.zone(7, keepTime); + } else { + mom.zone(8, keepTime); + } + } + + m = moment("2014-11-15T00:00:00-08:00").parseZone(); + m.startOf('M') + test.equal(m.format(), "2014-11-01T00:00:00-07:00", + "startOf('month') across -1"); + + m = moment("2014-11-02T09:00:00-08:00").parseZone(); + m.startOf('d'); + test.equal(m.format(), "2014-11-02T00:00:00-07:00", + "startOf('day') across -1"); + + // note that zone is -8 + m = moment("2014-11-02T01:30:00-08:00").parseZone(); + m.startOf('h'); + test.equal(m.format(), "2014-11-02T01:00:00-08:00", + "startOf('hour') after +1"); + + // note that zone is -7 + m = moment("2014-11-02T01:30:00-07:00").parseZone(); + m.startOf('h'); + test.equal(m.format(), "2014-11-02T01:00:00-07:00", + "startOf('hour') before +1"); + + moment.updateOffset = oldUpdateOffset; + test.done(); } };