Timezone difference of browser and server - javascript

I have been using momentjs for detecting timezone of user (client side). I have PHP timezone_identifiers_list() function for server timezone list.
Issue I am facing right now is, momentjs is returning timezone as 'Asia/Calcutta' and PHP is returning it as 'Asia/Kolkata'. Both are same but giving me a reverse effect.
Is there any way to match both these? Any help will be much appreciated.

Try using UTC and then adding or subtracting time on/off based on location.

I have not used moment.js, but looking at the documentation http://momentjs.com/timezone/ it seems as you can get the time in zulu time.
dec.tz('Asia/Calcutta').format('ha z');
// where dec is your moment time.
In php you can do the same-ish
echo gmdate('H', strtotime(time()));
// this should return the + or - hours your server time is from UTC/zulu
With those two values you can calcluate what time it is at the user.

Related

How to convert UTC time on server side to be users local time on a GET request?

I am trying to check if the date of the last time an element was clicked is equal to the current date. The current date is being created by the server and is 5 hours ahead of my local time, so at a certain time of day, the code stops working correctly because the program thinks it's now the next day.
Here is the code that is causing issues on my server side:
let todaysDate = new Date().toString().split(' ').splice(0, 4).join(' ')
let todaysDateMs = new Date(todaysDate + ', 00:00:00').getTime()
Promise.all([
Habits.updateMany({}, {
$set: {
todaysDate,
todaysDateMs
}
}),
Habits.updateMany({ lastClicked: { $ne: todaysDate } }, {
$set: {
clicked: 'false'
}
}),
The date that is being stored inside todaysDate is in UTC time and is 5 hours ahead. When it compares lastClicked (which is sent along with a PUT request from the client side in their local time) to todaysDate, it is setting clicked to false incorrectly because of the discrepancy between the timezones.
I am wondering if I can tell the server to create a date in the users local time or any way that I can work around this issue so that the two dates are the same. I don't want specific timestamps included, only the day, month and year.
Have you tried something like Moment.js? It makes dealing with things like this a lot easier. Check out their documentation or tutorals like this.
Generally, times on servers are done in UTC and only at the client is it converted to/from their time zone. This removes the need for the server to know anything about the client's time zone.
The client will need to send their time zone along with the lastClicked time. Then your server can read this time and adjust for time zone automatically. One example is to send the time in ISO 8601 format 2023-02-07T18:25:19-05:00 where the -05:00 indicates that this time is 5 hours behind UTC.
Alternatively, the client can pre-convert the timestamp their sending to UTC. JavaScript provides ways to do this, as do libraries such as Luxon.
Date values in MongoDB are stored as UTC time - always and only. You should never store date/time values as string, it's a design flaw.
I your case I suggest a 3rd party library like moment.js, Luxon or Day.js
They provide functions like DateTime.now().setZone('America/New_York').startOf('day').toJSDate();
With these functions it should be fairly easy to solve your requirements.

how to subtract php date from Javascript date

I create project with php Laravel framework and VueJS and I want to get the difference between server time and client time to process some data time out by Javascript in the client browser.
How can i do that?
I need to change the format of one of the dates to be available to manage by other language functions and property.
how to sub (minus) Carbon::now() got from php api Date.Now() in JS.
I do that to get the difference between client clock and the server.
In order to "speak" in dates, the best practice is to work with timestamps.
The server can have its own timezone offset which is why it is best that it will expose any managed dates in UTC.
The client, on the other hand, will need to convert the UTC timestamp to its locale date, which can be done by adding its timezone offset.
Having said that - you will probably want to calculate the data timeout on the server, since the client can be bypassed, thus exposing a timed-out data to potential hackers.
Hope this helps :)

The date 2019-04-01T00:00:00.000Z gives me previous month (March, not April)

So, I have the 1st day of month as 2019-04-01T00:00:00.000Z
When I use moment(date).month(), it returns me 2, not 3.
So, I receive March, not April.
What is the problem with it, and why I receive the previous month from the date? Maybe the problem in the TimeZone? Because my TimeZone is GMT-4, so, maybe this is problem?
Should I use UTC or ISO string instead to work with the date?
Like you mentioned, your timezone is GMT-4. The date that you are providing is in UTC. The 'Z' at the end stands for Zulu time, which is the same as UTC.
momentjs will convert this to local time.
How to handle this all depends on what you need the date for.
If this is a date that you saved somewhere before on a server, it might be important to add the correct timezone to it when you are saving it.
Be careful if you let a server create these dates, because the server might be running in a different timezone than your client.
If you create a new Date() in JS it will return a date object with the current time of your local time. If this happens on a server that's running in a different timezone, or in UTC (for example Docker containers), it will create a date in that timezone.
The best way to solve this is to think about your exact use case.
There are tons of articles written about handling dates and it's not easy.
If you have some time, this podcast helps to explain how dates work and will help you to get a better understanding of dates in general:
Coding Blocks - Why Date-ing Is Hard

UTC offset from server to client

In our application we are Saving the UTC DateTime in DataBase. Client (javascript) is sending the datetime in Local TimeZone and at controller level we are converting it to UTC time before saving the date in Database.
Both the client and servers are on different timezones.
we are fetching date from database in UTC Using Entity Framework with
DateTime.SpecifyKind(_CreatedDate, DateTimeKind.Utc);
So should we again convert the DateTime to local DateTime at controller or should we handle all the DateTime conversion logic at the client.
When sending DateTime instances to the server conversion conversion to UTC should happen as early as possible. In this case by the client and as your client is javascript you can use the method toUTCString. If you are using momentjs you can use utc.
When receiving DateTime instances from the server conversion conversion to local time should happen as late as possible. Make sure that persisted dates/retrieved dates are in UTC when you create them. Again, it is the client that should be converting them to local date time instance.
Finally send all datetime instances between client and server using ISO8601 format. Momentjs, javascript's date object, json.net all can do this. This ensures nothing is lost and no cultural specific bugs are introduced.
As to why it should be handled at the client is very simple, its easiest to do it there. Only the client truly knows its timezone, this is usually very difficult to "guess accurately" on the server side. The only reason not to do this is if you wanted to store a users timezone info with their profile but even this can get very tricky (what happens if the user travels or if they move location, etc).
As to how to persist you can use either a DateTime type or a DateTime with offset type (the true type names depend on the RDBMs you are using). Which one you choose should depend on if it is important to know the offset from utc at the moment it was saved. So far I have not had a need to do this but maybe it is important for you. It has no influence on the actual point in time as a DateTime should represent the UTC point in time and with offset should represent the local time with offset to get back to the UTC point in time.
Here's the way we do it in our projects. In my opinion, you should be using datetimeoffset in your database. This allows you to be able to identify what timezone the date was saved in. Then, when you send your date from your client to your server, just make sure it's sent in datetimeoffset.
When you send the datetimeoffset from the server to the client, you can do the conversion on the client side. I don't think anybody would argue that MomentJS Timezone is the best library for this. Look over it and give it a shot.
http://momentjs.com/timezone/
Elaborating on DateTimeOffset
DateTimeOffset is another datatype like datetime except datetimeoffset adds an hour offset to determine the timezone. For instance, let's say you're in Central Timezone and you want to save the time 08:00 am. Well, in Datetimeoffset, it would be something like 08:00:00:00 -04:00 declaring that the offset was -4 (central timezone). This makes it easy because you don't have to do any math in your head when reading it and you really don't have to do any conversions (let MomentJS do it for you). When you read it, you will always know that "Oh, it was 08:00 am for whomever saved the time, and it looks like they saved it in Central timezone."
Since it's quite relative when is the "Proper" time to convert.
The only absolute rule i think is valid is this one.
UTC time is the only Real meaningful data
Any other conversion to any timezone is just a "Display" for me
So follow the same rules as you would with the rest of your data.
Like converting a Boolean to a Checkbox on the view.Or sending that checkbox value as Boolean to the server.
And that's the soonest it Reaches or Leaves the UI.

Moment js utc() time in london - BST

I'm using momentjs lib to updated text on some ajax action. What I need to do is to set a current date & time in london. I'm using moment.utc() function but because of the summer time I'm one hour out.
For example running this on 14:26
console.log( moment.utc().format('HH:mm:ss') );
I'm getting 13:26:53.
Any idea on how to fix this?
Can you use momentJS timezone?
moment().tz('Europe/London');
EDIT: In case you try to use this without seeing the link, it's a separate library you have to include.
If you want the local time instead of the UTC time, just use moment() instead of moment.utc(). You're specifically asking for UTC, so you shouldn't be surprised when you get UTC :)
From the documentation:
By default, moment parses and displays in local time.
If you want to parse or display a moment in UTC, you can use moment.utc() instead of moment().
This brings us to an interesting feature of Moment.js. UTC mode.
While in UTC mode, all display methods will display in UTC time instead of local time.
This is assuming you always want the user's local time. If you want a specific time zone (London) which may not be the user's time zone and isn't UTC, then you should use the library indicated by Takuya's answer. I would think carefully before doing so though - while it may be a sensible approach, you should at least validate that first. It's often reasonable to display a time for user U1 in the time zone of user U2 - but here you're using a fixed time zone. That's only appropriate if you know that U2 will always be in London. It would be really confusing if actually U2 is in some other zone - either the same as or different to U1.

Categories

Resources