From: Tim Wood Date: Wed, 7 Sep 2011 21:33:15 +0000 (-0700) Subject: _date(input, format) can now accept an array of formats as the second parameter. X-Git-Tag: 0.6.0~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a1365730c3de1b27f2a52e20c14eb5a3a28c66d2;p=thirdparty%2Fmoment.git _date(input, format) can now accept an array of formats as the second parameter. --- diff --git a/test/date.js b/test/date.js index cb8f7cddd..9041994f4 100755 --- a/test/date.js +++ b/test/date.js @@ -4,7 +4,7 @@ var _date, _; if (typeof window === 'undefined') { - _date = require('underscore.date'); + _date = require('../underscore.date.js'); module = QUnit.module; _ = { date : _date }; } @@ -71,6 +71,12 @@ test("string with format", 11, function() { } }); +test("string with array of formats", 3, function() { + equal(_date('13-02-1999', ['MM-DD-YYYY', 'DD-MM-YYYY']).format('MM DD YYYY'), '02 13 1999', 'switching month and day'); + equal(_date('02-13-1999', ['MM/DD/YYYY', 'YYYY-MM-DD', 'MM-DD-YYYY']).format('MM DD YYYY'), '02 13 1999', 'year last'); + equal(_date('1999-02-13', ['MM/DD/YYYY', 'YYYY-MM-DD', 'MM-DD-YYYY']).format('MM DD YYYY'), '02 13 1999', 'year first'); +}); + test("string with format - years", 2, function() { equal(_date('71', 'YY').format('YYYY'), '1971', '71 > 1971'); equal(_date('69', 'YY').format('YYYY'), '2069', '69 > 2069'); diff --git a/test/speed.js b/test/speed.js deleted file mode 100755 index 91641e346..000000000 --- a/test/speed.js +++ /dev/null @@ -1,30 +0,0 @@ -var date = new Date(), - new_date = _date(); - -JSLitmus.test('create from date', function() { - return _date(date); -}); - -JSLitmus.test('create from _date', function() { - return _date(new_date); -}); - -JSLitmus.test('create from undefined', function() { - return _date(); -}); - -JSLitmus.test('create from number', function() { - return _date(100000); -}); - -JSLitmus.test('create from string', function() { - return _date("Mon, 25 Dec 1995 13:30:00 GMT"); -}); - -JSLitmus.test('create from array', function() { - return _date([2010, 2, 6, 15, 25, 50, 125]); -}); - -JSLitmus.test('create from string with format', function() { - return _date("12-02-1999 2:45:10", "DD-MM-YYYY h:m:s"); -}); diff --git a/test/test.html b/test/test.html index 972d4cd6f..d573214b6 100755 --- a/test/test.html +++ b/test/test.html @@ -6,10 +6,9 @@ - + -
diff --git a/underscore.date.js b/underscore.date.js index 53253d39b..dfcf2243d 100644 --- a/underscore.date.js +++ b/underscore.date.js @@ -56,6 +56,122 @@ return new Date(input[0], input[1] || 0, input[2] || 1, input[3] || 0, input[4] || 0, input[5] || 0, input[6] || 0); } + // format date using native date object + function formatDate(date, inputString) { + var currentMonth = date.getMonth(), + currentDate = date.getDate(), + currentYear = date.getFullYear(), + currentDay = date.getDay(), + currentHours = date.getHours(), + currentMinutes = date.getMinutes(), + currentSeconds = date.getSeconds(), + currentString = date.toString(), + charactersToReplace = /(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|dddd?|do?|w[o|w]?|YYYY|YY|a|A|hh?|HH?|mm?|ss?|zz?)/g, + nonuppercaseLetters = /[^A-Z]/g; + // check if the character is a format + // return formatted string or non string. + // + // uses switch/case instead of an object of named functions (like http://phpjs.org/functions/date:380) + // for minification and performance + // see http://jsperf.com/object-of-functions-vs-switch for performance comparison + function replaceFunction(input) { + // create a couple variables to be used later inside one of the cases. + var a, b; + switch (input) { + // MONTH + case 'M' : + return currentMonth + 1; + case 'Mo' : + return (currentMonth + 1) + _date.ordinal(currentMonth + 1); + case 'MM' : + return leftZeroFill(currentMonth + 1, 2); + case 'MMM' : + return _date.monthsShort[currentMonth]; + case 'MMMM' : + return _date.months[currentMonth]; + // DAY OF MONTH + case 'D' : + return currentDate; + case 'Do' : + return currentDate + _date.ordinal(currentDate); + case 'DD' : + return leftZeroFill(currentDate, 2); + // DAY OF YEAR + case 'DDD' : + a = new Date(currentYear, currentMonth, currentDate); + b = new Date(currentYear, 0, 1); + return ~~ (((a - b) / 864e5) + 1.5); + case 'DDDo' : + a = replaceFunction('DDD'); + return a + _date.ordinal(a); + case 'DDDD' : + return leftZeroFill(replaceFunction('DDD'), 3); + // WEEKDAY + case 'd' : + return currentDay; + case 'do' : + return currentDay + _date.ordinal(currentDay); + case 'ddd' : + return _date.weekdaysShort[currentDay]; + case 'dddd' : + return _date.weekdays[currentDay]; + // WEEK OF YEAR + case 'w' : + a = new Date(currentYear, currentMonth, currentDate - currentDay + 5); + b = new Date(a.getFullYear(), 0, 4); + return ~~ ((a - b) / 864e5 / 7 + 1.5); + case 'wo' : + a = replaceFunction('w'); + return a + _date.ordinal(a); + case 'ww' : + return leftZeroFill(replaceFunction('w'), 2); + // YEAR + case 'YY' : + return (currentYear + '').slice(-2); + case 'YYYY' : + return currentYear; + // AM / PM + case 'a' : + return currentHours > 11 ? 'pm' : 'am'; + case 'A' : + return currentHours > 11 ? 'PM' : 'AM'; + // 24 HOUR + case 'H' : + return currentHours; + case 'HH' : + return leftZeroFill(currentHours, 2); + // 12 HOUR + case 'h' : + return currentHours % 12 || 12; + case 'hh' : + return leftZeroFill(currentHours % 12 || 12, 2); + // MINUTE + case 'm' : + return currentMinutes; + case 'mm' : + return leftZeroFill(currentMinutes, 2); + // SECOND + case 's' : + return currentSeconds; + case 'ss' : + return leftZeroFill(currentSeconds, 2); + // TIMEZONE + case 'z' : + return replaceFunction('zz').replace(nonuppercaseLetters, ''); + case 'zz' : + a = currentString.indexOf('('); + if (a > -1) { + return currentString.slice(a + 1, currentString.indexOf(')')); + } + return currentString.slice(currentString.indexOf(':')).replace(nonuppercaseLetters, ''); + // DEFAULT + default : + return input.replace("\\", ""); + } + } + return inputString.replace(charactersToReplace, replaceFunction); + } + // date from string and format string function makeDateFromStringAndFormat(string, format) { var inArray = [0], @@ -132,6 +248,41 @@ return dateFromArray(inArray); } + // compare two arrays, return the number of differences + function compareArrays(array1, array2) { + var len = Math.min(array1.length, array2.length), + lengthDiff = Math.abs(array1.length - array2.length), + diffs = 0, + i; + for (i = 0; i < len; i++) { + if (~~array1[i] !== ~~array2[i]) { + diffs++; + } + } + return diffs + lengthDiff; + } + + // date from string and array of format strings + function makeDateFromStringAndArray(string, formats) { + var output, + charactersToPutInArray = /[0-9a-zA-Z]+/g, + inputParts = string.match(charactersToPutInArray), + scores = [], + scoreToBeat = 99, + i, + curDate, + curScore; + for (i = 0; i < formats.length; i++) { + curDate = makeDateFromStringAndFormat(string, formats[i]); + curScore = compareArrays(inputParts, formatDate(curDate, formats[i]).match(charactersToPutInArray)); + if (curScore < scoreToBeat) { + scoreToBeat = curScore; + output = curDate; + } + } + return output; + } + // UnderscoreDate prototype object function UnderscoreDate(input, format) { // parse UnderscoreDate object @@ -139,7 +290,11 @@ this.date = input.date; // parse string and format } else if (format) { - this.date = makeDateFromStringAndFormat(input, format); + if (isArray(format)) { + this.date = makeDateFromStringAndArray(input, format); + } else { + this.date = makeDateFromStringAndFormat(input, format); + } // parse everything else } else { this.date = input === undefined ? new Date() : @@ -220,121 +375,7 @@ }, format : function (inputString) { - // shortcuts to this and getting time functions - // done to save bytes in minification - var date = this.date, - currentMonth = date.getMonth(), - currentDate = date.getDate(), - currentYear = date.getFullYear(), - currentDay = date.getDay(), - currentHours = date.getHours(), - currentMinutes = date.getMinutes(), - currentSeconds = date.getSeconds(), - currentString = date.toString(), - charactersToReplace = /(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|dddd?|do?|w[o|w]?|YYYY|YY|a|A|hh?|HH?|mm?|ss?|zz?)/g, - nonuppercaseLetters = /[^A-Z]/g; - // check if the character is a format - // return formatted string or non string. - // - // uses switch/case instead of an object of named functions (like http://phpjs.org/functions/date:380) - // for minification and performance - // see http://jsperf.com/object-of-functions-vs-switch for performance comparison - function replaceFunction(input) { - // create a couple variables to be used later inside one of the cases. - var a, b; - switch (input) { - // MONTH - case 'M' : - return currentMonth + 1; - case 'Mo' : - return (currentMonth + 1) + _date.ordinal(currentMonth + 1); - case 'MM' : - return leftZeroFill(currentMonth + 1, 2); - case 'MMM' : - return _date.monthsShort[currentMonth]; - case 'MMMM' : - return _date.months[currentMonth]; - // DAY OF MONTH - case 'D' : - return currentDate; - case 'Do' : - return currentDate + _date.ordinal(currentDate); - case 'DD' : - return leftZeroFill(currentDate, 2); - // DAY OF YEAR - case 'DDD' : - a = new Date(currentYear, currentMonth, currentDate); - b = new Date(currentYear, 0, 1); - return ~~ (((a - b) / 864e5) + 1.5); - case 'DDDo' : - a = replaceFunction('DDD'); - return a + _date.ordinal(a); - case 'DDDD' : - return leftZeroFill(replaceFunction('DDD'), 3); - // WEEKDAY - case 'd' : - return currentDay; - case 'do' : - return currentDay + _date.ordinal(currentDay); - case 'ddd' : - return _date.weekdaysShort[currentDay]; - case 'dddd' : - return _date.weekdays[currentDay]; - // WEEK OF YEAR - case 'w' : - a = new Date(currentYear, currentMonth, currentDate - currentDay + 5); - b = new Date(a.getFullYear(), 0, 4); - return ~~ ((a - b) / 864e5 / 7 + 1.5); - case 'wo' : - a = replaceFunction('w'); - return a + _date.ordinal(a); - case 'ww' : - return leftZeroFill(replaceFunction('w'), 2); - // YEAR - case 'YY' : - return (currentYear + '').slice(-2); - case 'YYYY' : - return currentYear; - // AM / PM - case 'a' : - return currentHours > 11 ? 'pm' : 'am'; - case 'A' : - return currentHours > 11 ? 'PM' : 'AM'; - // 24 HOUR - case 'H' : - return currentHours; - case 'HH' : - return leftZeroFill(currentHours, 2); - // 12 HOUR - case 'h' : - return currentHours % 12 || 12; - case 'hh' : - return leftZeroFill(currentHours % 12 || 12, 2); - // MINUTE - case 'm' : - return currentMinutes; - case 'mm' : - return leftZeroFill(currentMinutes, 2); - // SECOND - case 's' : - return currentSeconds; - case 'ss' : - return leftZeroFill(currentSeconds, 2); - // TIMEZONE - case 'z' : - return replaceFunction('zz').replace(nonuppercaseLetters, ''); - case 'zz' : - a = currentString.indexOf('('); - if (a > -1) { - return currentString.slice(a + 1, currentString.indexOf(')')); - } - return currentString.slice(currentString.indexOf(':')).replace(nonuppercaseLetters, ''); - // DEFAULT - default : - return input.replace("\\", ""); - } - } - return inputString.replace(charactersToReplace, replaceFunction); + return formatDate(this.date, inputString); }, add : function (input) { diff --git a/underscore.date.min.js b/underscore.date.min.js index 80144cadd..b9dc34c8a 100755 --- a/underscore.date.min.js +++ b/underscore.date.min.js @@ -1 +1 @@ -(function(a){function m(a){var b=Math.abs(a)/1e3,d=b/60,e=d/60,f=e/24,g=f/365;return b<45&&k("s",c(b))||c(d)===1&&k("m")||d<45&&k("mm",c(d))||c(e)===1&&k("h")||e<22&&k("hh",c(e))||c(f)===1&&k("d")||f<25&&k("dd",c(f))||f<45&&k("M")||f<345&&k("MM",c(f/30))||c(g)===1&&k("y")||k("yy",c(g))}function l(a,b){return j(a)-j(b)}function k(a,c){return b.relativeTime[a].replace(/%d/i,c||1)}function j(a){return isNaN(a)?(new i(a)).date.getTime():a}function i(b,c){b&&b.date instanceof Date?this.date=b.date:c?this.date=h(b,c):this.date=b===a?new Date:b instanceof Date?b:f(b)?g(b):new Date(b)}function h(a,b){function j(a,b){switch(a){case"M":case"MM":c[1]=~~b-1;break;case"D":case"DD":case"DDD":case"DDDD":c[2]=~~b;break;case"YY":b=~~b,c[0]=b+(b>70?1900:2e3);break;case"YYYY":c[0]=~~b;break;case"a":case"A":i=b.toLowerCase()==="pm";break;case"H":case"HH":case"h":case"hh":c[3]=~~b;break;case"m":case"mm":c[4]=~~b;break;case"s":case"ss":c[5]=~~b}}var c=[0],d=/[0-9a-zA-Z]+/g,e=a.match(d),f=b.match(d),h,i;for(h=0;h11?"pm":"am";case"A":return i>11?"PM":"AM";case"H":return i;case"HH":return d(i,2);case"h":return i%12||12;case"hh":return d(i%12||12,2);case"m":return j;case"mm":return d(j,2);case"s":return k;case"ss":return d(k,2);case"z":return o("zz").replace(n,"");case"zz":c=l.indexOf("(");if(c>-1)return l.slice(c+1,l.indexOf(")"));return l.slice(l.indexOf(":")).replace(n,"");default:return a.replace("\\","")}}var c=this.date,e=c.getMonth(),f=c.getDate(),g=c.getFullYear(),h=c.getDay(),i=c.getHours(),j=c.getMinutes(),k=c.getSeconds(),l=c.toString(),m=/(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|dddd?|do?|w[o|w]?|YYYY|YY|a|A|hh?|HH?|mm?|ss?|zz?)/g,n=/[^A-Z]/g;return a.replace(m,o)},add:function(a){this.date=e(this.date,a,1);return this},subtract:function(a){this.date=e(this.date,a,-1);return this},from:function(a,c,d){var e=l(this.date,a),f=e<0?b.relativeTime.past:b.relativeTime.future;return d?e:c?m(e):f.replace(/%s/i,m(e))},fromNow:function(a,b){return this.from(new i,a,b)},isLeapYear:function(){var a=this.date.getFullYear();return a%4===0&&a%100!==0||a%400===0}},typeof window=="undefined"&&typeof module!="undefined"?module.exports=b:(this._!==a&&this._.mixin!==a&&this._.mixin({date:b}),this._date=b)})() \ No newline at end of file +(function(a){function p(a){var b=Math.abs(a)/1e3,d=b/60,e=d/60,f=e/24,g=f/365;return b<45&&n("s",c(b))||c(d)===1&&n("m")||d<45&&n("mm",c(d))||c(e)===1&&n("h")||e<22&&n("hh",c(e))||c(f)===1&&n("d")||f<25&&n("dd",c(f))||f<45&&n("M")||f<345&&n("MM",c(f/30))||c(g)===1&&n("y")||n("yy",c(g))}function o(a,b){return m(a)-m(b)}function n(a,c){return b.relativeTime[a].replace(/%d/i,c||1)}function m(a){return isNaN(a)?(new l(a)).date.getTime():a}function l(b,c){b&&b.date instanceof Date?this.date=b.date:c?f(c)?this.date=k(b,c):this.date=i(b,c):this.date=b===a?new Date:b instanceof Date?b:f(b)?g(b):new Date(b)}function k(a,b){var c,d=/[0-9a-zA-Z]+/g,e=a.match(d),f=[],g=99,k,l,m;for(k=0;k70?1900:2e3);break;case"YYYY":c[0]=~~b;break;case"a":case"A":i=b.toLowerCase()==="pm";break;case"H":case"HH":case"h":case"hh":c[3]=~~b;break;case"m":case"mm":c[4]=~~b;break;case"s":case"ss":c[5]=~~b}}var c=[0],d=/[0-9a-zA-Z]+/g,e=a.match(d),f=b.match(d),h,i;for(h=0;h11?"pm":"am";case"A":return i>11?"PM":"AM";case"H":return i;case"HH":return d(i,2);case"h":return i%12||12;case"hh":return d(i%12||12,2);case"m":return j;case"mm":return d(j,2);case"s":return k;case"ss":return d(k,2);case"z":return o("zz").replace(n,"");case"zz":c=l.indexOf("(");if(c>-1)return l.slice(c+1,l.indexOf(")"));return l.slice(l.indexOf(":")).replace(n,"");default:return a.replace("\\","")}}var e=a.getMonth(),f=a.getDate(),g=a.getFullYear(),h=a.getDay(),i=a.getHours(),j=a.getMinutes(),k=a.getSeconds(),l=a.toString(),m=/(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|dddd?|do?|w[o|w]?|YYYY|YY|a|A|hh?|HH?|mm?|ss?|zz?)/g,n=/[^A-Z]/g;return c.replace(m,o)}function g(a){return new Date(a[0],a[1]||0,a[2]||1,a[3]||0,a[4]||0,a[5]||0,a[6]||0)}function f(a){return Object.prototype.toString.call(a)==="[object Array]"}function e(a,b,c){var d=(b.ms||0)+(b.s||0)*1e3+(b.m||0)*6e4+(b.h||0)*36e5+(b.d||0)*864e5+(b.w||0)*6048e5,e=(b.M||0)+(b.y||0)*12,f;d&&a.setMilliseconds(a.getMilliseconds()+d*c),e&&(f=a.getDate(),a.setDate(1),a.setMonth(a.getMonth()+e*c),a.setDate(Math.min((new Date(a.getFullYear(),a.getMonth()+1,0)).getDate(),f)));return a}function d(a,b){var c=a+"";while(c.length