From 862121ea6eccfd24106a1997fd258a6549d7703a Mon Sep 17 00:00:00 2001 From: Matthew Wartman Date: Wed, 22 Jan 2020 13:32:44 -0600 Subject: [PATCH] Datepicker: Parse dates before year 100 4-digit years, unix times, and windows times now handle years between 0 and 99. Additionally, negative unix times can be parsed. --- tests/unit/datepicker/helper.js | 4 ++-- tests/unit/datepicker/options.js | 7 ++++++- ui/widgets/datepicker.js | 12 +++++++++--- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/tests/unit/datepicker/helper.js b/tests/unit/datepicker/helper.js index 7fd149bf1..7c9964d8d 100644 --- a/tests/unit/datepicker/helper.js +++ b/tests/unit/datepicker/helper.js @@ -18,8 +18,8 @@ return $.extend( helper, { assert.ok( false, message + " - missing date" ); return; } - d1 = new Date( d1.getFullYear(), d1.getMonth(), d1.getDate() ); - d2 = new Date( d2.getFullYear(), d2.getMonth(), d2.getDate() ); + d1 = $.datepicker._newDate( d1.getFullYear(), d1.getMonth(), d1.getDate() ); + d2 = $.datepicker._newDate( d2.getFullYear(), d2.getMonth(), d2.getDate() ); assert.equal( d1.toString(), d2.toString(), message ); }, diff --git a/tests/unit/datepicker/options.js b/tests/unit/datepicker/options.js index 9287aceeb..328a834d4 100644 --- a/tests/unit/datepicker/options.js +++ b/tests/unit/datepicker/options.js @@ -926,7 +926,7 @@ QUnit.test( "iso8601Week", function( assert ) { } ); QUnit.test( "parseDate", function( assert ) { - assert.expect( 26 ); + assert.expect( 29 ); testHelper.init( "#inp" ); var currentYear, gmtDate, fr, settings, zh; assert.ok( $.datepicker.parseDate( "d m y", "" ) == null, "Parse date empty" ); @@ -953,6 +953,8 @@ QUnit.test( "parseDate", function( assert ) { testHelper.equalsDate( assert, $.datepicker.parseDate( "'day' d 'of' MM (''DD''), yy", "day 3 of February ('Saturday'), 2001" ), new Date( 2001, 2 - 1, 3 ), "Parse date 'day' d 'of' MM (''DD''), yy" ); + testHelper.equalsDate( assert, $.datepicker.parseDate( "yy-mm-dd", "0001-02-03" ), + $.datepicker._newDate( 1, 2 - 1, 3 ), "Parse ancient date yy-mm-dd" ); currentYear = new Date().getFullYear(); testHelper.equalsDate( assert, $.datepicker.parseDate( "y-m-d", ( currentYear - 2000 ) + "-02-03" ), new Date( currentYear, 2 - 1, 3 ), "Parse date y-m-d - default cutuff" ); @@ -972,6 +974,9 @@ QUnit.test( "parseDate", function( assert ) { gmtDate.setMinutes( gmtDate.getMinutes() - gmtDate.getTimezoneOffset() ); testHelper.equalsDate( assert, $.datepicker.parseDate( "@", "981158400000" ), gmtDate, "Parse date @" ); testHelper.equalsDate( assert, $.datepicker.parseDate( "!", "631167552000000000" ), gmtDate, "Parse date !" ); + gmtDate = $.datepicker._newDate( 1, 2 - 1, 3 ); + testHelper.equalsDate( assert, $.datepicker.parseDate( "@", "-62132724000000" ), gmtDate, "Parse ancient date @" ); + testHelper.equalsDate( assert, $.datepicker.parseDate( "!", "28728000000000" ), gmtDate, "Parse ancient date !" ); fr = $.datepicker.regional.fr; settings = { dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames, diff --git a/ui/widgets/datepicker.js b/ui/widgets/datepicker.js index 44b513d1a..3f6368c25 100644 --- a/ui/widgets/datepicker.js +++ b/ui/widgets/datepicker.js @@ -1151,6 +1151,7 @@ $.extend( Datepicker.prototype, { monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, year = -1, + isFullYear = false, month = -1, day = -1, doy = -1, @@ -1172,11 +1173,14 @@ $.extend( Datepicker.prototype, { size = ( match === "@" ? 14 : ( match === "!" ? 20 : ( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ), minSize = ( match === "y" ? size : 1 ), - digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ), + digits = new RegExp( "^" + (match === "@" ? "-?" : "") + "\\d{" + minSize + "," + size + "}" ), num = value.substring( iValue ).match( digits ); if ( !num ) { throw "Missing number at position " + iValue; } + if ( match === "y" ) { + isFullYear = isDoubled; + } iValue += num[ 0 ].length; return parseInt( num[ 0 ], 10 ); }, @@ -1243,12 +1247,14 @@ $.extend( Datepicker.prototype, { case "@": date = new Date( getNumber( "@" ) ); year = date.getFullYear(); + isFullYear = true; month = date.getMonth() + 1; day = date.getDate(); break; case "!": date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 ); year = date.getFullYear(); + isFullYear = true; month = date.getMonth() + 1; day = date.getDate(); break; @@ -1274,7 +1280,7 @@ $.extend( Datepicker.prototype, { if ( year === -1 ) { year = new Date().getFullYear(); - } else if ( year < 100 ) { + } else if ( year < 100 && !isFullYear ) { year += new Date().getFullYear() - new Date().getFullYear() % 100 + ( year <= shortYearCutoff ? 0 : -100 ); } @@ -1292,7 +1298,7 @@ $.extend( Datepicker.prototype, { } while ( true ); } - date = this._daylightSavingAdjust( new Date( year, month - 1, day ) ); + date = this._daylightSavingAdjust( this._newDate( year, month - 1, day ) ); if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) { throw "Invalid date"; // E.g. 31/02/00 }