Home > Software engineering >  Keep local date in UTC
Keep local date in UTC

Time:10-30

So I have a front end app built with React, and a backend with .Net (C#). I have this problem of time conversion being 1 day behind.

So in my frontend, the date is correct, in Local time format, and when the API(backend, C#) receives the data, it converts the date into UTC which makes it 1day behind.

when I try to get the diff of localdate to UTC date it results to 0 using moment. I want to keep the date in even though it's in UTC.

CodePudding user response:

I would suggest using UTC times to communicate dates from the frontend to the backend. They are unambiguous and will not depend on what timezone the user is in.

You can either use Unix time, the number of seconds / milliseconds since 1 January 1970 00:00 UTC, e.g. 1635494392 or ISO 8601, a well-defined string encoding of date and time, e.g. 2021-10-29T08:27:22Z.

I recommend using ISO 8601 dates since they're much easier to eyeball than unix dates. They're also supported by native JS date objects and all time/date libraries.

If you send a date like 2021-10-29T08:27:22Z to the backend, it won't need to be converted to UTC and no ambiguity exists.

Likewise, when the frontend receives a date from the backend, using an ISO UTC date will mean the date will be parsed and understood unambiguously.

It's also easy to convert to local time, using Date.toLocaleString() for example. This will display in the user's local timezone by default, but you can display in any timezone using the argument { timeZone: 'xxx' }.

For example:

const timestampFromBackend = '2021-10-29T08:27:22Z';
const dateFromBackend = new Date(timestampFromBackend);

console.log('Date from backend (UTC):', dateFromBackend.toLocaleString([], { timeZone: 'UTC'}));
console.log('Date from backend (local):', dateFromBackend.toLocaleString());

// We can display in any timezone if we wish
console.log('Date from backend (Pacific Time):', dateFromBackend.toLocaleString([], { timeZone: 'America/Los_Angeles'}));
.as-console-wrapper { max-height: 100% !important; top: 0; }
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

Likewise, we can always convert a frontend date to an ISO UTC date, using Date.toISOString():

const frontEndDate = new Date();
const dateToBackend = frontEndDate.toISOString();

console.log('frontEndDate:', frontEndDate.toString() );
console.log('ISO string to send to backend:',dateToBackend);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

A very simple solution to that is to create a date object at the frontend before you send the request, like:

var dt = new Date();

and send that to the server. On the server you can measure the date in UTC as well, compute the difference of the two, round it to the nearest possible valid timezone value (beware that some time zones, like Afghanistan if I remember correctly have an offset of not whole hours, it is some 3 hours 30 minutes distance from UTC I believe) and add that offset into whatever dates were sent.

So, besides the actual times your frontend sends to the server, measure the actual time and send that as well and on the server see its distance from UTC.

This is still not 100% accurate, because if some dates are distant from the time of the request sending and DS (Daylight Saving) offsets are also involved, then you might be off with an hour in some cases.

If this inaccuracy is worrysome, then we need to add some complication to the solution, namely, in that case you might need to get the location of the user on frontend. Beware that they do not have to allow that, so this might be inaccessible. However, if you know their location, then you know their timezone as well. And using their timezone you can accurately convert any date from that timezone to UTC.

  • Related