SQL Server timestamp correct -> javascript Date wrong - javascript

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?

Related

Timezones management - server/client - struggling to understand

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?

Retrieving column data in MySQL with data type DATETIME turns the data into ISO format

Logging the date and time after doing a query on one of my tables in MySQL is coming up in ISO format. This becomes a problem because the way that the time is being inserted into the database is from using MySQL NOW() function which looks like it inserts the time in UTC (which in my local time is 5 hours ahead). So when I retrieve the data from the database, now the date is another 5 hours ahead of the UTC time, which makes it slightly difficult to change this time back to my local time.
The format that the date/time is being inserted into the database is: YYYY-MM-DD HH:MM:SS
The example I'm working with is 2019-09-13 00:26:12
I run the query "SELECT * From mytable" from within my code. This query gets put into an array, and I can then access the field by myarray.tempdate.
When I console log this in my application I get 2019-09-13T05:26:12.000Z which looks like it's in ISO format which would add another 5 hours, but why? I'm not sure why when logging this date it treats it as UTC instead of a string, which is what I expected to get. If anyone knows why this is happening I would me much appreciative. Thank You!

Is there a bug in all mysql export file with timestamp on non UTC servers?

Just had to move a sql database from one server over to the other
I understand a timestamp field in MYSQL is stored as an 4byte integer (timezone agnostic) and presented to the user in it current server (mysql server) timezone setting
Am I right?
Now When time changes from summer time to winder time in Europe (UTC+2 to UTC+1) in October, there are times overlapping for one hour.
This makes sense and is not an issue because we 'know' the server knows the difference because it stores thim in unix utc timestamp.
Am I Still right ?
Now when I moved my database export from one database to the other, the timestamp field is not moved as in integer, but as a human readable time string :
just a sample :
(1,'AAAA01',6.50,NULL,NULL,NULL,'2017-07-28 17:38:16',0,NULL,NULL,NULL,NULL,0,NULL),
(2,'AAAA01',6.50,NULL,NULL,NULL,'2017-07-28 20:00:00',1,NULL,NULL,NULL,NULL,0,NULL),
(3,'AAAA01',6.00,NULL,NULL,NULL,'2017-07-28 21:39:07',0,NULL,NULL,NULL,NULL,0,NULL),
(4,'AAAA01',5.50,NULL,NULL,NULL,'2017-07-28 21:42:15',0,NULL,NULL,NULL,NULL,0,NULL),
(5,'AAAA01',5.00,NULL,NULL,NULL,'2017-07-29 12:55:48',0,NULL,NULL,NULL,NULL,0,NULL),
You can see this field :
`received` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
but stored as a human readable field.
How does the receiving server knows if this field is before or after time change (in October)
Timechange happens 2 times a year , In spring it goes forward one hour, so there is no confusion as there is just a one hour gap, but in autumn it goes backwards and 'overwrites' the same hour..
Timezone conversion
How can the Mysql Server even give an answer to this time as it represents 2 different times:
SELECT CONVERT_TZ( '2018-10-28 02:40', 'Europe/Paris', 'UTC' )
The time zone of a MySQL server is only the default time zone used for these conversions. It can be overridden on a per-connection basis. That is what happens, here, to make this work.
When mysqldump queries the server to retrieve the data to write to the backup file, it starts by sending this:
SET TIME_ZONE='+00:00';
This sets the session (connection) time zone for mysqldump's connection to be UTC, which causes those TIMESTAMP columns to be sent by the server in UTC and written that way to the backup file.
Near the top of the dump file, it also adds this:
/*!40103 SET TIME_ZONE='+00:00' */;
The /*! ... */ is not really a comment, even though it looks like one. The !40103 signals any MySQL server version 4.01.03 or later to execute the embedded statement as normal -- thus setting the session time zone on the connection where the dump is being restored to also be UTC so that these timestamps-as-strings are stored correctly.
DATETIME columns do not do these conversions -- only TIMESTAMP... but for TIMESTAMP columns, there should be no incorrect values on the new server. The values in the dump file are UTC -- which is also the native internal storage format's time zone (not technically agnostic at all).
Note also that it is no longer considered a best practice to set the time zone for a server to anything other than UTC. Local times are a presentation issue, best handled by the application, not the database. UTC has no ambiguities like local time zones can -- such as the missing hour in spring and the duplicated hour in the fall, found in many local time zones.

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