From fc75c3e3adfa39f55f1a450a785cbe8da5329f30 Mon Sep 17 00:00:00 2001 From: Keith Wood Date: Wed, 1 Apr 2009 10:56:58 +0000 Subject: [PATCH] Datepicker: added Windows ticks format --- tests/unit/datepicker/datepicker_options.js | 8 +++ ui/ui.datepicker.js | 55 +++++++++++---------- 2 files changed, 37 insertions(+), 26 deletions(-) diff --git a/tests/unit/datepicker/datepicker_options.js b/tests/unit/datepicker/datepicker_options.js index 882a72b22..6b82a8370 100644 --- a/tests/unit/datepicker/datepicker_options.js +++ b/tests/unit/datepicker/datepicker_options.js @@ -657,6 +657,10 @@ test('parseDate', function() { new Date(2051, 2 - 1, 3), 'Parse date y-m-d - cutoff 80'); equalsDate($.datepicker.parseDate('y-m-d', '51-02-03', {shortYearCutoff: '+60'}), new Date(2051, 2 - 1, 3), 'Parse date y-m-d - cutoff +60'); + var gmtDate = new Date(2001, 2 - 1, 3); + gmtDate.setMinutes(gmtDate.getMinutes() - gmtDate.getTimezoneOffset()); + equalsDate($.datepicker.parseDate('@', '981158400000'), gmtDate, 'Parse date @'); + equalsDate($.datepicker.parseDate('!', '631167552000000000'), gmtDate, 'Parse date !'); var fr = $.datepicker.regional['fr']; var settings = {dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames, monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames}; @@ -745,6 +749,10 @@ test('formatDate', function() { equals($.datepicker.formatDate('\'day\' d \'of\' MM (\'\'DD\'\'), yy', new Date(2001, 2 - 1, 3)), 'day 3 of February (\'Saturday\'), 2001', 'Format date \'day\' d \'of\' MM (\'\'DD\'\'), yy'); + var gmtDate = new Date(2001, 2 - 1, 3); + gmtDate.setMinutes(gmtDate.getMinutes() - gmtDate.getTimezoneOffset()); + equals($.datepicker.formatDate('@', gmtDate), '981158400000', 'Format date @'); + equals($.datepicker.formatDate('!', gmtDate), '631167552000000000', 'Format date !'); var fr = $.datepicker.regional['fr']; var settings = {dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames, monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames}; diff --git a/ui/ui.datepicker.js b/ui/ui.datepicker.js index 05418b498..081ee749a 100644 --- a/ui/ui.datepicker.js +++ b/ui/ui.datepicker.js @@ -868,34 +868,25 @@ $.extend(Datepicker.prototype, { // Extract a number from the string value var getNumber = function(match) { lookAhead(match); - var origSize = (match == '@' ? 14 : (match == 'y' ? 4 : (match == 'o' ? 3 : 2))); - var size = origSize; - var num = 0; - while (size > 0 && iValue < value.length && - value.charAt(iValue) >= '0' && value.charAt(iValue) <= '9') { - num = num * 10 + parseInt(value.charAt(iValue++),10); - size--; - } - if (size == origSize) + var size = (match == '@' ? 14 : (match == '!' ? 20 : + (match == 'y' ? 4 : (match == 'o' ? 3 : 2)))); + var digits = new RegExp('^\\d{1,' + size + '}'); + var num = value.substring(iValue).match(digits); + if (!num) throw 'Missing number at position ' + iValue; - return num; + iValue += num[0].length; + return parseInt(num[0], 10); }; // Extract a name from the string value and convert to an index var getName = function(match, shortNames, longNames) { var names = (lookAhead(match) ? longNames : shortNames); - var size = 0; - for (var j = 0; j < names.length; j++) - size = Math.max(size, names[j].length); - var name = ''; - var iInit = iValue; - while (size > 0 && iValue < value.length) { - name += value.charAt(iValue++); - for (var i = 0; i < names.length; i++) - if (name == names[i]) - return i + 1; - size--; + for (var i = 0; i < names.length; i++) { + if (value.substr(iValue, names[i].length) == names[i]) { + iValue += names[i].length; + return i + 1; + } } - throw 'Unknown name at position ' + iInit; + throw 'Unknown name at position ' + iValue; }; // Confirm that a literal character matches the string value var checkLiteral = function() { @@ -936,6 +927,12 @@ $.extend(Datepicker.prototype, { month = date.getMonth() + 1; day = date.getDate(); break; + case '!': + var date = new Date((getNumber('!') - this._ticksTo1970) / 10000); + year = date.getFullYear(); + month = date.getMonth() + 1; + day = date.getDate(); + break; case "'": if (lookAhead("'")) checkLiteral(); @@ -978,9 +975,13 @@ $.extend(Datepicker.prototype, { RFC_1123: 'D, d M yy', RFC_2822: 'D, d M yy', RSS: 'D, d M y', // RFC 822 + TICKS: '!', TIMESTAMP: '@', W3C: 'yy-mm-dd', // ISO 8601 + _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + + Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), + /* Format a date object into a string value. The format can be combinations of the following: d - day of month (no leading zero) @@ -996,6 +997,7 @@ $.extend(Datepicker.prototype, { y - year (two digit) yy - year (four digit) @ - Unix timestamp (ms since 01/01/1970) + ! - Windows ticks (100ns since 01/01/0001) '...' - literal text '' - single quote @@ -1051,10 +1053,8 @@ $.extend(Datepicker.prototype, { output += formatName('D', date.getDay(), dayNamesShort, dayNames); break; case 'o': - var doy = date.getDate(); - for (var m = date.getMonth() - 1; m >= 0; m--) - doy += this._getDaysInMonth(date.getFullYear(), m); - output += formatNumber('o', doy, 3); + output += formatNumber('o', + (date.getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000, 3); break; case 'm': output += formatNumber('m', date.getMonth() + 1, 2); @@ -1069,6 +1069,9 @@ $.extend(Datepicker.prototype, { case '@': output += date.getTime(); break; + case '!': + output += date.getTime() * 10000 + this._ticksTo1970; + break; case "'": if (lookAhead("'")) output += "'";