3

Context: I have a server hosted on a VM in the cloud. When using just the moment library to initialize dates I always get a date which has +- some hours. After a quick research, I found the moment-timezone library which should solve this issue but I have some problems.

I have the following date: "transactionDate": "2020-08-25 18:30:00" which gets submitted.

My code now looks like this where moment is the moment-timezone library now:

  const momentTransactionDate = moment.tz(transactionDate, "YYYY-MM-DD HH:mm:ss", "Europe/Bucharest");

  const formattedTransactionDate = momentTransactionDate.format(
    "YYYY-MM-DD HH:mm:ss"
  );

This will output the following values:

    "momentTransactionDate": "2020-08-25T15:30:00.000Z",
    "formattedTransactionDate": "2020-08-25 18:30:00",

For testing, I'm just doing a request from Postman to the local server. Why is the momentTransactionDate 3 hours before, and why is the format() function formatting a different hour?

Could someone explain how this is working?

iDaniel19
  • 75
  • 7

1 Answers1

0

The momentTransactionDate object is specified to be in Bucharest time, so it will be three hours ahead of UTC time (in DST at the moment, https://www.timeanddate.com/time/zones/eest).

I'm presuming that you've logged something like this:

console.log( { momentTransactionDate: momentTransactionDate.toISOString(), formattedTransactionDate});

toISOString() outputs the UTC time of the date, so this is exactly what we'd expect. 18:30 in Bucharest (at this time of year) corresponds to 15:30 UTC time.

And to parse UTC dates we can use a timezone name of "UTC":

const transactionDate = "2020-08-17 17:30:00";
const momentTransactionDate = moment.tz(transactionDate, "YYYY-MM-DD HH:mm:ss", "UTC");

const formattedTransactionDate = momentTransactionDate.format(
    "YYYY-MM-DD HH:mm:ss"
);

console.log("momentTransactionDate.toISOString():", momentTransactionDate.toISOString());
console.log("formattedTransactionDate:", formattedTransactionDate); 
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.25/moment-timezone-with-data-10-year-range.js"></script>
Terry Lennox
  • 29,471
  • 5
  • 28
  • 40
  • I've logged the `toString()`. Thank you, it does make sense. Maybe I'm doing it wrong. I'm trying to keep the same date as the one that I pass in when I create the `moment` object. How can I achieve that? I think that depending on where the server is hosted, when the moment object is created my hours get that +- time off that I'm trying to solve. – iDaniel19 Aug 17 '20 at 14:58
  • I'd imagine you wish to use UTC time, is that correct, e.g. the transaction date is in UTC? – Terry Lennox Aug 17 '20 at 15:23
  • 1
    I'm a bit confused. I think the answer is yes. The transaction date comes from a datepicker or from an imported document. I don't really care about timezones. I would like to keep it as is – iDaniel19 Aug 17 '20 at 15:48
  • Ok, yes, well dates, times and timezones are always confusing :-). The question is, if the user picks a transaction date of 2020-08-17 17:30, do we mean 17:30 in their local time, or do we mean 17:30 UTC. I'll add some code to parse UTC dates just for fun! – Terry Lennox Aug 17 '20 at 16:02
  • Yes, when 17:30 is selected we mean 17:30 UTC, we don't care about the local time. Thank you for your time. Without the `moment-timezone` library the default of `moment` is to select the local time, meaning no `UTC` and that's why I have the issues? – iDaniel19 Aug 17 '20 at 16:19
  • 1
    That's correct, moment will assume the date is in the local time of the server, unless the 'Z' UTC zone indicator is at the end. – Terry Lennox Aug 17 '20 at 16:38
  • You can always indicate UTC time either in the Date or moment.js constructor by passing an ISO formatted date with the Z timezone, e.g. "2020-08-17T18:00:00Z", this might be another way to solve your issue. – Terry Lennox Aug 17 '20 at 16:44
  • 1
    Thank you. The approach `moment.tz(transactionDate, "YYYY-MM-DD HH:mm:ss", "UTC"); ` is indeed working. As for `2020-08-17T18:00:00Z`, probably the date parsing format has to be changed as well to take the `T`(time?) and `Z`(zone?) into account. Even if the moment object is initialized with that, after I call the .format function it will still return a date which has +- some hours - probably the difference between UTC and the server. – iDaniel19 Aug 18 '20 at 06:05
  • 1
    Great, glad to see we have a solution! Apologies, you're right, even if we initialize a Date / moment with a UTC timestamp, it's still a local time. You can however use moment.utc('2020-08-17T18:00:00Z') and it should do what you wish. – Terry Lennox Aug 18 '20 at 06:33