If given a date in UTC (let's say) is it possible to convert to various time zones taking DST into account?
I'm interested if JS can do this natively, without me having a list of time zones and their offset.
Thanks.
A date (in Javascript and in most other systems) is not "in" a particular timezone. It measures the number of milliseconds between midnight, January 1, 1970 GMT, and "now".
Timezone only comes into play when you want to convert it to or from a human-readable format.
You can use the getTimezoneOffset method.
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"});
Okay, newbie JavaScript question.
I am constructing a Date object from a string. This string to construct the Date is 2020-08-19T11:32:08 but the output of toISOString() is 2028-08-19T15:32:08.000Z
Why am I seeing the hour as 15 instead of 11?
2020-08-19T11:32:08 is your local time - in your timezone.
2028-08-19T15:32:08.000Z is the universal time (indicated by the Z at the end) - that's the time on the GMT/UTC. It's right in UK in winter, but otherwise the use of this is that we can all agree to use the same timezone when sharing times internationally.
If you only have local users all in the same timezone it's probably a can of worms you don't want to open. If you have international users and you want them to interact (for instance book a video meeting between New York and LA) then the convention is to use UTC dates (blame the British empire for that one).
ISO is the standard format and toISOString also uses the UTC timezone.
From MDN, emphasis mine:
The toISOString() method returns a string in simplified extended ISO format (ISO 8601), which is always 24 or 27 characters long (YYYY-MM-DDTHH:mm:ss.sssZ or ±YYYYYY-MM-DDTHH:mm:ss.sssZ, respectively). The timezone is always zero UTC offset, as denoted by the suffix "Z".
Because toISOString returns in ISO 8606 format and with UTC set to 0.
I'm processing some data with dates in the format YYYY-MM-DD hh:mm:ss zz. For example:
2019-04-06 08:24:51 Central Daylight Time
2018-09-06 12:16:12 Central Standard Time
2020-02-14 17:57:33 Central Standard Time
I want to be able to convert these dates to a Date object in browser JavaScript. However, the Date constructor does not recognize this sort of date format, and moment.js isn't much help (unless I'm missing something).
In practice, I'll probably only ever deal with Central Standard Time and Central Daylight Time, but is there a general solution that would allow me to convert this date format to a Date object?
Assuming that Central Standard Time can also be written as CST, you can try
new Date('2020-02-14 17:57:33 CST'); // default date output
which will give you the full date representation.
Or you could use Date.parse() to get the actual timestamp
Date.parse('2020-02-14 17:57:33 CST'); // 1581724653000 etc
Another thought - have you tried Moment timezone?
I know this seems like a straight forward question - but although Moment.js and moment timezone are very powerful tools for getting/setting and formatting dates..
I'm having an issue snapping my application to a single timezone.
What I want, is for a user to choose from a date/time picker - and to send that as a unix timestamp in UTC.. but the date/time picker MUST be considered to be BST.
In other words, even if you're using the site from abroad - the date/time you select should be the UTC value for if you had chosen it in the UK.
var local = moment(dateTime).unix();
var london = moment(dateTime).tz('Europe/London').unix();
var berlin = moment(dateTime).tz('Europe/Berlin').unix();
All 3 variables will equal the SAME UTC timestamp on the same machine, but a different timestamp on another machine running in a different timezone.
Think about it... if my date/time was 3pm on Saturday.. that's a DIFFERENT UTC in London than it is in Berlin, since it will occur one hour earlier in Berlin.
How do I force a date/time to be considered as a specific timezone?
Thanks :-)
Assuming dateTime is an ISO8601 string, and you want the date to be in the Europe/London timezone at all times all you need is:
moment.tz(dateTime, 'Europe/London').unix()
This tells moment to interpret that time as London time, provided that it does not have a specified offset. If it has an offset, it is going to convert from the time of the offset to London time.
So, for me in America/Chicago, you can see the effect of this:
//unix timestap in london time
moment.tz('2016-12-30', 'Europe/London').unix()
1483056000
//parse that timestamp back to my local time
moment.unix(1483056000).format()
"2016-12-29T18:00:00-06:00"
Keep in mind that London has multiple offsets due to Daylight Saving Time. I think this is what you want.
If you wanted it to always keep a fixed offset of +0, then you could just use UTC:
moment.utc(dateTime)
I have a legacy web app that stores dates as a UNIX timestamp (seconds since the epoch 1970). Usually a timestamp like this represents UTC, however these timestamps are UTC-8. It doesn't look like it ever accounts for Daylight Savings Time (DST). I could convert it on the server to UTC and send to the client, but I would like to know if there is a javascript only solution.
Example Input:
1399335987
Example Output:
"2014-05-05T16:26:27-07:00" // Pacific Daylight Time (PDT)
The client should display the date/time according to their local machine. I looked into using momentjs but I could not find how to construct a date from a number without the number being UTC already. Is this possible?
Yes, it's possible given the unix timestamps are in UTC, with Moment Timezone (http://momentjs.com/timezone/)
moment
.unix(1399335987)
.tz('MST')
.format('YYYY-MM-DDTHH:mm:ssZ');
And you get
"2014-05-05T17:26:27-07:00"
Note here I'm using MST, and you should be able to use whatever timezone you want, via Timezone Data Builder (http://momentjs.com/timezone/data/)
Actually, by default, moment parses and displays in local time.
This means, only if you're in a different timezone (offset really) and still want to get the local time in MST, it's necessary to set the timezone as MST.
Otherwise, moment.unix(1399335987).format('YYYY-MM-DDTHH:mm:ssZ') is good to go.