Timezones management - server/client - struggling to understand - javascript

I've been reading a whole day today. I want to understand how to manage time in my webapp. So just a few bits of information to begin with: I have Laravel 9 backend and Vue3 frontend - a monolith app.
On the front end, users can create an entry in the database which contains the start and end date.
Now the problematic thing - so I want to make it so that when a user in one country creates the entry, that user will see their local time but if the user in another timezone sees that entry on the website they will see that shifted accordingly to their timezone.
Now if on the front end I am using new Date () in JS to obtain the date like this Tue Dec 27 2022 19:40:08 GMT+0000 (Greenwich Mean Time) and then send it over to laravel I get something like that in database 2022-12-27 19:40:08.
Here is what I know:
UTC is not a timezone but a time system
new Date() called in my JS app in the browser is giving me the local, time-zoned time
Laravel by default uses UTC
Both dates on the frontend and database in Laravel are the same. How that is if once of them is local time and the other one is UTC?
Can anyone explain exactly how does that work from database/js/laravel point of view? Or at least point me to some good resources?
The way I see that is I need to:
create UTC date in JS on the frontend
send it to the LAravel app which will save it in UTC in my db
display it for the user after formatting it on the frontend with Javascript to use local timezone.
It all seems very confusing to me and so far I just managed to get mostly mean comments for not understanding this.
I am mostly interested in understanding what is the correct flow here and how when I send a date from Javascript to the backend, Laravel knows how to deal with it.
Can anyone explain that?

Related

iCalendar start time difference

What is this about
I'm developing a web application in NodeJS to display information about the agenda of the users which are synchronized with the central server of my University. For that, I wrote a script that downloads an ICS file every hour to update my local agenda (stored in an SQLite database).
What seems to be the problem
Someone reported to me that some events in their agenda aren't synchronized properly with the University's version, the start time differs. Here's the problem. I have an Event A and an Event B which are both displayed as starting at 6am UTC on the university web page. But, when I retrieve them from the server in iCal format, they are represented as such (I've removed the properties unrelated to my issue) :
DTSTART:20211108T070000Z <-- starts at 7am UTC
DTEND:20211108T083000Z
SUMMARY:Event A
LOCATION:A room
DESCRIPTION:A description
DTSTART:20211025T060000Z <-- starts at 6am UTC
DTEND:20211025T073000Z
SUMMARY:Event B
LOCATION:A room
DESCRIPTION:A description
What I already tried
I've already tried using an open source application (named OpenWebCalendar) that displays iCal events to a calendar from a URL and it displays just like the University agenda. Both *Event A and B start at 6am UTC.
Unfortunately, I couldn't find how the app did it be looking into its source code.
So this problem doesn't come from the University ical file I retrieve.
I've tried looking into the iCalendar specification document to no avail. I also couldn't find any evidence that this was related to a timezone issue as all datetime values set in the ical file are in UTC format.
So, no problem with the Timezones and I can't find a property or specification that would explain this difference and how to fix it.
I've also written a test script in NodeJS in order to retrieve info about the iCal to no avail using node-ical. The start time displayed when retrieving the events are the same as in the file which doesn't help at all.
Here's the redacted code if you are interested :
const ical = require('node-ical')
let body = `
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//SomeAppName/version 1.0
VERSION:2.0
CALSCALE:GREGORIAN
BEGIN:VEVENT
DTSTAMP:20211010T100331Z
DTSTART:20211108T070000Z
DTEND:20211108T083000Z
SUMMARY:Event A
LOCATION:A room
DESCRIPTION:A description
UID:UniqueCodeA
CREATED:19700101T000000Z
LAST-MODIFIED:20211010T100331Z
SEQUENCE:2128343411
END:VEVENT
BEGIN:VEVENT
DTSTAMP:20211010T100331Z
DTSTART:20211025T060000Z
DTEND:20211025T073000Z
SUMMARY:Event B
DESCRIPTION:A description
UID:UniqueCodeB
CREATED:19700101T000000Z
LAST-MODIFIED:20211010T100331Z
SEQUENCE:2128343411
END:VEVENT
END:VCALENDAR
`
ical.async.parseICS(body, function(err, events){
console.log(events["UniqueCodeA"])
console.log(events["UniqueCodeB"])
})
So, my question is
Is there any iCal specification, properties or any explanation as to why both iCal start times diverge and how to correct them just like OpenWebCalendar does it ?
Welcome to the joys of daylight saving changes and timezones. Somewhere there someone is viewing dates with a timezone set as most people do, this is expected. There are 2 dates there, and it appears one is one side of a daylight saving change and the other is on the other side.
Unlike UTC some timezones have daylight saving and of course timezones don't change from/to daylight saving at the same time, so lots potential for multiple time differences to appear to be inconsistent across events.
If we take London as an example, on the 8 of November 2021, london time is same as UTC time:
https://www.timeanddate.com/worldclock/meetingtime.html?day=8&month=11&year=2021&p1=195&p2=136&iv=0
However on 25 October 2021, at 6am UTC time, London is 7am.
https://www.timeanddate.com/worldclock/meetingtime.html?iso=20211025&p2=195&p3=136
Always check what timezones are set on every device and calendar app and be alert around daylight saving changes.

SQL Server timestamp correct -> javascript Date wrong

We live in the US Central Timezone, so 6 hours behind UTC time. We are storing a timestamp in a SQL Server DB for each comment inserted using CURRENT_TIMESTAMP. When I view the database in SQL Server Management Studio, it shows the correct current CST time. So if I entered a comment right now and my computer time says it is 9:31, the DB would show 9:31 for the comment entered. I'm not sure if that is correct or if it is supposed to be showing the UTC time which according to https://www.timeanddate.com/worldclock/timezone/utc is 15:31 right now.
So I am grabbing out the comment and data from the DB with Node and passing them into our React app. Once in React, I run this code to convert the timestamp to a js Date object: const commentDate = new Date(comment.date);. Now when I console that out is is showing 6 hours behind the current time. So currently I am manually adding 6 hours after converting to a Data object to get the correct time. Obviously this is less than ideal. I imagine after the DST switch, this will no longer be correct.
So where is my issue? Is it the way I am storing it in the DB? Should it actually say 15:31 when I view the DB? Or is it the way I am parsing/converting it when I get it into my javascript?

Time zone issue when using REST Api and JS

I'm using FormatJS library along with Handlebars to display a list of events that occured in the past. I'm calling for an endpoint on my server's REST API which returns me the list of events in Json, with datetimes to display for each event. ATM I'm saving datetimes in the DB using GMT time zone.
So when I'm getting my Json, I'm handling datetimes like this :
{{formatRelative commentDate}}
My issue is, since the datetimes are stocked in GMT, they display also like that. For example, since I'm on a GMT+2 timezone, as soon as a new event is created and shows up on the list, I see it "happened 2 hours ago" while it should be "a few seconds ago".
So, is there a way I can handle this ? Am I making a mistake in saving datetimes in GMT in my DB, and if so, how would you handle datetimes coming from different timezones and displaying them to people in other timezones ?
Of course I could customize the formatRelative helper to play with getTimezoneOffset and get the wanted result, but I wanted to know if there is something better to do.
Thanks a lot ahead !
The key to understanding your question is what you wrote in the comments:
Getting the Json, containing datetimes in the format 2016-02-28 10:15:53 - that's UTC time
You should ensure the value in JSON is in full ISO8601 format, including the appropriate offset or Z character to indicate UTC: 2016-02-28T10:15:53Z
Without the offset, most implementations will consider the value to be represented in local time, which explains your results.
Thus, the problem is with your server-side code, not your JavaScript code. There may be a client-side workaround you could apply when the date string is parsed from JSON, but really the best solution would be to qualify it at the server.

Passing a time zone into a web api call from moment with nodatime

I'm about to go insane dealing with datetime issues and the web.
I have a web server hosted in the Central Time Zone. When clients in the Eastern Time Zone try and schedule an item for a given day using my app, they pass in the value of (for example) 3/14/2015. When we pass the code back to our model, which is sent to the web api, we persist is using something like the code below.
moment.utc($("#mydatepicker").val).hour(0).minute(0).second(0)).toISOString();
This results in a string like the following:
2015-03-14T04:00:00.000Z
When the item is converted back on the server in web api, it converts to
3/13/2015 11:00:00 PM
Logic then strips off time and you can see what happens from here. Since I stripped off the time, it is now the day prior and that is the value persisted to the database.
I need to know some way to send a value from moment, into the web api preferrably as a ZonedDateTime in the client's time zone. I can then convert it to UTC for persistance in the DB.
I've seen things about using NodaTime.Serialization.JsonNet, but I am unclear on how to to use it with Moment and pass it back and forth across web api/ajax.
I need to know some way to send a value from moment, into the web api preferrably as a ZonedDateTime in the client's time zone. I can then convert it to UTC for persistance in the DB.
If that's what you want, then:
In your moment.js code, use .format() instead of .toISOString(), which will still give you an ISO8601 string, but will include the local offset instead of setting it to UTC.
In your ASP.Net code, define your values as a DateTimeOffset (or a noda OffsetDateTime) rather than a DateTime.
However, I don't think that's really what you want. When it comes to dates and times, context is super important. Here, you said you were picking a date from a date picker. When you do that - what time is being chosen by the user? In most cases, they aren't choosing a time - they're just picking a date. But since the JavaScript Date object is really a "date + time" object, it assigns midnight as a default time. Moment is no better in this regard.
Really, converting to UTC doesn't make logical sense when you are just talking about a calendar date. The string value you probably should be sending across the wire should just be a whole date, as in "2015-03-14". My guess is that is what you are starting with anyway. If not, then do moment.utc(yourvalue).format("YYYY-MM-DD") to get it. (Using UTC here is just a way to avoid local time zone issues, like midnight not existing in Brazil on the spring-forward day.)
This corresponds to the NodaTime LocalDate type in your .NET code. If you weren't using Noda Time, you would define the type as a DateTime and just ignore the time portion. In your database, if there's a date-only type available, then use it. For example, SQL Server has a date type.
I'd also encourage you to watch my Pluralsight course, Date and Time Fundamentals - which covers many of these issues.
Regarding using NodaTime.Serialization.JsonNet in WebAPI (so you can use LocalDate directly), in your WebApiConfig.cs file, wire it up like so:
config.Formatters.JsonFormatter.SerializerSettings
.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
Then it should just work.
I would start by sending all dates and times to the server as UTC times. If you store UTC times only then you should be able to show the correct time that something is scheduled on the client side.
When you create your moment on the client side, do you run it out .toDate() first before sending it to the server side? What code are you running on the server side? Is it a .Net WebApi?

SharePoint Dates and JavaScript

I am having some troubles dealing with the SharePoint date system, and I was hoping to find some advice here. The problem I am facing is that every time I use JS to save a new item to my SharePoint list, the date that I pass (simply yyyy-mm-dd, no time included) is saved as a day earlier than I intended. I am almost certain I know why this is- the timezones are different. While I am at -4, the server is at +1. I am not familiar enough with how SharePoint receives and stores dates to know how I should proceed to get the dates to work properly. Any suggestions would be appreciated.
SharePoint datehandling 101 is that it always store the dates in UTC, that is +-0. When using the gui SharePoint automatically translates the time to your local time. Hence, the date and time you get is the UTC version and when saving datetimes through an API you must ensure if the API is localized or not, if it isn't then store the datetime as UTC.

Categories