My question is regarding this quote from the manual about dates in JavaScript:
Note: parsing of date strings with the Date constructor (and
Date.parse, they are equivalent) is strongly discouraged due to
browser differences and inconsistencies.
new Date('2016-04-14') output for a user was Wed Apr 13 2016 17:00:00 GMT-0700 (US Mountain Standard Time) upon which he had to use .toUTCString().
How to handle this if the users are in many different time zones?
new Date().getTime(); returns an integer value as the time on client's machine since 1970 Jan 1.
Since this is an integer value, it will be agnostic of locales, browser version, different browsers (IE, Chrome, Mozilla, or anything).
So, this should give you consistent results in terms of time on client's machine as long as client's timezone is known.
You can fetch client's timezone offset by using getTimezoneOffset API
var x = new Date();
var currentTimeZoneOffsetInHours = x.getTimezoneOffset() / 60;
This together with new Date().getTime(); should give you consistent results.
If you use
new Date().getTime();
it will return you a milisecond time stamp since 1970-01-01 for the current time zone that the client is in. This can then be converted back to a date in any language.
This would be a better standard way to pass the date around if you are sending it to and from servers and between clients. As millisecond timestamp ts converted in timezone a will convert to 01/01/2010 and in timezone b will convert to 01/01/2010 as they are taken from 1970-01-01
Hope this makes sence
Related
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"});
Javascript hopeless here but I've got a problem I can't seem to understand, and don't know whether it's defined behavior in JS or not...
From what I can understand, new Date() returns the current time in the current timezone as reported by the browser. At the current time of writing this, I am in Milan, Italy (GMT +0200 CEST), so when performing the below:
var date = new Date();
console.log(date);
console.log(date.getTimezoneOffset());
I get, as expected:
Sun Oct 07 2018 15:42:12 GMT+0200 (Central European Summer Time)
-120
However, again from what I understand, throwing milliseconds into the Date Constructor creates a date based off of Epoch Time, 1st January 1970 00:00:00 GMT +0000 - So why if I perform:
var date = new Date(0); // Note The 0
console.log(date);
console.log(date.getTimezoneOffset())
Do I get:
Thu Jan 01 1970 01:00:00 GMT+0100 (Central European Standard Time)
-60
Did the browser for some reason change the timezone it thinks I am in? This is causing quite a few problems for me retrieving a unix timestamp from a database, and displaying it in the user's current timezone!
Any help or advice on this would be much appreciated!
Many thanks! :)
The numeric timestamp value inside every Date instance, no matter how it is constructed, represents an offset from a fixed UTC "epoch" time. When you construct a date in your locale, the timezone offset is taken into account when the Date instance timstamp is set. The timezone offset is also taken into account when you access parts of the date via locale-relative APIs like .getTimezoneOffset().
Thus what matters is how you get date/time information out of the Date instance. If you use UTC APIs, you get UTC time information. If you use locale-relative APIs, you get locale-relative values.
let d = new Date();
console.log("locale-relative: " + d);
console.log("UTC: " + d.toUTCString());
Now, as to how you handle the system timestamp values you've got in your database, that depends on how your application works and what the dates mean in that context. If it's important that users see the dates in terms of what your server(s) will do with them, format the dates on the server with locale-relative APIs. That would make sense if your application does some work based on local time. For example some banking applications (in the US) do things at night, but "night" in terms of late evening hours in the continental US.
If, on the other hand, the dates you store should be shown to your users in terms of their locales, then send the client the timestamp and format your dates as strings at the client with locale-relative APIs. That would be appropriate for an application that allows users to set up alarms etc: generally it makes sense for the user to think in terms of their own local time.
when i create date using date constructor new Date('2015','12'), it results in Fri Jan 01 2016 00:00:00 GMT-0500 (Eastern Standard Time). But don't it to assume that what date i am providing is already applied daylight conversion and create date object for december 2015, instead of jan 2016
When creating a date using the Date constructor, the time zone of the host system is almost always used (per ECMA-262). The only exception is when a number (interpreted as a time value, i.e. milliseconds since the ECMAScript epoch) is provided, or an ISO 8601 format string with a time zone. Even then, the internal time value of the Date (i.e. milliseconds since the epoch) is calculated in UTC and the host system time zone offset used for the non–UTC methods like getHours, getMinutes, etc.
Also, the timezone offset of the current systems settings are used for historical dates. So if the host is set for daylight saving, it will be applied to dates at times before daylight saving was implemented. Also, historical changes to daylight saving changeover dates and times (and even value) are not applied. The currents settings are assumed to always apply for past and future dates.
So all of the following will apply the timezone offset of the host system when creating a date for 3 February, 2016:
new Date('2/3/2016'); // US format is assumed by most browsers.
// May also create an invalid Date
new Date(2016, 1, 3); // months are zero indexed so 1 is February
new Date('2016-02-03T00:00:00'); // note missing time zone
However, the following will be treated as UTC (or invalid):
new Date('2016-02-03'); // contrary to ISO 8601, missing time zone for this
// format only is assumed to be UTC
new Date('2016-02-03T00:00:00Z'); // Note has a time zone of GMT
If you want to reliably create a Date for a specific instant in time from a string, you must provide a string with the time zone offset. Then parse it yourself since parsing of date strings is largely implementation dependent and varies across implementations. The best format to use is ISO 8601 extended so something like:
'2016-02-03T00:00:00-0800'
which represents the same instant in time no matter what the settings of the host system are. You just need to reliably parse it.
There are many good libraries for parsing and formatting, or you can write your own small functions for particular parse and output formats.
I am receiving a MySQL Timestamp in UTC and trying to covert it to the client's local timezone. However, When i do this I get the wrong time zone.
Ive formatted my DateTime String to be: var utcTime = 2014-05-15T13:00:00Z
However when after my conversion my dateObject is: Date {Thu May 15 2014 09:00:00 GMT-0400 (EDT)}. However, I want my Timezone to be GMT -0500 (EST).
I've searched online and saw there is a way to do this by appending "UTC" to a MYSQL formatted Timestamp.. However, this method does not work in all browsers.
If anyone has any insight on converting timezones i would appreciate it.
The D in EDT stands for Daylight and the S in EST stands for Standard. EDT should be used during Summer in the U.S. and EST in the Winter (list of countries here). Is it possible that GMT -4 (EDT) is actually the right local time? If it would be more towards winter it would switch automatically to GMT -5 (EST). The client timezone together with daylight savings is handled automatically by Javascript.
For example, the default string representation of a certain date in Javascript should correctly choose between Standard time and Daylight Savings time based on the date object itself and the machine timezone:
var date = new Date(millisSinceUnixEpoch);
alert(date.toDateString() + ' ' + date.toTimeString());
Note: there's room for a lot of assumption though. E.g. not sure exactly how your 'conversion to local timezone' code looks like
I've seen something similar to this. This MSDN article may explain it.
Handling daylight saving time using JavaScript
http://msdn.microsoft.com/en-us/library/ie/jj863688%28v=vs.85%29.aspx
In Windows Internet Explorer 9 and previous versions of Windows
Internet Explorer, dates are customized by applying the ECMAScript
specification's rules for storing daylight saving time adjusted times
internally. To improve accuracy, especially with dates in the past
(historical dates), Internet Explorer 10 relies on the system's rules
for storing daylight saving time adjusted times. This topic contains
the following sections:
I typed "date" in console...and I get Tue Sep 20 01:01:49 PDT 2011 ...which is correct.
But then I do this in node.js, and I get the wrong time.
var ts = String(Math.round(new Date().getTime() / 1000));
Output is: 1316505706, which is an hour behind.
#KARASZI is absolutely correct about the root cause: Unix timestamps are always UTC unless you manipulate them. I would suggest that if you want a Unix timestamp you should leave it in UTC, and only convert to local time if you need to display a formatted time to the user.
The first benefit of doing this is that all your servers can "speak" the same time. For instance, if you've deployed servers to Amazon EC2 US East and Amazon EC2 US West and they share a common database, you can use UTC timestamps in your database and on your servers without worrying about timezone conversions every time. This is a great reason to use UTC timestamps, but it might not apply to you.
The second benefit of this is that you can measure things in terms of elapsed time without having to worry about daylight savings time (or timezones either, in case you're measuring time on a platform which is moving!). This doesn't come up very much, but if you had a situation where something took negative time because the local time "fell back" an hour while you were measuring, you'd be very confused!
The third reason I can think of is very minor, but some performance geeks would really appreciate it: you can get the raw UTC timestamp without allocating a new Date object each time, by using the Date class's "now" function.
var ts = Date.now() / 1000;
The reason is that the getTime function returns the time in the UTC timezone:
The value returned by the getTime method is the number of milliseconds since 1 January 1970 00:00:00 UTC. You can use this method to help assign a date and time to another Date object.
If you want to fetch the UNIX timestamp in you current timezone, you can use the getTimezoneOffset method:
var date = new Date();
var ts = String(Math.round(date.getTime() / 1000) + date.getTimezoneOffset() * 60);
Note you can avoid this confusion by using a node.js package like timezonecomplete or timezone-js which have an interface that is much less error-prone for date and time manipulation.
date in console will return the server time, whereas using JavaScript on a webpage will return the client's local time.