What's the difference between datetime in ISO 8601 and UTC formats in javascript? - javascript

I pick some date and time in javascript and then want to store it on server (.NET). Dates are supposed to be in future from the current moment (so they won't be before 1970).
Having read topics here on SO I learnt it's better to store date as a string and people suggest using Date.prototype.toISOString() or Date.prototype.toUTCString().
I've read that toISOString() is not available in IE 7. And I'd like to know other differences, when I should choose one or another function.

They're for different purposes.
UTC is the primary time standard by which the world regulates clocks and time.
ISO is standard format time. ISO also supports ms in its format.
So if you want to send data to the server, send the ISO, because ISO is the standard format:
var date = new Date();
sendDate(date.toISOString());
You can also use toISOString in IE7 polyfill.

I hope it will helpful to you.
Summary About toISOString() :-
The toISOString() method returns a string in ISO format (ISO 8601 Extended Format), which can be described as follows: YYYY-MM-DDTHH:mm:ss.sssZ. The timezone is always UTC as denoted by the suffix "Z".
Refer Below link for more information about toISOString().
Date.prototype.toISOString()
Summary About toUTCString() :-
The toUTCString() method converts a date to a string, using the UTC time zone.
Refer Below link for more information about toUTCString()
Date.prototype.toUTCString()

Always use .toISOString()
They give almost the same information, but in different formats. Here is what I get on my machine.
new Date().toISOString()
"2019-10-11T18:56:08.984Z"
new Date().toUTCString()
"Fri, 11 Oct 2019 18:56:08 GMT"
There are 4 reasons .toISOString() is more often what you want than .toUTCString().
A. More convenient sorting
When you sort alphabetically, the "2019-10-11T18:56:08.984Z" pattern of .toISOString() gives you the correct date order.
B. Millisecond precision
.toISOString() provides millisecond values, whereas .toUTCString() does not.
C. Any user can interpret correctly
The .toUTCString() value may be more familiar to human end-users, but only if the language settings are suitable for them. In contrast, the .toISOString() is the same regardless of language settings.
D. Reproducibly regeneratable by software
You can easily convert the ISO date string to a Javascript Date object, and then back again, regenerating exactly the same string. This is regardless of who gave you the ISO date string, where the server is, and where you are.
This is not automatically true for the UTC string. For example, if a second instance of your app system is running in a different time zone, or language, it's .toUTCstring() may use different numbers or words (respectively) to represent the same instant in time. It will be difficult for it to create a UTCString that matches what was made by the first instance of the app, since in general it will not know the language or timezone in which the first UTC string was produced.
I think nobody needs .toUTCString()
I don't know why `.toUTCString()` exists. Its word-heavy format makes it useless for internal storage of dates in your program, because it varies depending on your language and timezone setting etc.
So maybe it is to produce something nice to display externally for the user to see? Well, not really. Anyone who is not in the London time zone will not find it very helpful.
I live in London. And even I, even if I was writing an app purely for use by me, solely on my system, and only in my home, would still not want to use .toUTCString(). Because it is showing UTC (also known as GMT). London is not always on GMT. In summer, we move to GMT+1, so the .toUTCString() result would mislead anyone who didn't notice the "GMT" and do the time adjustment in their head.
If I wanted a natural-language time, to make non-computer literate users comfortable, I would construct it manually from parts, using a library like moment.js. If I wanted a quick-and-dirty solution, I would use .toString() which at least will move to Summer time when appropriate.

Related

How to convert a Date in specific Timezone and send to server

My scenario is a Date object created using the browser timezone (just using new Date()) and sent to the server, but I want to send this date with another specific timezone let's assume it's, Europe/Athens.
What would be the best representation of the actual date string so I can convert it back to a Date object in the backend in the actual Europe/Athens date?
I have the timezone info but not sure how to get a Fri Feb 05 2021 05:30:00 GMT-0500 (Eastern Standard Time) and convert it to Europe/Athens date.
I have tried to use date-fns but didn't get far.
You've got a few different questions and misconceptions, so I will attempt to address each of them, starting with question in the title:
How to convert a Date in specific Timezone and send to server
If you mean a date like 2021-01-18, that cannot be in a particular time zone. It is, by definition, just a date. Think about a printed calendar you might hang on your wall that has a square for each date. There are no time zones associated with such calendars. One can ask "what date is it now in a particular time zone", but the answer itself has no time zone.
If instead you meant a JavaScript Date object, the answer is again "you can't". The Date object is not actually a date, nor does it have a time zone, but rather it is a timestamp. Internally, a Date object only holds one value - the number of milliseconds that have elapsed since 1970-01-01 00:00:00.000 UTC (not considering leap seconds). It has no time zone. Instead, some functions such as .toString() will apply the system-local time zone while operating. That time zone comes from the operating system (in most cases). It is not stored inside the Date object itself.
My scenario is a Date object created using the browser timezone (just using new Date()) ...
That will use the system clock where the browser is running, but the time zone is not relevant. The Date object will be constructed from the Unix timestamp that represents "now". Such timestamps are inherently UTC based. The browser fetches the UTC time directly from the operating system, without considering time zone.
... and sent to the server
One cannot send an object to a server without going through deserialization on one side and serialization on the other.
... but I want to send this date with another specific timezone let's assume it's, Europe/Athens.
What would be the best representation of the actual date string so I can convert it back to a Date object in the backend in the actual Europe/Athens date?
Since the object only represents "now", you don't need to send it in a time zone specific format. Just send the UTC time. The ideal format is ISO 8601, which can be obtained directly using the .toISOString() function from the Date object.
Depending on your use case, you might also consider whether you might instead just take the UTC time from the server instead. At least you will have some control over the clock.
On the server side, if you need the time in a specific time zone, then convert from UTC to that time zone on the server, not on the client.
Also, from comments:
I believe even EPOCH is different between timezones. I could just get the EPOCh and then try to work with converting to specific timezones.
That is incorrect on a few levels. First, understand that epoch is just an English word meaning essentially "a representation of a starting point". It isn't a format, nor is it an acronym. In JavaScript, Date objects use Unix timestamps, which use an epoch of 1970-01-01T00:00:00.000Z. In other words, Midnight Jan 1st 1970 UTC is the 0 timestamp. Sometimes, such timestamps are referred to as "epoch time". That's a misnomer in my opinion, but even still - they are always UTC based. There is no time zone, and thus they are the same for the whole world.
Try to use toLocaleString:
let date = (new Date()).toLocaleString("en-US", {timeZone: "Europe/Athens"});

Determining the day of the week for specified date in an arbitrary timezone with momentJS

Say I had an ISO date string with embedded timezone information, like "2016-08-22T13:30:00-07:00" (Here, the -07:00 specifies PST). I'm looking for an elegant way to determine what day of the week it will be in that timezone on that date and time. I've tried moment.parseZone(datestring).weekday() to no avail. How can I make moment think in terms of the timezone specified in the string, instead of wherever the server happens to be?
You can try moment(datestring).utcOffset(datestring).weekday(), check the docs for more explanation. Also there is a part of the documntation on weekday which describes it as locale aware I am not sure if it maintains the time zone of the date while converting or defaults to your local/server location, I usually uses moment.day(), if it suits your use case, you can use it instead of weekday().

moment.js timezone inconsistency

I am formatting a given date using momentjs. The following behaves differently in different timezones:
moment(new Date("2016" + "-" + "06" + "-01").toISOString()).format('MMMM YYYY')
It gives me May 2016 in timezone of America/Denver and June 2016 in Asia/Karachi. I tested by changing the browser timezone to different timezones. It should be June 2016 in both.
When i change the format in new Date() to use slashes instead of hyphens like below, it gives me correct result in both timezones i.e. May 2016.
moment(new Date("2016" + "/" + "06" + "/01").toISOString()).format('MMMM YYYY')
Both seem to be valid ISO strings, what would cause this inconsistency?
The short answer to your question is that parser for javascript date doesn't work in a way that makes sense to anybody. Instead, you should just use Moment's parser to get the result you want. Parsing dates in a way that makes sense is about 50% of the reason that moment exists.
If you eliminate the date call and use Moment to parse your date, you will observe that the following code will result in June 2016 in any browser, because your string will be interpreted as local time if you are using Moment's default constructor:
moment('2016-06-01').format()
If you wanted to use slashes instead, it would be:
moment('2016/06/01', 'YYYY/MM/DD').format()
See moment's parsing guide for more information about how moment interprets times with it's different constructor methods.
The long answer is that when you pass a string in ISO8601 format that is date only to the JavaScript date constructor, it will interpret that string as UTC. Because Denver is UTC -6 on daylight time, and Karachi is UTC +5 all the time, when moment then displays that timestamp as local time you see the result that you do. You can observe the following:
var a = new Date('2016-06-01');
a.toISOString();
"2016-06-01T00:00:00.000Z"
Note that the 'Z' in the above timestamp indicates that it is UTC, as toISOString always returns a UTC timestamp. That timestamp is June in Karachi because Karachi is ahead of UTC, while May in Denver because Denver is behind UTC.
Observe this as well:
var a = new Date('2016-06-01T00:00');
a.toISOString();
"2016-06-01T05:00:00.000Z"
If I put a time on my string, it is interpreted as local time. Because my timezone was UTC-5 on January 1, the point on the global timeline is appropriately five hours ahead of the string I passed.
The behavior you are seeing - interpreting 2016-06-01 as UTC, but 2016-06-01T00:00 as local, is actually an effort to accommodate technical debt across browsers. It has been made the standard behavior in the 7th edition of the ECMA 262 specification, so expect for that not to change. See this link as well.
Alternately, when you use the slashes (2016/06/01) the JS implementation that you are using is choosing to interpret that format as local time, as it does not conform to any of the formats in the ECMA standard. This is NOT a valid ISO8601 format. It is very important to note that this behavior is implementation specific, and will vary across browsers/environments. The ECMA standard does not define a behavior for parsing that date format. Other browsers may parse this string in other ways.
As general advice, don't use the JavaScript date parser. It doesn't work right. You can use Moment.js, one of moment's several competitors, or manually parse strings yourself. All of these are better options.

Where does the date time format coming when use date toLocaleString?

I'm facing some date time formatting related issue.
I'm confused about how a date object's output string is formatted. I did some testing in debug, when I call the toLocalString, the output is not following locale settingin the OS .
Below is the output of the method:
"1/12/2015, 8:12:12 PM"
But what I did in the os locale setting is
Why is toLocaleString formatting the date this way? where does those format coming from?
Where to change the format setting browser is using?
Why is toLocaleString formatting the date this way?
toLocaleString() doesn't watch for user's locale formatting settings before returning the string.
Where does those format coming from?
The format is based on the conventions of user's time zone for representing date and time. So, format is machine independent.
Where to change the format setting browser is using?
As stated the format is implementation dependent. It won't help you anything. And I think browsers don't provide such functionality.
For reference I have included it's documentation below.
The Documentation of Date.toLocaleString() as mentioned in Javascript: The Definitive Guide says:
Returns
A string representation of the date and time specified by date. The date and time are repre- sented in the local time zone and formatted using locally appropriate conventions.
Usage
toLocaleString() converts a date to a string, using the local time zone. This method also uses local conventions for date and time formatting, so the format may vary from platform to platform and from country to country. toLocaleString() returns a string formatted in what is likely the user’s preferred date and time format.

How to find browser date time format [duplicate]

I have set a deadline in UTC, as shown below, and I'm wondering what exactly the toLocaleString() method will do to it on user's local machines. For instance, will it account for daylight savings if they are in a timezone that recognizes it? Or will I need to insert additional code that checks where the user is, and then fixes the displayed time?
http://javascript.about.com/library/bldst.htm
var deadline = new Date('5/1/2013 ' + "16:15" + ' UTC');
alert(deadline.toLocaleString());
In general, the answer is yes. JavaScript will represent the UTC value at the appropriate local time based on the time zone settings of the computer it is running on. This includes adjustment for DST. However, as others have pointed out, the details are implementation specific.
If you want a consistent output, I would use a library to format your dates instead of relying on the default implementation. The best library (IMHO) for this is moment.js. The live examples on their main page will give you an idea of what it can do.
UPDATE
If you are passing UTC values that you want converted to the correct local time, and that time falls into a period where the time zone rules are different than the current one - then the results will be invalid. This is crazy, but true - and by design in the ECMA spec. Read - JavaScript Time Zone is wrong for past Daylight Saving Time transition rules
We don't know what exactly the toLocaleString method does (§15.9.5.5):
This function returns a String value. The contents of the String are
implementation-dependent, but are intended to represent the Date in
the current time zone in a convenient, human-readable form that
corresponds to the conventions of the host environment’s current
locale.
But yes, most implementations will consider DST if it is active in the current local timezone. For your example I'm getting "Mittwoch, 1. Mai 2013 18:15:00" - CEST.
Will I need to insert additional code that checks where the user is, and then fixes the displayed time?
I think you can trust toLocaleString - the browser should respect the user's settings. If you want to do it manually, check out timezone.js.
As you use "UTC" the date itself will be UTC format, but the toLocaleString() takes client's locale into account, which means it'll return the date in string updated with all and every changes typical to client's regional and locale settings (DST, date/time format, etc).As JS documentation describes this: "The toLocaleString() method converts a Date object to a string, using locale settings.".If you want to avoid this, use the toUTCString() method instead.I'd also recommend reading the accepted solution for the question Javascript dates: what is the best way to deal with Daylight Savings Time? to avoid (at least, to try to avoid :) future issues related to JS, browsers and locales.Hope this helps!

Categories