]> git.ipfire.org Git - thirdparty/moment.git/commitdiff
Fix addOrSubtract to properly handle updateOffset
authorIskren Chernev <iskren.chernev@gmail.com>
Thu, 27 Mar 2014 09:55:57 +0000 (02:55 -0700)
committerIskren Chernev <iskren.chernev@gmail.com>
Sat, 29 Mar 2014 17:19:19 +0000 (10:19 -0700)
moment.js
test/moment/zones.js

index bc60d4e59dd057c7199e04aebcaf085012bcb50c..2e5da3d1224f500fecc760d689b5f13e9b9f5d69 100644 (file)
--- a/moment.js
+++ b/moment.js
     }
 
     // helper function for _.addTime and _.subtractTime
-    function addOrSubtractDurationFromMoment(mom, duration, isAdding, ignoreUpdateOffset) {
+    function addOrSubtractDurationFromMoment(mom, duration, isAdding, updateOffset) {
         var milliseconds = duration._milliseconds,
             days = duration._days,
-            months = duration._months,
-            minutes,
-            hours;
+            months = duration._months;
+        updateOffset = updateOffset == null ? true : updateOffset;
 
         if (milliseconds) {
             mom._d.setTime(+mom._d + milliseconds * isAdding);
         }
-        // store the minutes and hours so we can restore them
-        if (days || months) {
-            minutes = mom.minute();
-            hours = mom.hour();
-        }
         if (days) {
-            mom.date(mom.date() + days * isAdding);
+            rawSetter(mom, 'Date', rawGetter(mom, 'Date') + days * isAdding);
         }
         if (months) {
-            mom.month(mom.month() + months * isAdding);
+            rawMonthSetter(mom, rawGetter(mom, 'Month') + months * isAdding);
         }
-        if (milliseconds && !ignoreUpdateOffset) {
+        if (updateOffset) {
             moment.updateOffset(mom, days || months);
         }
-        // restore the minutes and hours after possibly changing dst
-        if (days || months) {
-            mom.minute(minutes);
-            mom.hour(hours);
-        }
     }
 
     // check if is an array
             }
         },
 
-        month : function (input) {
-            var utc = this._isUTC ? 'UTC' : '',
-                dayOfMonth;
-
-            if (input != null) {
-                if (typeof input === 'string') {
-                    input = this.lang().monthsParse(input);
-                    if (typeof input !== 'number') {
-                        return this;
-                    }
-                }
-
-                dayOfMonth = Math.min(this.date(),
-                        daysInMonth(this.year(), input));
-                this._d['set' + utc + 'Month'](input, dayOfMonth);
-                moment.updateOffset(this, true);
-                return this;
-            } else {
-                return this._d['get' + utc + 'Month']();
-            }
-        },
+        month : makeAccessor('Month', true),
 
         startOf: function (units) {
             units = normalizeUnits(units);
             return other > this ? this : other;
         },
 
-        zone : function (input, adjust) {
-            adjust = (adjust == null ? true : false);
+        // keepTime = true means only change the timezone, without affecting
+        // the local hour. So 5:31:26 +0300 --[zone(2, true)]--> 5:31:26 +0200
+        zone : function (input, keepTime) {
             var offset = this._offset || 0;
             if (input != null) {
                 if (typeof input === "string") {
                 }
                 this._offset = input;
                 this._isUTC = true;
-                if (offset !== input && adjust) {
-                    addOrSubtractDurationFromMoment(this, moment.duration(offset - input, 'm'), 1, true);
+                if (offset !== input && !keepTime) {
+                    addOrSubtractDurationFromMoment(this,
+                            moment.duration(offset - input, 'm'), 1, false);
                 }
             } else {
                 return this._isUTC ? offset : this._d.getTimezoneOffset();
         }, fn);
     }
 
+    function rawMonthSetter(mom, value) {
+        var dayOfMonth;
+
+        // TODO: Move this out of here!
+        if (typeof value === 'string') {
+            value = mom.lang().monthsParse(value);
+            // TODO: Another silent failure?
+            if (typeof value !== 'number') {
+                return mom;
+            }
+        }
+
+        dayOfMonth = Math.min(mom.date(),
+                daysInMonth(mom.year(), value));
+        mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
+        return mom;
+    }
+
     function rawGetter(mom, unit) {
-        var utc = mom._isUTC ? 'UTC' : '';
-        return mom._d['get' + utc + unit]();
+        return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]();
     }
 
     function rawSetter(mom, unit, value) {
-        var utc = mom._isUTC ? 'UTC' : '';
-        return mom._d['set' + utc + unit](value);
+        if (unit === 'Month') {
+            return rawMonthSetter(mom, value);
+        } else {
+            return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
+        }
     }
 
-    function makeAccessor(unit, noDSTAdjust) {
+    function makeAccessor(unit, keepTime) {
         return function (value) {
             if (value != null) {
                 rawSetter(this, unit, value);
-                moment.updateOffset(this, noDSTAdjust);
+                moment.updateOffset(this, keepTime);
                 return this;
             } else {
                 return rawGetter(this, unit);
index cd203f6321e2576cf363f97752c8c8d9bf9ef157..f88e62901ad42b0440d1e0b00e54c7f0341d1f1c 100644 (file)
@@ -127,12 +127,12 @@ exports.zones = {
         var oldOffset = moment.updateOffset,
             m = moment.utc([2000, 6, 1]);
 
-        moment.updateOffset = function (mom) {
+        moment.updateOffset = function (mom, keepTime) {
             if (mom.__doChange) {
                 if (+mom > 962409600000) {
-                    mom.zone(120);
+                    mom.zone(120, keepTime);
                 } else {
-                    mom.zone(60);
+                    mom.zone(60, keepTime);
                 }
             }
         };
@@ -333,11 +333,11 @@ exports.zones = {
         var oldOffset = moment.updateOffset,
             m = moment.utc([2000, 2, 31, 3]);
 
-        moment.updateOffset = function (mom) {
+        moment.updateOffset = function (mom, keepTime) {
             if (mom.clone().utc().month() > 2) {
-                mom.zone(-60);
+                mom.zone(-60, keepTime);
             } else {
-                mom.zone(0);
+                mom.zone(0, keepTime);
             }
         };
 
@@ -375,11 +375,11 @@ exports.zones = {
     "isDST" : function (test) {
         var oldOffset = moment.updateOffset;
 
-        moment.updateOffset = function (mom) {
+        moment.updateOffset = function (mom, keepTime) {
             if (mom.month() > 2 && mom.month() < 9) {
-                mom.zone(-60);
+                mom.zone(-60, keepTime);
             } else {
-                mom.zone(0);
+                mom.zone(0, keepTime);
             }
         };