Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Datepicker: Support parsing, formatting, and selecting four-digit years before year 100 #1908

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
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.
mattheww-skyward committed Jan 22, 2020
commit 862121ea6eccfd24106a1997fd258a6549d7703a
4 changes: 2 additions & 2 deletions tests/unit/datepicker/helper.js
Original file line number Diff line number Diff line change
@@ -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 );
},

7 changes: 6 additions & 1 deletion tests/unit/datepicker/options.js
Original file line number Diff line number Diff line change
@@ -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,
12 changes: 9 additions & 3 deletions ui/widgets/datepicker.js
Original file line number Diff line number Diff line change
@@ -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
}