Skip to content

Commit

Permalink
Fix date methods
Browse files Browse the repository at this point in the history
  • Loading branch information
Xotic750 committed Dec 10, 2015
1 parent a827b75 commit 0471bd9
Show file tree
Hide file tree
Showing 2 changed files with 264 additions and 3 deletions.
144 changes: 144 additions & 0 deletions es5-shim.js
Original file line number Diff line number Diff line change
Expand Up @@ -1034,6 +1034,150 @@ defineProperties($Object, {
// ====
//

var negativeTestDate = new Date(-3509827329600292);
var hasNegativeMonthYearBug = negativeTestDate.getUTCMonth() === 12;
var hasToDateStringFormatBug = negativeTestDate.toDateString() !== 'Thu Jan 01 -109252';
var hasToUTCStringFormatBug = negativeTestDate.toUTCString() !== 'Thu, 01 Jan -109252 11:59:59 GMT';
var hasToStringFormatBug = !(/^Wed Dec 09 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/).test(new Date(1449662400000).toString());
var originalGetFullYear;
var originalGetMonth;
var originalGetUTCFullYear;
var originalGetUTCMonth;
var originalToUTCString;
var originalToDateString;
var originalToString;
var dayName;
var monthName;
if (hasNegativeMonthYearBug || hasToDateStringFormatBug || hasToUTCStringFormatBug || hasToStringFormatBug) {
originalGetFullYear = Date.prototype.getFullYear;
originalGetMonth = Date.prototype.getMonth;
originalGetUTCFullYear = Date.prototype.getUTCFullYear;
originalGetUTCMonth = Date.prototype.getUTCMonth;
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'];
}

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) === 12) {
return year + 1;
}
return year;
},
getMonth: function getMonth() {
if (!this || !(this instanceof Date)) {
throw new TypeError('this is not a Date object.');
}
var month = originalGetMonth.call(this);
if (month === 12) {
return 0;
}
return month;
},
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) === 12) {
return year + 1;
}
return year;
},
getUTCMonth: function getUTCMonth() {
if (!this || !(this instanceof Date)) {
throw new TypeError('this is not a Date object.');
}
var month = originalGetUTCMonth.call(this);
if (month === 12) {
return 0;
}
return month;
}
}, 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
123 changes: 120 additions & 3 deletions tests/spec/s-date.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ describe('Date', function () {
var ifSupportsDescriptorsIt = supportsDescriptors ? it : xit;
var has = Object.prototype.hasOwnProperty;

var negativeDate;
beforeEach(function () {
negativeDate = new Date(-3509827329600292);
});

describe('.now()', function () {
it('should be the current time', function () {
var before = (new Date()).getTime();
Expand Down Expand Up @@ -211,14 +216,27 @@ describe('Date', function () {
describe('#getUTCDate()', function () {
it('should return the right value for negative dates', function () {
// Opera 10.6/11.61/Opera 12 bug
expect(new Date(-3509827334573292).getUTCDate()).toBe(1);
expect(negativeDate.getUTCDate()).toBe(1);
});
});

describe('#getUTCDay()', function () {
it('should return the right value for negative dates', function () {
expect(negativeDate.getUTCDay()).toBe(4);
});
});

describe('#getUTCFullYear()', function () {
it('should return the right value for negative dates', function () {
// Opera 10.6/11.61/Opera 12 bug
expect(negativeDate.getUTCFullYear()).toBe(-109252);
});
});

describe('#getUTCMonth()', function () {
it('should return the right value for negative dates', function () {
// Opera 10.6/11.61/Opera 12 bug
expect(new Date(-3509827334573292).getUTCMonth()).toBe(0);
expect(negativeDate.getUTCMonth()).toBe(0);
});

it('should return correct values', function () {
Expand All @@ -227,6 +245,85 @@ describe('Date', function () {
});
});

describe('#getUTCHours()', function () {
it('should return the right value for negative dates', function () {
expect(negativeDate.getUTCHours()).toBe(11);
});
});

describe('#getUTCMinutes()', function () {
it('should return the right value for negative dates', function () {
expect(negativeDate.getUTCMinutes()).toBe(59);
});
});

describe('#getUTCSeconds()', function () {
it('should return the right value for negative dates', function () {
expect(negativeDate.getUTCSeconds()).toBe(59);
});
});

describe('#getUTCMilliseconds()', function () {
it('should return the right value for negative dates', function () {
// Opera 10.6/11.61/Opera 12 bug
expect(negativeDate.getUTCMilliseconds()).toBe(708);
});
});

describe('#getDate()', function () {
it('should return the right value for negative dates', function () {
expect(negativeDate.getDate()).toBe(1);
});
});

describe('#getDay()', function () {
it('should return the right value for negative dates', function () {
expect(negativeDate.getDay()).toBe(4);
});
});

describe('#getFullYear()', function () {
it('should return the right value for negative dates', function () {
// Opera 10.6/11.61/Opera 12 bug
expect(negativeDate.getFullYear()).toBe(-109252);
});
});

describe('#getMonth()', function () {
it('should return the right value for negative dates', function () {
// Opera 10.6/11.61/Opera 12 bug
expect(negativeDate.getMonth()).toBe(0);
});
});

describe('#getHours()', function () {
it('should return the right value for negative dates', function () {
expect(negativeDate.getHours() + Math.floor(negativeDate.getTimezoneOffset() / 60)).toBe(11);
});
});

describe('#getMinutes()', function () {
it('should return the right value for negative dates', function () {
var off = negativeDate.getTimezoneOffset();
var offHours = Math.floor(off / 60);
var offMins = off - offHours * 60;
expect(negativeDate.getMinutes() + offMins).toBe(59);
});
});

describe('#getSeconds()', function () {
it('should return the right value for negative dates', function () {
expect(negativeDate.getSeconds()).toBe(59);
});
});

describe('#getMilliseconds()', function () {
it('should return the right value for negative dates', function () {
// Opera 10.6/11.61/Opera 12 bug
expect(negativeDate.getMilliseconds()).toBe(708);
});
});

describe('#toISOString()', function () {
// TODO: write the rest of the test.

Expand All @@ -237,11 +334,31 @@ describe('Date', function () {

it('should return correct dates', function () {
expect(new Date(-1).toISOString()).toBe('1969-12-31T23:59:59.999Z');// Safari 5.1.5 "1969-12-31T23:59:59.-01Z"
expect(new Date(-3509827334573292).toISOString()).toBe('-109252-01-01T10:37:06.708Z'); // Opera 11.61/Opera 12 bug with Date#getUTCMonth
expect(negativeDate.toISOString()).toBe('-109252-01-01T11:59:59.708Z'); // Opera 11.61/Opera 12 bug with Date#getUTCMonth
});

});

describe('#toUTCString()', function () {
it('should return correct dates', function () {
expect(negativeDate.toUTCString()).toBe('Thu, 01 Jan -109252 11:59:59 GMT');
});
});

describe('#toDateString()', function () {
it('should return correct dates', function () {
expect(negativeDate.toDateString()).toBe('Thu Jan 01 -109252');
});
});

describe('#toString()', function () {
it('should return correct dates', function () {
var actual = new Date(1449662400000).toString();
var re = /^Wed Dec 09 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/;
expect(re.test(actual)).toBe(true, actual);
});
});

describe('#toJSON()', function () {

// Opera 11.6x/12 bug
Expand Down

0 comments on commit 0471bd9

Please sign in to comment.