Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling the Date constructor with a Date object

Tags:

javascript

The JS documentation for Date claims that there are four ways to use the Date constructor. From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date:

new Date();
new Date(value); // integer
new Date(dateString); // string
new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]]);

However, there seems to be a fifth way to use the constructor, by passing in a valid date object. For example, the following works fine in the chrome console:

date = new Date() // Wed Sep 02 2015 16:30:21 GMT-0700 (PDT)
date2 = new Date(date) // Wed Sep 02 2015 16:30:21 GMT-0700 (PDT)

They are different objects, so it seems like an easy way to make a copy of a date:

date2 === date // false
date.setMonth(1) // 1422923421090
date // Mon Feb 02 2015 16:30:21 GMT-0800 (PST)
date2 // Wed Sep 02 2015 16:30:21 GMT-0700 (PDT)

So my questions are:

  1. Why is this not in the official documentation? Am I missing something?
  2. Is this an officially supported use of the constructor? Will it work on all platforms/browsers?
  3. Is this a safe way to make a copy of a Date object, replacing e.g. date2 = new Date().setTime(date.getTime())?
like image 886
xph Avatar asked Sep 02 '15 23:09

xph


People also ask

How can you get the current Date using JS Date objects?

In JavaScript, we can easily get the current date or time by using the new Date() object. By default, it uses our browser's time zone and displays the date as a full text string, such as "Fri Jun 17 2022 10:54:59 GMT+0100 (British Summer Time)" that contains the current date, time, and time zone.

How do you declare a Date object?

You can create a Date object using the Date() constructor of java. util. Date constructor as shown in the following example. The object created using this constructor represents the current time.

Does JavaScript store dates in a Date object?

The Date object is a built-in object in JavaScript that stores the date and time.

What is the use of Date object?

The Date object is an inbuilt datatype of JavaScript language. It is used to work with dates and times. The Date object is created by using new keyword, i.e. new Date(). The Date object can be used date and time in terms of millisecond precision within 100 million days before or after 1/1/1970.


2 Answers

Straight from the relevant portion of the ECMAScript 6 spec:

If Type(value) is Object and value has a [[DateValue]] internal slot, then Let tv be thisTimeValue(value).

Which basically says that if you pass the Date constructor a single argument and it's an object and it has the [[DateValue]] internal slot, then use that to initialize the new object.

So, what you are seeing is documented in the specification.

Here's more detail:

enter image description here

But, the ES5 spec is not the same and will do a conversion to a string when you do what you're doing which will then be parsed as a string by the constructor. While that will work to preserve everything down to the seconds, it will not preserve milliseconds since those are not present in the default string conversion. So, if you want a perfect copy, then you should do this in ES5 or earlier:

var date = new Date();
var date2 = new Date(date.getTime());
like image 56
jfriend00 Avatar answered Oct 10 '22 20:10

jfriend00


I would advise against that for now. This is what's going now under the browsers following different specs for the Date object.

ES 6.0:

var d1 = new Date();
var d2 = new Date(d1.getTime());
//ES6.0 basically gets the property that holds the timestamp straight from the object.

document.getElementById('results').innerHTML = 'Assert: ' + d1.valueOf() + ' === ' + d2.valueOf() + ' ' + (d1.valueOf() === d2.valueOf());
<pre id="results"></pre>

It does compare it perfectly BUT.... Here's how ES5.1 will handle that:

var d1 = new Date();
var d2 = new Date(Date.parse(d1.toString()));
//ES5.1 will attempt to parse the string representation of the Date object.

document.getElementById('results').innerHTML = 'Assert: ' + d1.valueOf() + ' === ' + d2.valueOf() + ' ' + (d1.valueOf() === d2.valueOf());
<pre id="results"></pre>

It basically gets rids of the milliseconds of the first Date object (Assertion might work if the first date object has no milliseconds, run the snippet a couple of times). Firefox seems to be following ES5.1 behaviour at the moment and Chrome ES6.0. Can't really say when they started adopting it.

I would definately not advise to pass the Date object as a constructor for a new Date object if the purpose is to clone the first Date object. Use Data.prototype.getTime() instead.

like image 34
MinusFour Avatar answered Oct 10 '22 20:10

MinusFour