please explain this javascript debugger output regarding Date constructor - javascript

I am trying to instantiate a date so that the code works in Chrome and IE (et al). Ideally I'd like to find a simple statement rather than a UDF, if it's possible. Is it not possible to Date.parse the string value in javascript when the time chunk is represented as T00:00:00?
Here's what I have in the Immediate Window in Visual Studio; caldate contains a string representation of a date returned by the back-end database; passing that string to Date.parse() returns a timestamp, 1371441600000, and passing that timestamp to the Date() constructor returns both Mon Jun 17 00:00:00 EDT 2013 and [prototype]: Invalid Date.
?caldate
"2013-06-17T00:00:00"
?Date.parse(caldate);
1371441600000
?new Date( Date.parse(caldate) );
Mon Jun 17 00:00:00 EDT 2013
[prototype]: Invalid Date

The Invalid Date is normal. That is just what the debugger prints for the proto object of a Date. I believe this is because the debugger calls the toString method on the proto object without supplying the actual Date instance, and so the toString method returns "Invalid Date".
I suggest you read the MDN documentation on Date.
You can just use new Date(caldate) to create a Date from your string.

Related

Javascript 'new' keyword appears to be ignored - is this an "edge case"? [duplicate]

new Date() takes an ordinal and returns a Date object.
What does Date() do, and how come it gives a different time?
>>> new Date(1329429600000)
Date {Fri Feb 17 2012 00:00:00 GMT+0200 (القدس Standard Time)}
>>> Date(1329429600000)
"Tue Mar 06 2012 15:29:58 GMT+0200 (Jerusalem Standard Time)"
From the specs:
When Date is called as a function rather than as a constructor, it returns a String representing the current time (UTC).
and:
When Date is called as part of a new expression, it is a constructor: it initialises the newly created object.
So, new Date(...) returns an object such that obj instanceof Date is true, whereas Date(...) basically returns the same as new Date().toString().
new Date creates a new Date object that you can modify or initialize with a different date while Date returns a string of the current date/time, ignoring its arguments.
Check out JavaScript Date for a quick API reference and code test bed. You can see the Date() function called without new does not take any parameters and always returns a string representation of the current date/time. If you modify the sample to be:
console.log(Date());
console.log(Date(1329429600000));
You'll find the results for both are the same (because JavaScript ignores extra arguments passed to functions):
Wed Apr 11 2012 09:58:11 GMT-0700 (PDT)
Wed Apr 11 2012 09:58:11 GMT-0700 (PDT)
It's 2017 and I had the same question in mind. What I found as an answer after some reading:
"The simplest way to perform an explicit type conversion is to use the Boolean() , Number() , String() , or Object() functions. We’ve already seen these functions as constructors for wrapper objects. When invoked without the new operator, however, they work as conversion functions and perform type conversions.."
"The built-in classes of core JavaScript attempt
valueOf() conversion before toString() conversion, except for the Date class,
which performs toString() conversion."
So Date() invoked without the new keyword performs a type conversion. And since Date is an object and an object-to-primitive should happen, date objects by default call toString() (though Date has meaningful valueOf() method as well).
Found that on the "JavaScript: The Definitive Guide" book. Leaving it here for the future generations who have just started learning JS :)
new Date() returns the date based on the input parameter and Date() returns todays date on the browser.
Date class can be called as constructor or as method to have a built-in code like :
function Date(args){
if (this.constructor == Date){
// if you call : new Date(args)
}else{
// if you call as method : Date()
return new Date()
}
}
Thus , if you called it like method , it re-call the constructor to return the current date&time .
Date lets you create objects that represent date/time. It's NOT meant to be called like a function. You can get more information here: Date - MDN
Calling a constructor as a Function is plain wrong it'll do (probably) unexpected things with your app scope and before very long you'll be the focus of attention in a group bug fixing session.
Create a Date Object as intended by the designers of the spec, don't code to the workarounds implemented as safeguards by engineers that think JS programmers are stupid. (worked in the lab, was in the next chair during the conversation, dealt with it and moved on)
If you are madly against new you can try object.create but at time of writing it's slower and unless you are planning to implement polymorphic inheritance then it is extra effort for less reward.

What is the reasoning behind `Date(epoch)` ignoring any parameter and returning the current time? [duplicate]

new Date() takes an ordinal and returns a Date object.
What does Date() do, and how come it gives a different time?
>>> new Date(1329429600000)
Date {Fri Feb 17 2012 00:00:00 GMT+0200 (القدس Standard Time)}
>>> Date(1329429600000)
"Tue Mar 06 2012 15:29:58 GMT+0200 (Jerusalem Standard Time)"
From the specs:
When Date is called as a function rather than as a constructor, it returns a String representing the current time (UTC).
and:
When Date is called as part of a new expression, it is a constructor: it initialises the newly created object.
So, new Date(...) returns an object such that obj instanceof Date is true, whereas Date(...) basically returns the same as new Date().toString().
new Date creates a new Date object that you can modify or initialize with a different date while Date returns a string of the current date/time, ignoring its arguments.
Check out JavaScript Date for a quick API reference and code test bed. You can see the Date() function called without new does not take any parameters and always returns a string representation of the current date/time. If you modify the sample to be:
console.log(Date());
console.log(Date(1329429600000));
You'll find the results for both are the same (because JavaScript ignores extra arguments passed to functions):
Wed Apr 11 2012 09:58:11 GMT-0700 (PDT)
Wed Apr 11 2012 09:58:11 GMT-0700 (PDT)
It's 2017 and I had the same question in mind. What I found as an answer after some reading:
"The simplest way to perform an explicit type conversion is to use the Boolean() , Number() , String() , or Object() functions. We’ve already seen these functions as constructors for wrapper objects. When invoked without the new operator, however, they work as conversion functions and perform type conversions.."
"The built-in classes of core JavaScript attempt
valueOf() conversion before toString() conversion, except for the Date class,
which performs toString() conversion."
So Date() invoked without the new keyword performs a type conversion. And since Date is an object and an object-to-primitive should happen, date objects by default call toString() (though Date has meaningful valueOf() method as well).
Found that on the "JavaScript: The Definitive Guide" book. Leaving it here for the future generations who have just started learning JS :)
new Date() returns the date based on the input parameter and Date() returns todays date on the browser.
Date class can be called as constructor or as method to have a built-in code like :
function Date(args){
if (this.constructor == Date){
// if you call : new Date(args)
}else{
// if you call as method : Date()
return new Date()
}
}
Thus , if you called it like method , it re-call the constructor to return the current date&time .
Date lets you create objects that represent date/time. It's NOT meant to be called like a function. You can get more information here: Date - MDN
Calling a constructor as a Function is plain wrong it'll do (probably) unexpected things with your app scope and before very long you'll be the focus of attention in a group bug fixing session.
Create a Date Object as intended by the designers of the spec, don't code to the workarounds implemented as safeguards by engineers that think JS programmers are stupid. (worked in the lab, was in the next chair during the conversation, dealt with it and moved on)
If you are madly against new you can try object.create but at time of writing it's slower and unless you are planning to implement polymorphic inheritance then it is extra effort for less reward.

Creating new date using Javascript gives Invalid Date in IE11

I'm creating a new date object in Javascript and it throws Invalid Date error in IE11.
It runs fine on Chrome and Firefox though.
Any idea what can be wrong?
new Date()
[date] Thu Sep 22 2016 12:24:33 GMT+0530 (India Standard Time)[date] Thu Sep 22 2016 12:24:33 GMT+0530 (India Standard Time)
[functions]
__proto__[date] Invalid Date
screenshot: http://screencast.com/t/hN4Kt8FEwdXu
Where do you see that it throws? The console displays a Date instance. The __proto__ property of this instance is an invalid date, but you should not care about that at all, it's part of the internal implementation.
Try new Date().toString(), you should get a valid string representation of your date, which means that all is fine.
It actually returns a date object where as the __proto__ (prototype) alone says "Invalid Date" which is as per the ES5 Date specification which goes like this,
The Date prototype object is itself a Date object (its [[Class]] is "Date") whose [[PrimitiveValue]] is NaN.
Source URL : http://es5.github.io/#x15.9.5
Hope this helps

Date changes results if called with an array of parameters

I tried the following script with both Node.js and my Chrome console:
console.log(new Date([1988,11,5]))
console.log(new Date(1988,11,5))
I was expecting the two methods to give the same results, but they behave differently:
Sat Nov 05 1988 00:00:00 GMT+0100 (W. Europe Standard Time)
Mon Dec 05 1988 00:00:00 GMT+0100 (W. Europe Standard Time)
In particular, the second field, which specifies the month, starts the counting from zero in the first case.
I would expect the month starting from zero in both cases, or have I misunderstood something?
The first line is not a valid Date constructor; it doesn't accept an array element as parameter. I think it's assuming it as a string value and is intepreted as yyyy,mm (1 based),dd.
Ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
These are equivalently a wrong init:
console.log(new Date([1988,11,5]))
console.log(new Date([1988,11,5].toString()))
console.log(new Date("1988,11,5"))
Demo: https://jsfiddle.net/IrvinDominin/Lweww6et/
The second call, new Date(1988, 11, 5), matches the specific format required by the specification for the Date constructor:
new Date (year, month [, date [, hours [, minutes [, seconds [, ms ] ] ] ] ] )
The first call will be passed through to the other form of the constructor, as you're passing in a single array:
new Date (value)
Looking at the steps here, it will be calling an internal implementation detail, ToPrimitive, on the array. Following the specification through the definitions of ToPrimitive and [[Default Value]], we see that the value argument passed to new Date in your first instance is a string representation of the array, ie 1988,11,5.
Going back to the spec for new Date (value), we see that if the type is a String, which it now is, it will be handed off to the same code that is used for Date.Parse, which says:
The function first attempts to parse the format of the String according to the rules called out in Date Time String Format (15.9.1.15). If the String does not conform to that format the function may fall back to any implementation-specific heuristics or implementation-specific date formats. Unrecognisable Strings or dates containing illegal element values in the format String shall cause Date.parse to return NaN.
(emphasis mine).
So, the implementors of V8, Chrome's and Node.js' JavaScript engine, have chosen to recognise and parse that string using a 1-based month. But because it's not in the spec, it might change, and it might be different in different implementations/browsers, so don't rely on it.

Dates display behind by a day

I'm encountering some weird behavior while using Moment.js. I have some helper classes attached to the Date prototype, which are apparently are causing each date to display behind by a day.
Date.prototype.format = function(){
return moment(this).format('MM/DD/YYYY')
}
var date = new Date('2008-05-13T00:00:00')
date.format() // => 05/12/2008, but should be 05/13/2008
A couple of other weird things I've noticed:
date.getDate() // => yields 12, but should be 13
But, if I instantiated the Moment object directly with the UTC string, then it works:
moment('2008-05-13T00:00:00').format('MM/DD/YY') // => 05/13/08
But I'm dealing with plain date objects, and modifying every date to a Moment object isn't my favorite idea. I have already tried modifying the format function to extract the UTC string from the date and see if it displays correctly then, but to no avail.
date.toUTCString() // => Correctly yields "Tue, 13 May 2008 00:00:00 GMT"
moment(date.toUTCString()).format('MM/DD/YY') // => still 05/12/08
Any ideas what's happening here? Is there a problem with the date constructor?
EDIT: Outputting the time as well:
moment(date).format('MM/DD/YY hh:mm:ss') // => "05/12/08 08:00:00"
You have to tell moment.js that you to display the date in UTC:
moment(this).utc().format('MM/DD/YYYY')
More in the documentation: http://momentjs.com/docs/#/parsing/utc/
But, if I instantiated the Moment object directly with the UTC string, then it works:
moment('2008-05-13T00:00:00').format('MM/DD/YY') // => 05/13/08`
Moment.js interprets the argument as local time:
By default, moment parses and displays in local time.
Whereas new Date() (and Date.parse) interpret the value as UTC time:
The parse function [...] interprets the resulting String as a date and time; it returns a Number, the UTC time value corresponding to the date and time.
I have already tried modifying the format function to extract the UTC string from the date and see if it displays correctly then, but to no avail.
date.toUTCString() // => Correctly yields "Tue, 13 May 2008 00:00:00 GMT"
moment(date.toUTCString()).format('MM/DD/YY') // => still 05/12/08`
The format that date.toUTCString() yields is not in any of the formats that moment.js supports, so it falls back to using new Date() (which interprets the string as UTC time, not local time).

Categories