2

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.

George Taskos
  • 8,324
  • 18
  • 82
  • 147
  • Why not keep server-client communication in epoch format? – rahulpsd18 Jan 18 '21 at 20:22
  • I believe even EPOCH is different between timezones. I could just get the EPOCh and then try to work with converting to specific timezones. – George Taskos Jan 18 '21 at 20:48
  • Epoch time doesn't technically have a timezone. It is based on a particular point in time, which just so happens to line up to an "even" UTC time. Refer [this](https://stackoverflow.com/q/23062515/7087502). Using epoch will keep all communication of datetime simple and you can just create a localized date object whenever required without even handling the timezone thingy. – rahulpsd18 Jan 18 '21 at 20:52
  • How do you create a localized date object programmatically? new Date(timestamp)? – George Taskos Jan 18 '21 at 21:07
  • Yes, that'll do. – rahulpsd18 Jan 18 '21 at 21:09
  • My problems start when I want to search timestamps in a specific timezone though. Note that such timestamps (i.e. created from a certain day) are different for different time-zones: '2020-03-17 UTC' = 1584403200 and '2020-03-17 CET' = 1584399600. So a range for '2020-03-17 CET' might not return accurate results. – George Taskos Jan 18 '21 at 21:12
  • 1
    It will not. `2020-03-17 UTC` is not equal to `2020-03-17 CET` as CET is an hour ahead of UTC. So if your epoch (1584399600) was created exactly at `March 17, 2020 00:00:00 (am) CET` then that was `March 16, 2020 23:00:00 (pm) UTC`. You stored it in epoch format.. so you will query it in epoch too getting valid and accurate results. 1584403200 which is `March 17, 2020 00:00:00 (am) UTC` is `March 17, 2020 01:00:00 (am) CET`. So when you search from a CET timezone for 17th March, you will get it. – rahulpsd18 Jan 18 '21 at 21:36
  • It makes sense. Yes. That was my initial thoughts and then I tried to store different timezone (local created the event and UTC) which lead to mess. – George Taskos Jan 18 '21 at 22:00
  • 1
    @rahulpsd18—typically, date–only timestamps do not have an associated timezone, only the ECMAScript authors decided that YYYY-MM-DD would be parsed as UTC, everyone else treats it as local. There really is no such thing as 2020-03-17 UTC or 2020-03-17 CET, it's just 2020-03-17. E.g. in Safari `new Date('2020-10-10 +10:00')` returns an invalid date. – RobG Jan 19 '21 at 01:06
  • I did not mean it that way and reading back I can see how it could be inferred as such. I was just trying to explain that a date object with time set to 00:00:00 in CET is different than one in UTC and just copied the OPs way of writing the date with timezone. Thanks! – rahulpsd18 Jan 19 '21 at 14:36
  • I accomplished what I needed by going back to UTC timestamp stored in the server database and to make it more interesting when querying or other reasons I store a human-readable zoned formatted string with the date and the timezone etc. date-fns and date-fns-tz helped a lot. Thank you for your comments. – George Taskos Jan 19 '21 at 22:25

2 Answers2

5

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.

Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
  • I had to find out all that stuff the hard way last night :) thank you for the answer and it is accepted. Indeed I just send the timestamp in milliseconds and in the server using date-fns-tz I was able to get a representation of the actual zoned formatted string for the purpose I need. But I made everything worked fine in the browser as soon as I cleared all these things in my head. – George Taskos Jan 19 '21 at 22:30
0

Try to use toLocaleString:

let date = (new Date()).toLocaleString("en-US", {timeZone: "Europe/Athens"});
Kubwimana Adrien
  • 2,463
  • 2
  • 8
  • 11