Browse Source

Fixed #24980 -- Fixed day determination in admin calendar widget.

Alexander Gaevsky 9 năm trước cách đây
mục cha
commit
44930cc466

+ 4 - 1
django/contrib/admin/static/admin/js/core.js

@@ -240,7 +240,10 @@ function findPosY(obj) {
             }
             ++i;
         }
-        return new Date(year, month, day);
+        // Create Date object from UTC since the parsed value is supposed to be
+        // in UTC, not local time. Also, the calendar uses UTC functions for
+        // date extraction.
+        return new Date(Date.UTC(year, month, day));
     };
 
 })();

+ 4 - 0
docs/releases/1.8.9.txt

@@ -14,3 +14,7 @@ Bugfixes
 
 * Fixed a crash in the translations system when the current language has no
   translations (:ticket:`26046`).
+
+* Fixed a regression that caused the incorrect day to be selected when opening
+  the admin calendar widget for timezones from GMT+0100 to GMT+1200
+  (:ticket:`24980`).

+ 4 - 0
docs/releases/1.9.2.txt

@@ -17,3 +17,7 @@ Bugfixes
 
 * Fixed a crash in the translations system when the current language has no
   translations (:ticket:`26046`).
+
+* Fixed a regression that caused the incorrect day to be selected when opening
+  the admin calendar widget for timezones from GMT+0100 to GMT+1200
+  (:ticket:`24980`).

+ 43 - 3
js_tests/admin/core.test.js

@@ -57,7 +57,47 @@ test('Date.strftime', function(assert) {
 });
 
 test('String.strptime', function(assert) {
-    var date = new Date(1988, 1, 26);
-    assert.equal('1988-02-26'.strptime('%Y-%m-%d').toString(), date.toString());
-    assert.equal('26/02/88'.strptime('%d/%m/%y').toString(), date.toString());
+    // Use UTC functions for extracting dates since the calendar uses them as
+    // well. Month numbering starts with 0 (January).
+    var firstParsedDate = '1988-02-26'.strptime('%Y-%m-%d');
+    assert.equal(firstParsedDate.getUTCDate(), 26);
+    assert.equal(firstParsedDate.getUTCMonth(), 1);
+    assert.equal(firstParsedDate.getUTCFullYear(), 1988);
+
+    var secondParsedDate = '26/02/88'.strptime('%d/%m/%y');
+    assert.equal(secondParsedDate.getUTCDate(), 26);
+    assert.equal(secondParsedDate.getUTCMonth(), 1);
+    assert.equal(secondParsedDate.getUTCFullYear(), 1988);
+
+    var format = django.get_format('DATE_INPUT_FORMATS')[0];
+    var thirdParsedDate = '1983-11-20'.strptime(format);
+
+    assert.equal(thirdParsedDate.getUTCDate(), 20);
+    assert.equal(thirdParsedDate.getUTCMonth(), 10);
+    assert.equal(thirdParsedDate.getUTCFullYear(), 1983);
+
+    // Extracting from a Date object with local time must give the correct
+    // result. Without proper conversion, timezones from GMT+0100 to GMT+1200
+    // gives a date one day earlier than necessary, e.g. converting local time
+    // Feb 26, 1988 00:00:00 EEST is Feb 25, 21:00:00 UTC.
+
+    // Checking timezones from GMT+0100 to GMT+1200
+    var i, tz, date;
+    for (i = 1; i <= 12; i++) {
+        tz = i > 9 ? '' + i : '0' + i;
+        date = new Date(Date.parse('Feb 26, 1988 00:00:00 GMT+' + tz + '00'));
+        assert.notEqual(date.getUTCDate(), 26);
+        assert.equal(date.getUTCDate(), 25);
+        assert.equal(date.getUTCMonth(), 1);
+        assert.equal(date.getUTCFullYear(), 1988);
+    }
+
+    // Checking timezones from GMT+0000 to GMT-1100
+    for (i = 0; i <= 11; i++) {
+        tz = i > 9 ? '' + i : '0' + i;
+        date = new Date(Date.parse('Feb 26, 1988 00:00:00 GMT-' + tz + '00'));
+        assert.equal(date.getUTCDate(), 26);
+        assert.equal(date.getUTCMonth(), 1);
+        assert.equal(date.getUTCFullYear(), 1988);
+    }
 });