diff --git a/moment-timezone.js b/moment-timezone.js index bd3f15b0..e93b51ff 100644 --- a/moment-timezone.js +++ b/moment-timezone.js @@ -161,6 +161,10 @@ } }, + getNextTransition : getNextTransition, + + getPreviousTransition : getPreviousTransition, + parse : function (timestamp) { var target = +timestamp, offsets = this.offsets, @@ -362,6 +366,34 @@ return cachedGuess; } + function getNextTransition (dateObject) { + var currentTimezone = guess(), + time = dateObject ? dateObject.valueOf() : Date.now(), + untils = getZone(currentTimezone).untils; + + for(var i = 0; i < untils.length; i++) { + if (untils[i] > time) { + return new moment(untils[i]); + } + } + } + + function getPreviousTransition (dateObject) { + var currentTimezone = guess(), + time = dateObject ? dateObject.valueOf() : Date.now(), + untils = getZone(currentTimezone).untils, + nextDSTIndex; + + for(var i = 0; i < untils.length; i++) { + if (untils[i] > time) { + nextDSTIndex = i; + break; + } + } + + return new moment(untils[nextDSTIndex - 1]); + } + /************************************ Global Methods ************************************/ @@ -510,6 +542,8 @@ tz.needsOffset = needsOffset; tz.moveInvalidForward = true; tz.moveAmbiguousForward = false; + tz.getNextTransition = getNextTransition; + tz.getPreviousTransition = getPreviousTransition; /************************************ Interface with Moment.js diff --git a/tests/moment-timezone/get-nearest-transition.js b/tests/moment-timezone/get-nearest-transition.js new file mode 100644 index 00000000..eae0f5ee --- /dev/null +++ b/tests/moment-timezone/get-nearest-transition.js @@ -0,0 +1,69 @@ +"use strict"; + +var tz = require("../../").tz; +var moment = require('../../index'); + +var guess = tz.prototype.guess; +var now = Date.prototype.now; + +exports.getNextTransition = { + setUp : function (done) { + tz.prototype.guess = 'America/New_York'; + Date.now = function() { return 1361481581996 }; + done(); + }, + + tearDown : function (done) { + tz.prototype.guess = guess; + Date.now = now; + done(); + }, + + "returns moment object with the date of next transition date relative to the moment or date object given as argument" : function (test) { + var resultWithDate = tz.getNextTransition(new Date(1461481581996)); + test.equal(resultWithDate.valueOf(), 1478412000000); + + var resultWithMoment = tz.getNextTransition(moment(1461481581996)); + test.equal(resultWithMoment.valueOf(), 1478412000000); + + test.done(); + }, + + "when no argument is given, returns moment object with the date of next transition date relative to current time" : function (test) { + var result = tz.getNextTransition(); + test.equal(result.valueOf(), 1362898800000); + + test.done(); + } +}; + +exports.getPreviousTransition = { + setUp : function (done) { + tz.prototype.guess = 'America/New_York'; + Date.now = function() { return 1361481581996 }; + done(); + }, + + tearDown : function (done) { + tz.prototype.guess = guess; + Date.now = now; + done(); + }, + + "returns moment object with the date of previous transition date relative to the moment or date object given as argument" : function (test) { + var resultWithDate = tz.getPreviousTransition(new Date(1461481581996)); + test.equal(resultWithDate.valueOf(), 1457852400000); + + var resultWithMoment = tz.getPreviousTransition(moment(1461481581996)); + test.equal(resultWithMoment.valueOf(), 1457852400000); + + test.done(); + }, + + "when no argument is given, returns moment object with the date of previous transition date relative to current time" : function (test) { + var result = tz.getPreviousTransition(); + test.equal(result.valueOf(), 1352008800000); + + test.done(); + } +}; diff --git a/tests/moment-timezone/zone.js b/tests/moment-timezone/zone.js index 8dac8c14..f9e7f412 100644 --- a/tests/moment-timezone/zone.js +++ b/tests/moment-timezone/zone.js @@ -1,6 +1,9 @@ "use strict"; var tz = require("../../").tz; +var guess = tz.prototype.guess; +var now = Date.prototype.now; +var moment = require('../../index'); // gE = 1000; 1E = 100; 2k = 140 var PACKED = "SomeZone|TIM TAM IAM|60.u 50 60|012101|gE 1E 2k 1E 2k"; @@ -11,12 +14,16 @@ exports.zone = { setUp : function (done) { moveAmbiguousForward = tz.moveAmbiguousForward; moveInvalidForward = tz.moveInvalidForward; + tz.prototype.guess = 'America/New_York'; + Date.now = function() { return 82400000 }; done(); }, tearDown : function (done) { tz.moveAmbiguousForward = moveAmbiguousForward; tz.moveInvalidForward = moveInvalidForward; + tz.prototype.guess = guess; + Date.now = now; done(); }, @@ -144,5 +151,35 @@ exports.zone = { } test.done(); - } + }, + + getNextTransition : function (test) { + var zone = new tz.Zone(PACKED); + + var resultWithDate = zone.getNextTransition(new Date(65000000)); + test.equal(resultWithDate.valueOf(), 66000000); + + var resultWithMoment = zone.getNextTransition(moment(65000000)); + test.equal(resultWithMoment.valueOf(), 66000000); + + var result = zone.getNextTransition(); + test.equal(result.valueOf(), 88800000); + + test.done(); + }, + + getPreviousTransition : function (test) { + var zone = new tz.Zone(PACKED); + + var resultWithDate = zone.getPreviousTransition(new Date(65000000)); + test.equal(resultWithDate.valueOf(), 60000000); + + var resultWithMoment = zone.getPreviousTransition(moment(65000000)); + test.equal(resultWithMoment.valueOf(), 60000000); + + var result = zone.getPreviousTransition(); + test.equal(result.valueOf(), 80400000); + + test.done(); + } };