diff --git a/tests/unit/datepicker/core.js b/tests/unit/datepicker/core.js
index 2cc89cd21b9..c5106718f32 100644
--- a/tests/unit/datepicker/core.js
+++ b/tests/unit/datepicker/core.js
@@ -39,9 +39,11 @@ QUnit.test( "widget method", function( assert ) {
 
 QUnit.test( "baseStructure", function( assert ) {
 	var ready = assert.async();
-	assert.expect( 58 );
+	assert.expect( 60 );
 	var header, title, table, thead, week, panel, inl, child,
-		inp = testHelper.initNewInput(),
+		inp = testHelper.initNewInput( {
+			defaultDate: $.datepicker._newDate( 1, 2 - 1, 3 )
+		} ),
 		dp = $( "#ui-datepicker-div" );
 
 	function step1() {
@@ -61,7 +63,7 @@ QUnit.test( "baseStructure", function( assert ) {
 			assert.ok( title.is( "div.ui-datepicker-title" ) && title.html() !== "", "Structure - title division" );
 			assert.equal( title.children().length, 2, "Structure - title child count" );
 			assert.ok( title.children().first().is( "span.ui-datepicker-month" ) && title.children().first().text() !== "", "Structure - month text" );
-			assert.ok( title.children().last().is( "span.ui-datepicker-year" ) && title.children().last().text() !== "", "Structure - year text" );
+			assert.ok( title.children().last().is( "span.ui-datepicker-year" ) && title.children().last().text() === "0001", "Structure - year text" );
 
 			table = dp.children().eq( 1 );
 			assert.ok( table.is( "table.ui-datepicker-calendar" ), "Structure - month table" );
@@ -90,12 +92,15 @@ QUnit.test( "baseStructure", function( assert ) {
 		inp = testHelper.initNewInput( {
 			changeMonth: true,
 			changeYear: true,
-			showButtonPanel: true
+			showButtonPanel: true,
+			defaultDate: $.datepicker._newDate( 1, 2 - 1, 3 )
 		} );
 		testHelper.onFocus( inp, function() {
 			title = dp.find( "div.ui-datepicker-title" );
 			assert.ok( title.children().first().is( "select.ui-datepicker-month" ), "Structure - month selector" );
 			assert.ok( title.children().last().is( "select.ui-datepicker-year" ), "Structure - year selector" );
+			assert.equal( title.children().last().children().first().text(), "-9" );
+			assert.equal( title.children().last().children().last().text(), "0011" );
 
 			panel = dp.children().last();
 			assert.ok( panel.is( "div.ui-datepicker-buttonpane" ), "Structure - button panel division" );
@@ -457,7 +462,7 @@ QUnit.test( "keystrokes", function( assert ) {
 } );
 
 QUnit.test( "mouse", function( assert ) {
-	assert.expect( 15 );
+	assert.expect( 16 );
 	var inl,
 		inp = testHelper.init( "#inp" ),
 		dp = $( "#ui-datepicker-div" ),
@@ -470,6 +475,10 @@ QUnit.test( "mouse", function( assert ) {
 	$( ".ui-datepicker-calendar tbody a:contains(12)", dp ).simulate( "click", {} );
 	testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 12 ),
 		"Mouse click - preset" );
+	inp.val( "02/04/0001" ).datepicker( "show" );
+	$( ".ui-datepicker-calendar tbody a:contains(12)", dp ).simulate( "click", {} );
+	testHelper.equalsDate( assert, inp.datepicker( "getDate" ), $.datepicker._newDate( 1, 2 - 1, 12 ),
+		"Mouse click - year 0-99" );
 	inp.val( "02/04/2008" ).datepicker( "show" );
 	inp.val( "" ).datepicker( "show" );
 	$( "button.ui-datepicker-close", dp ).simulate( "click", {} );
diff --git a/tests/unit/datepicker/helper.js b/tests/unit/datepicker/helper.js
index 7fd149bf156..7c9964d8d77 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 7711e741233..60f22cf37c3 100644
--- a/tests/unit/datepicker/options.js
+++ b/tests/unit/datepicker/options.js
@@ -267,7 +267,7 @@ QUnit.test( "otherMonths", function( assert ) {
 } );
 
 QUnit.test( "defaultDate", function( assert ) {
-	assert.expect( 16 );
+	assert.expect( 18 );
 	var inp = testHelper.init( "#inp" ),
 		date = new Date();
 	inp.val( "" ).datepicker( "show" ).
@@ -350,6 +350,11 @@ QUnit.test( "defaultDate", function( assert ) {
 		simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
 	date = new Date( 2007, 7 - 1, 4 );
 	testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date 07/04/2007" );
+	inp.datepicker( "option", { defaultDate: "07/04/0001" } ).
+		datepicker( "hide" ).val( "" ).datepicker( "show" ).
+		simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+	date = $.datepicker._newDate( 1, 7 - 1, 4 );
+	testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date 07/04/0001" );
 	inp.datepicker( "option", { dateFormat: "yy-mm-dd", defaultDate: "2007-04-02" } ).
 		datepicker( "hide" ).val( "" ).datepicker( "show" ).
 		simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
@@ -362,6 +367,11 @@ QUnit.test( "defaultDate", function( assert ) {
 		datepicker( "hide" ).val( "" ).datepicker( "show" ).
 		simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
 	testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date 01/26/2007" );
+	date = $.datepicker._newDate( 1, 1 - 1, 26 );
+	inp.datepicker( "option", { defaultDate: date } ).
+		datepicker( "hide" ).val( "" ).datepicker( "show" ).
+		simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
+		testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date 01/26/0001" );
 } );
 
 QUnit.test( "miscellaneous", function( assert ) {
@@ -537,14 +547,17 @@ QUnit.test( "minMax", function( assert ) {
 } );
 
 QUnit.test( "setDate", function( assert ) {
-	assert.expect( 24 );
+	assert.expect( 26 );
 	var inl, alt, minDate, maxDate, dateAndTimeToSet, dateAndTimeClone,
 		inp = testHelper.init( "#inp" ),
 		date1 = new Date( 2008, 6 - 1, 4 ),
-		date2 = new Date();
+		date2 = new Date(),
+		date3 = $.datepicker._newDate( 1, 4 - 1, 1 );
 	assert.ok( inp.datepicker( "getDate" ) == null, "Set date - default" );
 	inp.datepicker( "setDate", date1 );
 	testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date1, "Set date - 2008-06-04" );
+	inp.datepicker( "setDate", date3 );
+	testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date3, "Set date - 0001-04-01" );
 	date1 = new Date();
 	date1.setDate( date1.getDate() + 7 );
 	inp.datepicker( "setDate", +7 );
@@ -568,6 +581,10 @@ QUnit.test( "setDate", function( assert ) {
 	date1.setDate( date1.getDate() - 21 );
 	inp.datepicker( "setDate", "c -3 w" );
 	testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date1, "Set date - c -3 w" );
+	date3 = new Date( date1 );
+	date3.setFullYear( 1 );
+	inp.datepicker( "setDate", "c " + ( 1 - date1.getFullYear() ) + " y" );
+	testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date3, "Set date - 0001 relatively" );
 
 	// Inline
 	inl = testHelper.init( "#inl" );
@@ -926,7 +943,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 +970,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 +991,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,
@@ -1066,7 +1088,7 @@ QUnit.test( "Ticket #7244: date parser does not fail when too many numbers are p
 } );
 
 QUnit.test( "formatDate", function( assert ) {
-	assert.expect( 16 );
+	assert.expect( 17 );
 	testHelper.init( "#inp" );
 	var gmtDate, fr, settings;
 	assert.equal( $.datepicker.formatDate( "d m y", new Date( 2001, 2 - 1, 3 ) ),
@@ -1090,6 +1112,8 @@ QUnit.test( "formatDate", function( assert ) {
 	assert.equal( $.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" );
+	assert.equal( $.datepicker.formatDate( "yy-mm-dd", $.datepicker._newDate( 999, 2 - 1, 3 ) ),
+		"0999-02-03", "Format ancient date yy-mm-dd" );
 	gmtDate = new Date( 2001, 2 - 1, 3 );
 	gmtDate.setMinutes( gmtDate.getMinutes() - gmtDate.getTimezoneOffset() );
 	assert.equal( $.datepicker.formatDate( "@", gmtDate ), "981158400000", "Format date @" );
diff --git a/ui/widgets/datepicker.js b/ui/widgets/datepicker.js
index 5e6321e1d44..1e20f521171 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
 		}
@@ -1400,7 +1406,7 @@ $.extend( Datepicker.prototype, {
 							break;
 						case "o":
 							output += formatNumber( "o",
-								Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 );
+								Math.round( ( this._newDate( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - this._newDate( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 );
 							break;
 						case "m":
 							output += formatNumber( "m", date.getMonth() + 1, 2 );
@@ -1409,8 +1415,7 @@ $.extend( Datepicker.prototype, {
 							output += formatName( "M", date.getMonth(), monthNamesShort, monthNames );
 							break;
 						case "y":
-							output += ( lookAhead( "y" ) ? date.getFullYear() :
-								( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 );
+							output += lookAhead( "y" ) ? this._formatYear( date.getFullYear() ) : ( "00" + date.getFullYear() ).slice( -2 );
 							break;
 						case "@":
 							output += date.getTime();
@@ -1558,7 +1563,7 @@ $.extend( Datepicker.prototype, {
 					}
 					matches = pattern.exec( offset );
 				}
-				return new Date( year, month, day );
+				return $.datepicker._newDate( year, month, day );
 			},
 			newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) :
 				( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) );
@@ -1610,7 +1615,7 @@ $.extend( Datepicker.prototype, {
 	/* Retrieve the date(s) directly. */
 	_getDate: function( inst ) {
 		var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null :
-			this._daylightSavingAdjust( new Date(
+			this._daylightSavingAdjust( this._newDate(
 			inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
 			return startDate;
 	},
@@ -1662,7 +1667,7 @@ $.extend( Datepicker.prototype, {
 			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
 			tempDate = new Date(),
 			today = this._daylightSavingAdjust(
-				new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time
+				this._newDate( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time
 			isRTL = this._get( inst, "isRTL" ),
 			showButtonPanel = this._get( inst, "showButtonPanel" ),
 			hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ),
@@ -1672,7 +1677,7 @@ $.extend( Datepicker.prototype, {
 			stepMonths = this._get( inst, "stepMonths" ),
 			isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ),
 			currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) :
-				new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ),
+				this._newDate( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ),
 			minDate = this._getMinMaxDate( inst, "min" ),
 			maxDate = this._getMinMaxDate( inst, "max" ),
 			drawMonth = inst.drawMonth - showCurrentAtPos,
@@ -1683,10 +1688,10 @@ $.extend( Datepicker.prototype, {
 			drawYear--;
 		}
 		if ( maxDate ) {
-			maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(),
+			maxDraw = this._daylightSavingAdjust( this._newDate( maxDate.getFullYear(),
 				maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) );
 			maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw );
-			while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) {
+			while ( this._daylightSavingAdjust( this._newDate( drawYear, drawMonth, 1 ) ) > maxDraw ) {
 				drawMonth--;
 				if ( drawMonth < 0 ) {
 					drawMonth = 11;
@@ -1699,7 +1704,7 @@ $.extend( Datepicker.prototype, {
 
 		prevText = this._get( inst, "prevText" );
 		prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText,
-			this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ),
+			this._daylightSavingAdjust( this._newDate( drawYear, drawMonth - stepMonths, 1 ) ),
 			this._getFormatConfig( inst ) ) );
 
 		prev = ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ?
@@ -1709,7 +1714,7 @@ $.extend( Datepicker.prototype, {
 
 		nextText = this._get( inst, "nextText" );
 		nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText,
-			this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ),
+			this._daylightSavingAdjust( this._newDate( drawYear, drawMonth + stepMonths, 1 ) ),
 			this._getFormatConfig( inst ) ) );
 
 		next = ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ?
@@ -1747,7 +1752,7 @@ $.extend( Datepicker.prototype, {
 			group = "";
 			this.maxRows = 4;
 			for ( col = 0; col < numMonths[ 1 ]; col++ ) {
-				selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) );
+				selectedDate = this._daylightSavingAdjust( this._newDate( drawYear, drawMonth, inst.selectedDay ) );
 				cornerClass = " ui-corner-all";
 				calender = "";
 				if ( isMultiMonth ) {
@@ -1785,7 +1790,7 @@ $.extend( Datepicker.prototype, {
 				curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate
 				numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043)
 				this.maxRows = numRows;
-				printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) );
+				printDate = this._daylightSavingAdjust( this._newDate( drawYear, drawMonth, 1 - leadDays ) );
 				for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows
 					calender += "<tr>";
 					tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
@@ -1873,7 +1878,7 @@ $.extend( Datepicker.prototype, {
 		if ( !inst.yearshtml ) {
 			inst.yearshtml = "";
 			if ( secondary || !changeYear ) {
-				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
+				html += "<span class='ui-datepicker-year'>" + this._formatYear( drawYear ) + "</span>";
 			} else {
 
 				// determine range of years to display
@@ -1893,7 +1898,7 @@ $.extend( Datepicker.prototype, {
 				for ( ; year <= endYear; year++ ) {
 					inst.yearshtml += "<option value='" + year + "'" +
 						( year === drawYear ? " selected='selected'" : "" ) +
-						">" + year + "</option>";
+						">" + this._formatYear( year ) + "</option>";
 				}
 				inst.yearshtml += "</select>";
 
@@ -1915,7 +1920,7 @@ $.extend( Datepicker.prototype, {
 		var year = inst.selectedYear + ( period === "Y" ? offset : 0 ),
 			month = inst.selectedMonth + ( period === "M" ? offset : 0 ),
 			day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ),
-			date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) );
+			date = this._restrictMinMax( inst, this._daylightSavingAdjust( this._newDate( year, month, day ) ) );
 
 		inst.selectedDay = date.getDate();
 		inst.drawMonth = inst.selectedMonth = date.getMonth();
@@ -1955,18 +1960,18 @@ $.extend( Datepicker.prototype, {
 
 	/* Find the number of days in a given month. */
 	_getDaysInMonth: function( year, month ) {
-		return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate();
+		return 32 - this._daylightSavingAdjust( this._newDate( year, month, 32 ) ).getDate();
 	},
 
 	/* Find the day of the week of the first of a month. */
 	_getFirstDayOfMonth: function( year, month ) {
-		return new Date( year, month, 1 ).getDay();
+		return this._newDate( year, month, 1 ).getDay();
 	},
 
 	/* Determines if we should allow a "next/prev" month display change. */
 	_canAdjustMonth: function( inst, offset, curYear, curMonth ) {
 		var numMonths = this._getNumberOfMonths( inst ),
-			date = this._daylightSavingAdjust( new Date( curYear,
+			date = this._daylightSavingAdjust( this._newDate( curYear,
 			curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) );
 
 		if ( offset < 0 ) {
@@ -2020,9 +2025,28 @@ $.extend( Datepicker.prototype, {
 			inst.currentYear = inst.selectedYear;
 		}
 		var date = ( day ? ( typeof day === "object" ? day :
-			this._daylightSavingAdjust( new Date( year, month, day ) ) ) :
-			this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
+			this._daylightSavingAdjust( this._newDate( year, month, day ) ) ) :
+			this._daylightSavingAdjust( this._newDate( inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
 		return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) );
+	},
+
+	/* Create a Date from a year, month, and day, accounting for years 0-99. */
+	_newDate: function( year, month, day ) {
+		var date = new Date( year, month, day );
+
+		// Offset dates in the incorrect range.  Blindly calling setFullYear(year) would not handle out-of-range
+		// months/days causing the year to shift.
+		if ( year >= 0 && year <= 99 ) {
+			date.setFullYear( date.getFullYear() - 1900 );
+		}
+		return date;
+	},
+
+	/* Add leading zeros to produce an at-least-four-digit year. */
+	_formatYear: function( year ) {
+		var yearString = "" + year;
+		return year < 0 ? yearString :
+			yearString.length < 4 ? ( "0000" + yearString ).slice( -4 ) : yearString;
 	}
 } );