]> git.ipfire.org Git - thirdparty/moment.git/commitdiff
Fix rfc2822 multiple issues
authorIskren Chernev <iskren.chernev@gmail.com>
Mon, 7 Aug 2017 21:38:17 +0000 (00:38 +0300)
committerIskren Chernev <iskren.chernev@gmail.com>
Mon, 7 Aug 2017 21:38:17 +0000 (00:38 +0300)
src/lib/create/from-string.js
src/test/moment/create.js

index d7081e0854eb20ea1fb06b7031a23e7dc2ee1d6e..7c1052a3e479067f661a7eeb595f0dc397083ac7 100644 (file)
@@ -1,4 +1,5 @@
 import { configFromStringAndFormat } from './from-string-and-format';
+import { createUTCDate } from './date-from-array';
 import { configFromArray } from './from-array';
 import { hooks } from '../utils/hooks';
 import { deprecate } from '../utils/deprecate';
@@ -97,7 +98,7 @@ export function configFromISO(config) {
 }
 
 // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
-var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|(?:([+-]\d\d)(\d\d)))$/;
+var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/;
 
 function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {
     var result = [
@@ -130,13 +131,6 @@ function preprocessRFC2822(s) {
     return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').trim();
 }
 
-function signedOffset(offHourStr, offMinuteStr) {
-    var offHour = parseInt(offHourStr, 10) || 0,
-        offMin = parseInt(offMinuteStr, 10) || 0,
-        offMinSigned = offHour < 0 ? -offMin : offMin;
-    return offHour * 60 + offMinSigned;
-}
-
 function checkWeekday(weekdayStr, parsedInput, config) {
     if (weekdayStr) {
         // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.
@@ -152,22 +146,28 @@ function checkWeekday(weekdayStr, parsedInput, config) {
 }
 
 var obsOffsets = {
+    UT: 0,
     GMT: 0,
     EDT: -4 * 60,
     EST: -5 * 60,
-    CDT: 5 * 60,
-    CST: 6 * 60,
-    MDT: 6 * 60,
-    MST: 7 * 60,
-    PDT: 7 * 60,
-    PST: 8 * 60
+    CDT: -5 * 60,
+    CST: -6 * 60,
+    MDT: -6 * 60,
+    MST: -7 * 60,
+    PDT: -7 * 60,
+    PST: -8 * 60
 };
 
-function calculateOffset(obsOffset, milOffset, offHourStr, offMinuteStr) {
+function calculateOffset(obsOffset, militaryOffset, numOffset) {
     if (obsOffset) {
         return obsOffsets[obsOffset];
+    } else if (militaryOffset) {
+        // the only allowed military tz is Z
+        return 0;
     } else {
-        return (milOffset) ? 0 : signedOffset(offHourStr, offMinuteStr);
+        var hm = parseInt(numOffset, 10);
+        var m = hm % 100, h = (hm - m) / 100;
+        return h * 60 + m;
     }
 }
 
@@ -181,9 +181,11 @@ export function configFromRFC2822(config) {
         }
 
         config._a = parsedArray;
-        config._tzm = calculateOffset(match[8], match[9], match[10], match[11]);
+        config._tzm = calculateOffset(match[8], match[9], match[10]);
+
+        config._d = createUTCDate.apply(null, config._a);
+        config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
 
-        configFromArray(config);
         getParsingFlags(config).rfc2822 = true;
     } else {
         config._isValid = false;
index cc29957d202b1ff1745a4894ba2b5e7af5eceecd..652e0cf9073db77e9d9904a1490ed6b3f938d3d0 100644 (file)
@@ -456,34 +456,50 @@ test('cloning carrying over utc mode', function (assert) {
 
 test('parsing RFC 2822', function (assert) {
     var testCases = {
-        'clean RFC2822 datetime with all options': 'Tue, 01 Nov 2016 01:23:45 UT',
-        'clean RFC2822 datetime without comma': 'Tue 01 Nov 2016 02:23:45 GMT',
-        'clean RFC2822 datetime without seconds': 'Tue, 01 Nov 2016 03:23 +0000',
-        'clean RFC2822 datetime without century': 'Tue, 01 Nov 16 04:23:45 Z',
-        'clean RFC2822 datetime without day': '01 Nov 2016 05:23:45 z',
-        'clean RFC2822 datetime with single-digit day-of-month': 'Tue, 1 Nov 2016 06:23:45 GMT',
-        'RFC2822 datetime with CFWSs': '(Init Comment) Tue,\n 1 Nov              2016 (Split\n Comment)  07:23:45 +0000 (GMT)'
+        'Tue, 01 Nov 2016 01:23:45 UT': [2016, 10, 1, 1, 23, 45, 0],
+        'Sun, 12 Apr 2015 05:06:07 GMT': [2015, 3, 12, 5, 6, 7, 0],
+        'Tue, 01 Nov 2016 01:23:45 +0000': [2016, 10, 1, 1, 23, 45, 0],
+        'Tue, 01 Nov 16 04:23:45 Z': [2016, 10, 1, 4, 23, 45, 0],
+        '01 Nov 2016 05:23:45 z': [2016, 10, 1, 5, 23, 45, 0],
+        '(Init Comment) Tue,\n 1 Nov              2016 (Split\n Comment)  07:23:45 +0000 (GMT)': [2016, 10, 1, 7, 23, 45, 0],
+        'Mon, 02 Jan 2017 06:00:00 -0800': [2017, 0, 2, 6, 0, 0, -8 * 60],
+        'Mon, 02 Jan 2017 06:00:00 +0800': [2017, 0, 2, 6, 0, 0, +8 * 60],
+        'Mon, 02 Jan 2017 06:00:00 +0330': [2017, 0, 2, 6, 0, 0, + (3 * 60 + 30)],
+        'Mon, 02 Jan 2017 06:00:00 -0330': [2017, 0, 2, 6, 0, 0, - (3 * 60 + 30)],
+        'Mon, 02 Jan 2017 06:00:00 PST': [2017, 0, 2, 6, 0, 0, -8 * 60],
+        'Mon, 02 Jan 2017 06:00:00 PDT': [2017, 0, 2, 6, 0, 0, -7 * 60],
+        'Mon, 02 Jan 2017 06:00:00 MST': [2017, 0, 2, 6, 0, 0, -7 * 60],
+        'Mon, 02 Jan 2017 06:00:00 MDT': [2017, 0, 2, 6, 0, 0, -6 * 60],
+        'Mon, 02 Jan 2017 06:00:00 CST': [2017, 0, 2, 6, 0, 0, -6 * 60],
+        'Mon, 02 Jan 2017 06:00:00 CDT': [2017, 0, 2, 6, 0, 0, -5 * 60],
+        'Mon, 02 Jan 2017 06:00:00 EST': [2017, 0, 2, 6, 0, 0, -5 * 60],
+        'Mon, 02 Jan 2017 06:00:00 EDT': [2017, 0, 2, 6, 0, 0, -4 * 60],
     };
-    var testCase;
 
-    for (testCase in testCases) {
-        var testResult = moment(testCases[testCase], moment.RFC_2822, true);
-        assert.ok(testResult.isValid(), testResult);
-        assert.ok(testResult.parsingFlags().rfc2822, testResult + ' - rfc2822 parsingFlag');
+    var inp, tokens;
+
+    for (inp in testCases) {
+        var tokens = testCases[inp];
+        var parseResult = moment(inp, moment.RFC_2822, true).parseZone();
+        var expResult = moment.utc(tokens.slice(0, 6)).utcOffset(tokens[6], true);
+        assert.ok(parseResult.isValid(), inp);
+        assert.ok(parseResult.parsingFlags().rfc2822, inp + ' - rfc2822 parsingFlag');
+        assert.equal(parseResult.utcOffset(), expResult.utcOffset(), inp + ' - zone');
+        assert.equal(parseResult.valueOf(), expResult.valueOf(), inp + ' - correctness');
     }
 });
 
 test('non RFC 2822 strings', function (assert) {
     var testCases = {
         'RFC2822 datetime with all options but invalid day delimiter': 'Tue. 01 Nov 2016 01:23:45 GMT',
-        'RFC2822 datetime with mismatching Day (week v date)': 'Mon, 01 Nov 2016 01:23:45 GMT'
+        'RFC2822 datetime with mismatching Day (weekday v date)': 'Mon, 01 Nov 2016 01:23:45 GMT'
     };
     var testCase;
 
     for (testCase in testCases) {
         var testResult = moment(testCases[testCase], moment.RFC_2822, true);
-        assert.ok(!testResult.isValid(), testResult);
-        assert.ok(!testResult.parsingFlags().rfc2822, testResult + ' - rfc2822 parsingFlag');
+        assert.ok(!testResult.isValid(), testCase + ': ' + testResult + ' - is invalid rfc2822');
+        assert.ok(!testResult.parsingFlags().rfc2822, testCase + ': ' + testResult + ' - rfc2822 parsingFlag');
     }
 });