Javascript Date() object with NULL Time - javascript

Is there a way to indicate only the date portion of a Date() object, without indicating the time?
e.g.
var d = Date();
d.setFullYear(2015, 0, 13);
d.toString();
"Tue Jan 13 2015 00:00:00 GMT-0500 (EST)" // Wrong - I didn't set a time!
"Tue Jan 13 2015 NULL GMT-0500 (EST)" // Expected Result
I want to be able to tell the difference between a user who only inputed the Date portion, vs one who explicitly inputed both a Date and a Time

Not really. A Javascript Date object always has a time. You can leave it at midnight and ignore it if you want, but it'll still be there. It's up to you how you interpret it.
If you want to be able to represent a null time, you could interpret midnight to mean that, though then you would have no way to represent times that actually are midnight. If you want to be able to have a null time and still represent every possible time you would need to have two variables.
You could have:
// Date with null time
var date = new Date(2015, 0, 13); // time component ignored
var time = null;
// Date with non-null time
var date = new Date(2015, 0, 13); // time component ignored
var time = new Date(1970, 0, 1, 9, 30); // date component ignored
Note in the second example the year, month and day in the time component are arbitrary and won't be used, but they still need to be there if you want to create a Date object.

JavaScript Date objects are internally defined using number of milliseconds since January 1, 1970 UTC. Therefore you are stuck with the time part.
Try this code
var date = new Date(2015, 0, 13);
console.log(date.valueOf());
You'll get this output
1421125200000
Here is the standard definition...
ECMAScript Language Spec See page 165
From ECMA standard:
A Date object contains a Number indicating a particular instant in time to within a millisecond. Such a Number
is called a time value. A time value may also be NaN, indicating that the Date object does not represent a
specific instant of time.
Time is measured in ECMAScript in milliseconds since 01 January, 1970 UTC. In time values leap seconds
are ignored. It is assumed that there are exactly 86,400,000 milliseconds per day. ECMAScript Number values
can represent all integers from –9,007,199,254,740,992 to 9,007,199,254,740,992; this range suffices to
measure times to millisecond precision for any instant that is within approximately 285,616 years, either
forward or backward, from 01 January, 1970 UTC.
The actual range of times supported by ECMAScript Date objects is slightly smaller: exactly –100,000,000
days to 100,000,000 days measured relative to midnight at the beginning of 01 January, 1970 UTC. This gives
a range of 8,640,000,000,000,000 milliseconds to either side of 01 January, 1970 UTC.
The exact moment of midnight at the beginning of 01 January, 1970 UTC is represented by the value +0

Dates are objects. As such, you can add properties to them as needed:
var date_only = new Date("2015-03-04");
date_only.time_is_meaningful = false;
var date_with_time = new Date("2015-03-04T10:47");
date_with_time.time_is_meaningful = true;
This is simpler and cleaner than your millisecond hack, and more
convenient than having two separate variables. You could then, if you
wish, subclass Date with a custom toString that checks the
time_is_meaningful property and acts accordingly.

You cannot remove the time information from a Date.
If you want to have both informations independently, use a Date for the date and ignore the time (e.g. ensure it's always exactly midnight for instance), and use another field to hold the time (it could be a Date where you ignore the date but not the time, or it could be one input text with formatted time, or several input texts with hour, minute, etc).
The UI representation is up to you.

Related

Why doesn't new Date(ms) == (new Date()).setMilliseconds(ms)

I'd like to convert a timestamp into a date:
status_transitions:
{ finalized_at: 1557419382,
marked_uncollectible_at: null,
paid_at: 1557419384,
voided_at: null },
In particular, paid_at: 1557419384. But when I try new Date(1557419384) I do not get the expected result. If I use Date.setMilliseconds() I do.
What's especially strange is the output of Date.setMilliseconds()
const ms = 1557419384;
const fromConstructor = new Date(ms);
const fromFn = new Date();
const strangeOutput = fromFn.setMilliseconds(ms);
console.log(`Milliseconds: ${ms}`);
console.log(`Output from setMilliseconds: ${strangeOutput}`);
console.log(`Date from new Date(ms): ${fromConstructor}`);
console.log(`Date using setMilliseconds(ms): ${fromFn}`);
The output of the code above is:
Milliseconds: 1557419384
Output from setMilliseconds: 1558978824384
Date from new Date(ms): Sun Jan 18 1970 18:36:59 GMT-0600 (Central Standard Time)
Date using setMilliseconds(ms): Mon May 27 2019 12:40:24 GMT-0500 (Central Daylight Time)
Why does creating a new date from a number not yield the same result of setMilliseconds()? Also, why is the output from setMilliseconds() different than the actual milliseconds passed in?
I've read the docs and they seem to imply there should be no difference between these two methods.
Consider the example shown in the setMilliseconds() part of the docs here.
var theBigDay = new Date();
theBigDay.setMilliseconds(100);
Running this right now, this gives me the value 1557421875100. Notice only the last three digits are 100. Thus, it doesn't set the entire date object to 100, but only sets the milliseconds portion of the value. The rest is coming from new Date(), which is the current UTC-based timestamp.
As far as why you don't get the expected result from new Date(1557419384), that timestamp would appear to be in seconds rather than milliseconds. Multiply the value by 1000 and it gives a more reasonable value. (Unix timestamps are commonly expressed in whole seconds, which appears to be the case here.)
Why is the output from setMilliseconds() different than the actual milliseconds passed in?
Check the docs more closely. setMilliSeconds has a "Parameter:
A number between 0 and 999, representing the milliseconds." and its description states "If you specify a number outside the expected range, the date information in the Date object is updated accordingly. For example, if you specify 1005, the number of seconds is incremented by 1, and 5 is used for the milliseconds.".
So new Date() creates a date with the current time, and then you add your millisecond value to that.
Why does creating a new date from a number not yield the same result of setMilliseconds()?
I've read the docs and they seem to imply there should be no difference between these two methods.
What you were looking for is setTime. new Date().setTime(millseconds) creates an object that is equal to new Date(milliseconds).
When I try new Date(1557419384) I do not get the expected result.
As Matt Johnson noted, this value appears to be seconds not millisecond. Multiply it by 1000.

Is there a value X such that new Date(X) yields the current date?

In a more general sense, I'm wondering if a value in Javascript can behave as if no variable were input, so that new Date(whatever) functions exactly like new Date().
null doesn't do this, instead creating a Date of (I think) -1 UNIX seconds (the very end of 1969). Is there a string that would work, e.g "now"?
You can use
new Date(Date.now());
to get the current date. Typing that into the console would return (for today's date)
Wed Jul 12 2017 14:03:16 GMT-0400 (Eastern Daylight Time)
To clarify, Date.now() returns the number of milliseconds since January 1, 1970 at 0:00 UTC.
You can read more about Date here : MDN: Date - JavaScript
No, there is no single value that would instruct new Date(…) with one argument to use the current time. However, you can call Date.now() or new Date() to get the current time, and then pass that to the constructor, which will return a new Date instance with that time.

Convert milliseconds into UTC date object with UTC Time Zone

I am trying to convert milliseconds into UTC date object as below -
var tempDate = new Date(1465171200000);
// --> tempDate = Mon Jun 06 2016 05:30:00 **GMT+0530 (India Standard Time)** {}
var _utcDate = new Date(tempDate.getUTCFullYear(), tempDate.getUTCMonth(), tempDate.getUTCDate(), tempDate.getUTCHours(), tempDate.getUTCMinutes(), tempDate.getUTCSeconds());
//--> _utcDate = Mon Jun 06 2016 00:00:00 **GMT+0530 (India Standard Time)** {}
Time is resetting to UTC time but Time Zone is still coming as GMT+0530 (India Standard Time).
Is there any sure shot approach to convert milliseconds into UTC date object with UTC Time Zone?
Quoting from this answer (that I suggest you to read completely):
There is no time zone or string format stored in the Date object itself. When various functions of the Date object are used, the computer's local time zone is applied to the internal representation.
As time zone is not stored in the Date object there is no way to set it.
I see two options:
the first is to make use of a library (as suggested in the answer above). Quite popular now is Moment.js
the second (pure JavaScript - if it's a viable solution in your context):
Do the "time math" in your local timezone.
When you're ready to switch to UTC use toUTCString() method.
Of course you'll end up with a string as this let you store the time zone as long as the date time value.
As you won't be able to manipulate the date time as a Date object from now on this must be the last step.
var tempDate = new Date(1465171200000);
// Mon Jun 06 2016 05:30:00 GMT+0530
// Do your date time math here
// using the Date object's methods
var utcDateAsString = tempDate.toUTCString();
// Mon Jun 06 2016 00:00:00 GMT
You say:
Time is resetting to UTC time but Time Zone is still coming as GMT+0530 (India Standard Time). Is there any sure shot approach to convert milliseconds into UTC date object with UTC Time Zone?
But I think you misunderstand what is occurring. When you pass a number to the Date constructor as in:
new Date(1465171200000)
is it assumed to be milliseconds since the ECMAScript epoch (1970-01-01T00:00:00Z), so a Date object is created with that value as its internal time value. So Date objects are inherently UTC.
When you write that to a string, internally a human readable date string is generated based on the host timezone setting, which is why you see a date for GMT+0530 (that is your host system timezone setting). The Date object itself does not have a timezone, it's always UTC.
When you then use UTC values to create a "local" Date using:
new Date(tempDate.getUTCFullYear(), tempDate.getUTCMonth(), ...)
then the host timezone is used to generate a UTC time value equivalent to a "local" date for the associated values. You've effectively subtracted your timezone offset from the original time value so it now represents a different moment in time. You can get exactly the same result doing:
var d = new Date(1465171200000);
d.setMinutes(d.getMintues() + d.getTimezoneOffset());
which just shows a bit more clearly what's going on. Note that ECMAScript timezone offsets are in minutes and have the opposite sense to UTC, that is, they are negative (-) for east and positive (+) for west. So an offset of UTC+05:30 it is represented as -330 and you need to add it to "shift" a Date rather than subtract it.
var tempDate = new Date(1465171200000);
var _utcDate = new Date(tempDate.getUTCFullYear(), tempDate.getUTCMonth(), tempDate.getUTCDate(), tempDate.getUTCHours(), tempDate.getUTCMinutes(), tempDate.getUTCSeconds());
console.log('Direct conversion to Date\ntempDate: ' + tempDate.toString());
console.log('Adjusted using UTC methods\n_utcDate: ' + _utcDate.toString());
tempDate.setMinutes(tempDate.getMinutes() + tempDate.getTimezoneOffset());
console.log('Adjusted using timezoneOffset\ntempDate: ' + tempDate.toString());
However, I can't understand why you want to do the above. 1465171200000 represents a specific moment in time (2016-06-06T00:00:00Z), adjusting it for every client timezone means it represents a different moment in time for each client with a different timezone offset.
If you create a Date from a Number, the local timezone is the one considered. But if you want to see what a timestamp would mean with the hours corrected for UTC, you could use a helper as such:
Number.prototype.toUTCDate = function () {
var value = new Date(this);
value.setHours(value.getHours() - (value.getTimezoneOffset() / 60));
return value;
};
The usage would be:
var date = (1465171200000).toUTCDate();

In javascript, how to get timezone value in UTC format for new Date(2017,05,31).toISOString()?

How to get timezone value for new Date(2017,05,31).toISOString()? It always comes as 000Z for any Date when the date is passed to the Date constructor. But for new Date().toISOString(), it gives the the timezone value.
new Date(2017,05,31).toISOString() gives "2017-05-30T18:30:00.000Z"
and new Date().toISOString() gives "2017-06-07T15:29:23.692Z". How to get timezone in UTC format for the past dates?
If you want the time to default to midnight in UTC, you can use Date.UTC(year, month, ...) to first create a timestamp based in UTC.
var utcMay31 = Date.UTC(2017, 4, 31); // note: 4 = May (0 = January)
Then, create the Date from that timestamp.
new Date(utcMay31).toUTCString(); // "Wed, 31 May 2017 00:00:00 GMT"
However, if you're wanting to know the timezone stored in the Date object, it doesn't actually have that. Dates represent an "instant" in time as the total number of milliseconds that have passed since Jan 1, 1970 00:00:00.000 UTC.
new Date().getTime(); // 1496851...
A Date can tell you the user's local offset from UTC in minutes at that instant.
new Date().getTimezoneOffset(); // e.g. 0, -480, 300
Otherwise, the timezone is limited to two choices when creating date strings, and the choice is based on the method used – user's local timezone or UTC.
new Date().toString(); // "now" in user's local time
new Date().toUTCString(); // "now" in UTC time
new Date().toISOString(); // "now" also in UTC time, alternate format
// etc.
You're confused ISO date values do not show the "time zone" instead they show the UTC time. Z stand for Zulu (UTC time).
2017-06-07T15:29:23.692Z
The bold part is not the time zone. It is the milli-seconds, the full time is in UTC. The reason it shows a 000Z in the set Date is because you didnt' set the milli-seconds.
If you want to display the time zone use toUTCString(). However it will display GMT which is UTC/Greenwich Time. To display the local time zone in a the date format you can use date.toLocaleString('en-US',{timeZoneName:'short'}) for example will display the date plus the local US time zone. Or you can use toString() which will display the GMT offset + the long local time zone.
In javascript, parsing, rendering and constructing dates will always assume local. It will convert to a timestamp, the number of milliseconds since 1-1-1970 00:00:00. JSON.stringify will convert to a UTC string, but legacy framworks use local dates. Always beware of this.
var myDate = new Date(); // this is now.
you can get your timezoneoffset (in minutes) with myDate.getTimezoneOffset(), but this will return the same offset for every date (aside from daylight saving time)
You shouldn't do this:
var utcDate = new Date(+d+60000*d.getTimezoneOffset());
// +d convert the date to a timespan.
// getTimezoneOffset() is in minutes
// *60000 makes that in milliseconds, the scale timespans operate upon
Date has a few methods to format dates, but always as local or UTC date. You need to do it manually if you want different time zones.
Note: the Date.UTC(...) function returns a timestamp. You sometimes see shifted dates, so they behave like UTC. But this causes problems later on.
var date = new Date(2000,1,1,12,0,0);
// DO NOT USE (breaks at start of daylight saving time)
// these are date/times that have the UTC-value,
// but Javascript treats them like local dates with this value.
utcDate1 = (+date-60000*d.getTimeZoneOffset()); // minus!!
utcDate2 = new Date(Date.UTC(2000,1,1,12,0,0));
// DO NOT USE (breaks at start of daylight saving time)
BTW
Edge, Chrome and Firefox display dates differently in the console: Edge and Firefox always shows local date, Chrome shows UTC. Also, if you change your timezone, Edge will screw up.

Javascript date toISOSstring/toJSON one day backwards

I store two dates. First date is the current day and the second one is a future date. To convert those dates into format year-month-day I use toISOSstring function. However usually (but not always) the current date is changed one day backwards.
I also tried to use toJSON function instead. But nothing has changed.
season.from = "Sun Apr 02 2017 18:29:52 GMT+0200 (CEST)"
season.to = "Fri Apr 21 2017 18:29:52 GMT+0200 (CEST)"
var date1 = new Date(season.from);
var date2 = new Date(season.to);
season.from = date1.toISOString().slice(0,10);
season.to = date2.toISOString().slice(0,10);
console.log(season.from); // one day backwards (e.g. 2017-04-01 not 2017-04-02)
console.log(season.to); // proper date somewhere in the future
Your original time strings are in local time, or at least they have a time zone specification. But toISOString returns the UTC time:
The timezone is always zero UTC offset, as denoted by the suffix "Z"
In the case of your GMT+02 time zone, this means the date/time returned by toISOString is two hours "earlier" than the local time. In some cases this can be a time before midnight, and this can render a different date as well.
The implementation of the toJSON method depends on toISOString, so it has the same behaviour.
Work-around
You could use toLocaleDateString('se'), which uses your local time, and formats according to Swedish standards, i.e. YYYY-MM-DD, so you don't even need to slice it. There are some other country codes you could specify to have the same.

Categories

Resources