]> git.ipfire.org Git - thirdparty/moment.git/commitdiff
Fix months parsing for stranger locales
authorIskren Chernev <iskren.chernev@gmail.com>
Wed, 6 Jan 2016 23:44:36 +0000 (01:44 +0200)
committerIskren Chernev <iskren.chernev@gmail.com>
Sat, 9 Jan 2016 12:41:25 +0000 (14:41 +0200)
src/lib/locale/prototype.js
src/lib/parse/regex.js
src/lib/units/month.js
src/locale/gd.js
src/test/locale/gd.js

index ed02d4f3b0b5251757c061a6de094c7a8d5e389f..6c59d5edbe4f995e2ebb88aa915b85fbb44f1b7c 100644 (file)
@@ -30,14 +30,22 @@ proto.set             = set;
 import {
     localeMonthsParse,
     defaultLocaleMonths,      localeMonths,
-    defaultLocaleMonthsShort, localeMonthsShort
+    defaultLocaleMonthsShort, localeMonthsShort,
+    defaultMonthsRegex,       monthsRegex,
+    defaultMonthsShortRegex,  monthsShortRegex,
+    computeMonthsParse
 } from '../units/month';
 
-proto.months       =        localeMonths;
-proto._months      = defaultLocaleMonths;
-proto.monthsShort  =        localeMonthsShort;
-proto._monthsShort = defaultLocaleMonthsShort;
-proto.monthsParse  =        localeMonthsParse;
+proto.months            =        localeMonths;
+proto._months           = defaultLocaleMonths;
+proto.monthsShort       =        localeMonthsShort;
+proto._monthsShort      = defaultLocaleMonthsShort;
+proto.monthsParse       =        localeMonthsParse;
+proto._monthsRegex      = defaultMonthsRegex;
+proto.monthsRegex       = monthsRegex;
+proto._monthsShortRegex = defaultMonthsShortRegex;
+proto.monthsShortRegex  = monthsShortRegex;
+proto._computeMonthsParse = computeMonthsParse;
 
 // Week
 import { localeWeek, defaultLocaleWeek, localeFirstDayOfYear, localeFirstDayOfWeek } from '../units/week';
index a168de6f25dff8de381202c95981c35f42a8313d..b1dc7529e5c7e2e182191f382217c62da6b16aa8 100644 (file)
@@ -20,7 +20,7 @@ export var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123
 
 // any word (or two) characters or numbers including two/three word month in arabic.
 // includes scottish gaelic two word and hyphenated months
-export var matchWord = /[0-9]*(a[mn]\s?)?['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF\-]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i;
+export var matchWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i;
 
 
 import hasOwnProp from '../utils/has-own-prop';
@@ -29,7 +29,7 @@ import isFunction from '../utils/is-function';
 var regexes = {};
 
 export function addRegexToken (token, regex, strictRegex) {
-    regexes[token] = isFunction(regex) ? regex : function (isStrict) {
+    regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {
         return (isStrict && strictRegex) ? strictRegex : regex;
     };
 }
@@ -44,7 +44,11 @@ export function getParseRegexForToken (token, config) {
 
 // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
 function unescapeFormat(s) {
-    return s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
+    return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
         return p1 || p2 || p3 || p4;
-    }).replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
+    }));
+}
+
+export function regexEscape(s) {
+    return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
 }
index 18e42cff834c8e1f4abd1939279d3977b0569734..7d323471791d9aa68ca50be1fea23126b010de57 100644 (file)
@@ -1,7 +1,8 @@
 import { get } from '../moment/get-set';
+import hasOwnProp from '../utils/has-own-prop';
 import { addFormatToken } from '../format/format';
 import { addUnitAlias } from './aliases';
-import { addRegexToken, match1to2, match2, matchWord } from '../parse/regex';
+import { addRegexToken, match1to2, match2, matchWord, regexEscape } from '../parse/regex';
 import { addParseToken } from '../parse/token';
 import { hooks } from '../utils/hooks';
 import { MONTH } from './constants';
@@ -36,8 +37,12 @@ addUnitAlias('month', 'M');
 
 addRegexToken('M',    match1to2);
 addRegexToken('MM',   match1to2, match2);
-addRegexToken('MMM',  matchWord);
-addRegexToken('MMMM', matchWord);
+addRegexToken('MMM',  function (isStrict, locale) {
+    return locale.monthsShortRegex(isStrict);
+});
+addRegexToken('MMMM', function (isStrict, locale) {
+    return locale.monthsRegex(isStrict);
+});
 
 addParseToken(['M', 'MM'], function (input, array) {
     array[MONTH] = toInt(input) - 1;
@@ -136,3 +141,54 @@ export function getSetMonth (value) {
 export function getDaysInMonth () {
     return daysInMonth(this.year(), this.month());
 }
+
+export var defaultMonthsShortRegex = matchWord;
+export function monthsShortRegex (isStrict) {
+    if (this._monthsParseExact) {
+        this._computeMonthsParse();
+        if (isStrict) {
+            return this._monthsShortStrictRegex;
+        } else {
+            return this._monthsShortRegex;
+        }
+    } else {
+        return this._monthsShortStrictRegex && isStrict ?
+            this._monthsShortStrictRegex : this._monthsShortRegex;
+    }
+}
+
+export var defaultMonthsRegex = matchWord;
+export function monthsRegex (isStrict) {
+    if (this._monthsParseExact) {
+        this._computeMonthsParse();
+        if (isStrict) {
+            return this._monthsStrictRegex;
+        } else {
+            return this._monthsRegex;
+        }
+    } else {
+        return this._monthsStrictRegex && isStrict ?
+            this._monthsStrictRegex : this._monthsRegex;
+    }
+}
+
+export function computeMonthsParse () {
+    if (!hasOwnProp(this, '_monthsRegex')) {
+        var shortOnly = '', longOnly = '', mixed = '', i, mom;
+        for (i = 0; i < 12; i++) {
+            // make the regex if we don't have it already
+            mom = createUTC([2000, i]);
+            shortOnly += '|' + regexEscape(this.monthsShort(mom, ''));
+            longOnly += '|' + regexEscape(this.months(mom, ''));
+            mixed += '|' + regexEscape(this.months(mom, '')) + '|' + regexEscape(this.monthsShort(mom, ''));
+        }
+        shortOnly = shortOnly.substr(1);
+        longOnly = longOnly.substr(1);
+        mixed = mixed.substr(1);
+
+        this._monthsRegex = new RegExp('^(' + mixed + ')', 'i');
+        this._monthsShortRegex = this._monthsRegex;
+        this._monthsStrictRegex = new RegExp('^(' + longOnly + ')$', 'i');
+        this._monthsShortStrictRegex = new RegExp('^(' + shortOnly + ')$', 'i');
+    }
+}
index d4fdff1800a8f893eae5c7554dd119d50d24504d..b7689f98a34de11bf7156c681c9311d0c851870b 100644 (file)
@@ -5,18 +5,7 @@
 import moment from '../moment';
 
 var months = [
-    'Am Faoilleach',
-    'An Gearran',
-    'Am Màrt',
-    'An Giblean',
-    'An Cèitean',
-    'An t-Ògmhios',
-    'An t-Iuchar',
-    'An Lùnastal',
-    'An t-Sultain',
-    'An Dàmhair',
-    'An t-Samhain',
-    'An Dùbhlachd'
+    'Am Faoilleach', 'An Gearran', 'Am Màrt', 'An Giblean', 'An Cèitean', 'An t-Ògmhios', 'An t-Iuchar', 'An Lùnastal', 'An t-Sultain', 'An Dàmhair', 'An t-Samhain', 'An Dùbhlachd'
 ];
 
 var monthsShort = ['Faoi', 'Gear', 'Màrt', 'Gibl', 'Cèit', 'Ògmh', 'Iuch', 'Lùn', 'Sult', 'Dàmh', 'Samh', 'Dùbh'];
@@ -30,6 +19,7 @@ var weekdaysMin = ['Dò', 'Lu', 'Mà', 'Ci', 'Ar', 'Ha', 'Sa'];
 export default moment.defineLocale('gd', {
     months : months,
     monthsShort : monthsShort,
+    monthsParseExact : true,
     weekdays : weekdays,
     weekdaysShort : weekdaysShort,
     weekdaysMin : weekdaysMin,
index 583d574dd958aec805f6b90c2c51b278bf192e0c..b3d468fd62a867ad04c6b29f88fc2b092dfd0dd4 100644 (file)
@@ -19,7 +19,7 @@ var months = [
 
 test('parse', function (assert) {
     function equalTest(monthName, monthFormat, monthNum) {
-        assert.equal(moment(monthName, monthFormat).month(), monthNum, monthName + ' should be month ' + monthNum + 1);
+        assert.equal(moment(monthName, monthFormat).month(), monthNum, monthName + ' should be month ' + (monthNum + 1));
     }
 
     for (var i = 0; i < 12; i++) {