Skip to content

Commit

Permalink
Fix date methods
Browse files Browse the repository at this point in the history
  • Loading branch information
Xotic750 authored and Xotic750 committed Dec 21, 2015
1 parent 35403c7 commit 4a4f88e
Show file tree
Hide file tree
Showing 2 changed files with 511 additions and 50 deletions.
196 changes: 196 additions & 0 deletions es5-shim.js
Original file line number Diff line number Diff line change
Expand Up @@ -1076,6 +1076,202 @@ defineProperties($Object, {
// ====
//

var hasNegativeMonthYearBug = new Date(-3509827329600292).getUTCMonth() !== 0;
var aNegativeTestDate = new Date(-1509842289600292);
var aPositiveTestDate = new Date(1449662400000);
var hasToUTCStringFormatBug = aNegativeTestDate.toUTCString() !== 'Mon, 01 Jan -45875 11:59:59 GMT';
var hasToDateStringFormatBug;
var hasToStringFormatBug;
var timeZoneOffset = aNegativeTestDate.getTimezoneOffset();
if (timeZoneOffset < -720) {
hasToDateStringFormatBug = aNegativeTestDate.toDateString() !== 'Tue Jan 02 -45875';
hasToStringFormatBug = !(/^Thu Dec 10 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/).test(aPositiveTestDate.toString());
} else {
hasToDateStringFormatBug = aNegativeTestDate.toDateString() !== 'Mon Jan 01 -45875';
hasToStringFormatBug = !(/^Wed Dec 09 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/).test(aPositiveTestDate.toString());
}

var originalGetFullYear;
var originalGetMonth;
var originalGetDate;
var originalGetUTCFullYear;
var originalGetUTCMonth;
var originalGetUTCDate;
var originalToUTCString;
var originalToDateString;
var originalToString;
var dayName;
var monthName;
var daysInMonth;
if (hasNegativeMonthYearBug || hasToDateStringFormatBug || hasToUTCStringFormatBug || hasToStringFormatBug) {
originalGetFullYear = Date.prototype.getFullYear;
originalGetMonth = Date.prototype.getMonth;
originalGetDate = Date.prototype.getDate;
originalGetUTCFullYear = Date.prototype.getUTCFullYear;
originalGetUTCMonth = Date.prototype.getUTCMonth;
originalGetUTCDate = Date.prototype.getUTCDate;
originalToUTCString = Date.prototype.toUTCString;
originalToDateString = Date.prototype.toDateString;
originalToString = Date.prototype.toString;
dayName = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri'];
monthName = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
daysInMonth = function dim(month, year) {
return originalGetDate.call(new Date(year, month, 0));
};
}

defineProperties(Date.prototype, {
getFullYear: function getFullYear() {
if (!this || !(this instanceof Date)) {
throw new TypeError('this is not a Date object.');
}
var year = originalGetFullYear.call(this);
if (year < 0 && originalGetMonth.call(this) > 11) {
return year + 1;
}
return year;
},
getMonth: function getMonth() {
if (!this || !(this instanceof Date)) {
throw new TypeError('this is not a Date object.');
}
var year = originalGetFullYear.call(this);
var month = originalGetMonth.call(this);
if (year < 0 && month > 11) {
return 0;
}
return month;
},
getDate: function getDate() {
if (!this || !(this instanceof Date)) {
throw new TypeError('this is not a Date object.');
}
var year = originalGetFullYear.call(this);
var month = originalGetMonth.call(this);
var date = originalGetDate.call(this);
if (year < 0 && month > 11) {
if (month === 12) {
return date;
}
var days = daysInMonth(0, year + 1);
return (days - date) + 1;
}
return date;
},
getUTCFullYear: function getUTCFullYear() {
if (!this || !(this instanceof Date)) {
throw new TypeError('this is not a Date object.');
}
var year = originalGetUTCFullYear.call(this);
if (year < 0 && originalGetUTCMonth.call(this) > 11) {
return year + 1;
}
return year;
},
getUTCMonth: function getUTCMonth() {
if (!this || !(this instanceof Date)) {
throw new TypeError('this is not a Date object.');
}
var year = originalGetUTCFullYear.call(this);
var month = originalGetUTCMonth.call(this);
if (year < 0 && month > 11) {
return 0;
}
return month;
},
getUTCDate: function getUTCDate() {
if (!this || !(this instanceof Date)) {
throw new TypeError('this is not a Date object.');
}
var year = originalGetUTCFullYear.call(this);
var month = originalGetUTCMonth.call(this);
var date = originalGetUTCDate.call(this);
if (year < 0 && month > 11) {
if (month === 12) {
return date;
}
var days = daysInMonth(0, year + 1);
return (days - date) + 1;
}
return date;
}
}, hasNegativeMonthYearBug);

defineProperties(Date.prototype, {
toUTCString: function toUTCString() {
if (!this || !(this instanceof Date)) {
throw new TypeError('this is not a Date object.');
}
var day = this.getUTCDay();
var date = this.getUTCDate();
var month = this.getUTCMonth();
var year = this.getUTCFullYear();
var hour = this.getUTCHours();
var minute = this.getUTCMinutes();
var second = this.getUTCSeconds();
return dayName[day] + ', ' +
(date < 10 ? '0' + date : date) + ' ' +
monthName[month] + ' ' +
year + ' ' +
(hour < 10 ? '0' + hour : hour) + ':' +
(minute < 10 ? '0' + minute : minute) + ':' +
(second < 10 ? '0' + second : second) + ' GMT';
}
}, hasNegativeMonthYearBug || hasToUTCStringFormatBug);

// Opera 12 has `,`
defineProperties(Date.prototype, {
toDateString: function toDateString() {
if (!this || !(this instanceof Date)) {
throw new TypeError('this is not a Date object.');
}
var day = this.getDay();
var date = this.getDate();
var month = this.getMonth();
var year = this.getFullYear();
return dayName[day] + ' ' +
monthName[month] + ' ' +
(date < 10 ? '0' + date : date) + ' ' +
year;
}
}, hasNegativeMonthYearBug || hasToDateStringFormatBug);

// can't use defineProperties here because of toString enumeration issue in IE <= 8
if (hasNegativeMonthYearBug || hasToStringFormatBug) {
Date.prototype.toString = function toString() {
if (!this || !(this instanceof Date)) {
throw new TypeError('this is not a Date object.');
}
var day = this.getDay();
var date = this.getDate();
var month = this.getMonth();
var year = this.getFullYear();
var hour = this.getHours();
var minute = this.getMinutes();
var second = this.getSeconds();
var timezoneOffset = this.getTimezoneOffset();
var hoursOffset = Math.floor(Math.abs(timezoneOffset) / 60);
var minutesOffset = Math.floor(Math.abs(timezoneOffset) % 60);
return dayName[day] + ' ' +
monthName[month] + ' ' +
(date < 10 ? '0' + date : date) + ' ' +
year + ' ' +
(hour < 10 ? '0' + hour : hour) + ':' +
(minute < 10 ? '0' + minute : minute) + ':' +
(second < 10 ? '0' + second : second) + ' GMT' +
(timezoneOffset > 0 ? '-' : '+') +
(hoursOffset < 10 ? '0' + hoursOffset : hoursOffset) +
(minutesOffset < 10 ? '0' + minutesOffset : minutesOffset);
};
if (supportsDescriptors) {
$Object.defineProperty(Date.prototype, 'toString', {
configurable: true,
enumerable: false,
writable: true
});
}
}

// ES5 15.9.5.43
// http://es5.github.com/#x15.9.5.43
// This function returns a String value represent the instance in time
Expand Down
Loading

0 comments on commit 4a4f88e

Please sign in to comment.