I'd like to change the behaviour of the standard Date object. Years between 0..99
passed to the constructor should be interpreted as fullYear
(no add of 1900
). But my following function doesn't work
var oDateConst = Date.prototype.constructor; // save old contructor
Date.prototype.constructor = function () {
var d = oDateConst.apply(oDateConst, arguments); // create object with it
if ( ((arguments.length == 3) || (arguments.length == 6))
&& ((arguments[0] < 100) && (arguments[0] >= 0))) {
d.setFullYear(arguments[0]);
}
return d;
}
Why does it never get called? How would you solve this problem?
With reference to the technique mentioned in Matthew Albert's post, apart from the point which Dan Hlavenka posted, there is one more test scenario which fails. See the following code:
typeof Date() == typeof new Date() //Should be false, but it returns true
In a legacy project, there is a chance the above scenario could break few scenarios. Apart from the above and what Dan Hlavenka pointed, I agree that this is the most complete solution so far.
The reason it never gets called is because you're changing the constructor
property on Date.prototype
. However you're probably still creating a date using the code new Date()
. So it never uses your constructor. What you really want to do is create your own Date constructor:
function MyDate() {
var d = Date.apply(Date, arguments);
if ((arguments.length == 3 || arguments.length == 6)
&& (arguments[0] < 100 && arguments[0] >= 0)) {
d.setFullYear(arguments[0]);
return d;
}
Then you can create your new date like this:
var d = MyDate();
Edit: Instead of using Date.apply
I would rather use the following instantiate
function which allows you to apply arguments to a constructor function:
var bind = Function.bind;
var unbind = bind.bind(bind);
function instantiate(constructor, args) {
return new (unbind(constructor, null).apply(null, args));
}
This is how I would implement the new date constructor:
function myDate() {
var date = instantiate(Date, arguments);
var args = arguments.length;
var arg = arguments[0];
if ((args === 3 || args == 6) && arg < 100 && arg >= 0)
date.setFullYear(arg);
return date;
}
Edit: If you want to override the native Date constructor then you must do something like this:
Date = function (Date) {
MyDate.prototype = Date.prototype;
return MyDate;
function MyDate() {
var date = instantiate(Date, arguments);
var args = arguments.length;
var arg = arguments[0];
if ((args === 3 || args == 6) && arg < 100 && arg >= 0)
date.setFullYear(arg);
return date;
}
}(Date);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With