]> git.ipfire.org Git - thirdparty/moment.git/commitdiff
Fix local to utc/zone switching with keepLocalTime option 1738/head
authorIskren Chernev <iskren.chernev@gmail.com>
Thu, 26 Jun 2014 07:17:35 +0000 (00:17 -0700)
committerIskren Chernev <iskren.chernev@gmail.com>
Thu, 26 Jun 2014 07:39:19 +0000 (00:39 -0700)
moment.js
test/moment/zone_switching.js [new file with mode: 0644]

index ba5a6de8ba699235997d8425890f477bb43d620c..bcdf4ac8efc904fc9c2a0dacc83375ddae54cb1a 100644 (file)
--- a/moment.js
+++ b/moment.js
             return this._pf.overflow;
         },
 
-        utc : function () {
-            return this.zone(0);
+        utc : function (keepLocalTime) {
+            return this.zone(0, keepLocalTime);
         },
 
-        local : function () {
-            this.zone(0);
-            this._isUTC = false;
+        local : function (keepLocalTime) {
+            if (this._isUTC) {
+                this.zone(0, keepLocalTime);
+                this._isUTC = false;
+
+                if (keepLocalTime) {
+                    this.add(this._d.getTimezoneOffset(), 'm');
+                }
+            }
             return this;
         },
 
                 }
         ),
 
-        // keepTime = true means only change the timezone, without affecting
-        // the local hour. So 5:31:26 +0300 --[zone(2, true)]--> 5:31:26 +0200
-        // It is possible that 5:31:26 doesn't exist int zone +0200, so we
-        // adjust the time as needed, to be valid.
+        // keepLocalTime = true means only change the timezone, without
+        // affecting the local hour. So 5:31:26 +0300 --[zone(2, true)]-->
+        // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist int zone
+        // +0200, so we adjust the time as needed, to be valid.
         //
         // Keeping the time actually adds/subtracts (one hour)
         // from the actual represented time. That is why we call updateOffset
         // a second time. In case it wants us to change the offset again
         // _changeInProgress == true case, then we have to adjust, because
         // there is no such time in the given timezone.
-        zone : function (input, keepTime) {
-            var offset = this._offset || 0;
+        zone : function (input, keepLocalTime) {
+            var offset = this._offset || 0,
+                localAdjust;
             if (input != null) {
                 if (typeof input === "string") {
                     input = timezoneMinutesFromString(input);
                 if (Math.abs(input) < 16) {
                     input = input * 60;
                 }
+                if (!this._isUTC && keepLocalTime) {
+                    localAdjust = this._d.getTimezoneOffset();
+                }
                 this._offset = input;
                 this._isUTC = true;
+                if (localAdjust != null) {
+                    this.subtract(localAdjust, 'm');
+                }
                 if (offset !== input) {
-                    if (!keepTime || this._changeInProgress) {
+                    if (!keepLocalTime || this._changeInProgress) {
                         addOrSubtractDurationFromMoment(this,
                                 moment.duration(offset - input, 'm'), 1, false);
                     } else if (!this._changeInProgress) {
diff --git a/test/moment/zone_switching.js b/test/moment/zone_switching.js
new file mode 100644 (file)
index 0000000..f72cf8c
--- /dev/null
@@ -0,0 +1,115 @@
+var moment = require('../../moment');
+
+exports.zoneSwitching = {
+    setUp : function (done) {
+        moment.lang('en');
+        moment.createFromInputFallback = function () {
+            throw new Error("input not handled by moment");
+        };
+
+        done();
+    },
+
+    "local to utc, keepLocalTime = true" : function (test) {
+        var m = moment(),
+            fmt = "YYYY-DD-MM HH:mm:ss";
+        test.equal(m.clone().utc(true).format(fmt), m.format(fmt), "local to utc failed to keep local time");
+
+        test.done();
+    },
+
+    "local to utc, keepLocalTime = false" : function (test) {
+        var m = moment();
+        test.equal(m.clone().utc().valueOf(), m.valueOf(), "local to utc failed to keep utc time (implicit)");
+        test.equal(m.clone().utc(false).valueOf(), m.valueOf(), "local to utc failed to keep utc time (explicit)");
+
+        test.done();
+    },
+
+    "local to zone, keepLocalTime = true" : function (test) {
+        var m = moment(),
+            fmt = "YYYY-DD-MM HH:mm:ss",
+            z;
+
+        // Apparently there is -12:00 and +14:00
+        // http://en.wikipedia.org/wiki/UTC+14:00
+        // http://en.wikipedia.org/wiki/UTC-12:00
+        for (z = -12; z <= 14; ++z) {
+            test.equal(m.clone().zone(z * 60, true).format(fmt), m.format(fmt),
+                    "local to zone(" + z + ":00) failed to keep local time");
+        }
+
+        test.done();
+    },
+
+    "local to zone, keepLocalTime = false" : function (test) {
+        var m = moment(),
+            z;
+
+        // Apparently there is -12:00 and +14:00
+        // http://en.wikipedia.org/wiki/UTC+14:00
+        // http://en.wikipedia.org/wiki/UTC-12:00
+        for (z = -12; z <= 14; ++z) {
+            test.equal(m.clone().zone(z * 60).valueOf(), m.valueOf(),
+                    "local to zone(" + z + ":00) failed to keep utc time (implicit)");
+            test.equal(m.clone().zone(z * 60, false).valueOf(), m.valueOf(),
+                    "local to zone(" + z + ":00) failed to keep utc time (explicit)");
+        }
+
+        test.done();
+    },
+
+    "utc to local, keepLocalTime = true" : function (test) {
+        var um = moment.utc(),
+            fmt = "YYYY-DD-MM HH:mm:ss";
+
+        test.equal(um.clone().local(true).format(fmt), um.format(fmt), "utc to local failed to keep local time");
+
+        test.done();
+    },
+
+    "utc to local, keepLocalTime = false" : function (test) {
+        var um = moment.utc();
+        test.equal(um.clone().local().valueOf(), um.valueOf(), "utc to local failed to keep utc time (implicit)");
+        test.equal(um.clone().local(false).valueOf(), um.valueOf(), "utc to local failed to keep utc time (explicit)");
+
+        test.done();
+    },
+
+    "zone to local, keepLocalTime = true" : function (test) {
+        var m = moment(),
+            fmt = "YYYY-DD-MM HH:mm:ss",
+            z;
+
+        // Apparently there is -12:00 and +14:00
+        // http://en.wikipedia.org/wiki/UTC+14:00
+        // http://en.wikipedia.org/wiki/UTC-12:00
+        for (z = -12; z <= 14; ++z) {
+            m.zone(z * 60);
+
+            test.equal(m.clone().local(true).format(fmt), m.format(fmt),
+                    "zone(" + z + ":00) to local failed to keep the local time");
+        }
+
+        test.done();
+    },
+
+    "zone to local, keepLocalTime = false" : function (test) {
+        var m = moment(),
+            z;
+
+        // Apparently there is -12:00 and +14:00
+        // http://en.wikipedia.org/wiki/UTC+14:00
+        // http://en.wikipedia.org/wiki/UTC-12:00
+        for (z = -12; z <= 14; ++z) {
+            m.zone(z * 60);
+
+            test.equal(m.clone().local(false).valueOf(), m.valueOf(),
+                    "zone(" + z + ":00) to local failed to keep the local time (explicit)");
+            test.equal(m.clone().local().valueOf(), m.valueOf(),
+                    "zone(" + z + ":00) to local failed to keep the local time (implicit)");
+        }
+
+        test.done();
+    }
+};