How to store and compare time-zone sensitive times - linq-to-sql

I have a data structure where an entity has times stored as an int (minutes into the day) for fast comparison. The entity also has a Foreign Key reference back to a TimeZone table which contains the .NET CLR ID Name and it's Standard Time/Daylight Time acronyms.
Since this information is stored as time-zone insensitive - I was wondering how in LINQ to SQL I could convert this into a UTC DateTime for comparison against other times that will be in UTC.
Just to be clear this conversion has to be done server-side so that I can execute filtering on the SQL Server and not the client. The reason for this is to ensure we take into account DST for time zones that support it.
I am using .NET 3.5 SP1 and SQL Server 2008.

Ideally, times should be stored in the database in UTC, and only converted to some local timezone (which would include a DST factor where appropriate) for display. This is especially true if "fast comparison" is your goal.
You might find it easiest to add an extra field which contains the UTC time, modify the clients to add this information, and run a script which one-time calculates it for existing entries.

I can store a CurrentOffset field that will need to be updated by a script that will be updated on the hour, every hour to determine the contextual offset.

Related

Synchronizing MySql Server and VB.Net Winform Application

Good day good sirs.
I have a winform application and a Mysql server for the database. In my application, I have several date fields wherein it displays dates of transactions like start date and time. In the application, it is set to follow the date and time of the computer (client) and not the server and when I change the client date and time, it saves as it is and not the server time which compromises data integrity and accuracy. How can i set the client machine to follow the server date and time. Is there any way or techniques to avoid these problem. Like how can i set the appliocation to check if the server and client has thesame date before starting the application. Thanks
When inserting your records in the MySQL database you can use the NOW() function for the datetime field instead of passing in the current datetime from the client machine. NOW() will evaluate on the server and therefore be the server datetime.
https://www.w3schools.com/sql/func_mysql_now.asp
Have you thought about using an EPOCH timestamp?
Unix Time Stamp
Carrying this value instead of datetime values would provide a common base from which to determine the local (client) datetime values.

Pure SQL solution to convert historical DateTime values to DateTimeOffset?

I have a large table with DateTime values that need to be converted to DateTimeOffset.
I can do this by using the following statement, which retains the date/time and adds the current time zone offset.
TODATETIMEOFFSET([StatisticDateUTC], DATENAME(tz, SYSDATETIMEOFFSET()))
The problem is some of these values represent dates years ago, some in daylight savings, some not, so it's actually incorrect to put the current offset in all of them. Some of them should have an offset of -700 some should have an offset of -800.
If the time zone was consistent for all of the values, how can I get the correct offset? I know how this can be done in .net, as there are a nice set of functions to do it, but I need a pure sql solution, no CLR functions.
If you can upgrade to SQL Server 2016, or use Azure SQL Database (v12), then you can use the new AT TIME ZONE function, which is very similar to the TimeZoneInfo.ConvertTime method you may be used to in .NET.
Otherwise, consider a third-party solution, such as my SQL Server Time Zone Support package, which uses standard IANA time zones.
More on both in this related answer.

Is there MySQL equivalent to Oracle's TIMESTAMP WITH TIME ZONE?

Is there MySQL equivalent to Oracle's TIMESTAMP WITH TIME ZONE?
I need to map a Oracle table, which has some columns with that datatype, into a MySQL table but I can't seem to find an easy way to do this without resorting to some MySQL functions.
Thanks and best regards.
No, you'll need to split the data into 2 columns, one a datetime, and the other holding the timezone information. But what you put in the latter field is dependant on what you've got stored in Oracle - the TIMESTAMP WITH TIME ZONE Datatype can contain the TZ offset and (optionally) the time zone region. Obviously the latter is a requirement for the date time to be semantically correct, but IIRC Oracle does not enforce this data being populated.
without resorting to some MySQL functions
Since MySQL doesn't have the datatype, it'll be very difficult to write MySQL function to process it - it's a lot simpler to create a MySQL compatible representation in Oracle where the datatype is supported. You just need to work out what data you've actually got and decide how you want to represent it in MySQL. By convention that means storing it in UTC along with the TZ in a seperate column, then convert it on selection with the convert_tz function (always from UTC)
MySQL always store timestamps as utc. Dates are always stored without timezone information.
You can configure mysql to return values from now() in different timezones.
To store the current offset you need to add this to some column on your own.

grails/mysql timezone change

Whats the best way to accomplish changing the timezone of an app? The way I see it the following must occur:
Server TZ is changed by sys admin
mysql must be restarted.
every time based column in the database must have all values updated, using convert_tz or equivalent. So either a mysql script must be written or a grails script that loads every row for each class, updating all the time fields.
Obviously the server should be taken down while this is happening, and backups must be in place incase of an error.
Is there a better/easier way to do this?
Java does not use time zones when using Dates; it stores everything as UTC and only uses time zones when displaying dates. see the following link for a discussion of java date/time.
http://www.odi.ch/prog/design/datetime.php
If you're using the Date, Time, or DateTime column types in MySQL, time zone does not matter.
If you’re using the TIMESTAMP column type, time zones may matter since the TIMESTAMP is stored as a UTC but has conversion done when both retrieving and storing the values. For a discussion of MySQL time zone behavior see
http://dev.mysql.com/doc/refman/5.1/en/time-zone-support.html .
If you’re worried about synchronizing objects across multiple servers in different time zones things get more complicated, see the following thread for a discussion of this.
http://www.pubbs.net/201006/grails/2500-grails-user-how-to-get-gorm-to-store-dates-as-timestamp-in-utc-by-default-without-a-custom-hibernate-mapping-or-joda-time-plu.html
I know this is an old question but I think it's also pretty timeless... at least, I have stumbled upon it a fair number of times recently... so I thought I would contribute my solution.
First, I am using Grails 2.5.1 and PostgreSQL 9.4 as the backend.
Second, Date fields in Groovy/Grails are stored as timestamp without time zone in PostgreSQL. So it seems to me the first answer above is not actually fully correct - the date is not stored in UTC. This observation got me thinking... along the lines of "well if the database doesn't know what the timezone is, who does"? And the first answer that came to mind was "maybe it's Spring".
Third, the specifics of my problem is that I have a lot of dates that I bootstrapped into the database via BootStrap.groovy and new ThisClass().save(). And because these were dates, not dates + times, they all look like 2005-11-03 00:00:00 as PostgreSQL timestamps (without timezones).
Fourth, what really made the penny drop was when I edited one of my GSPs to include the timezone in the date format string, which showed up as PST (where my server is); and when I included timeZone="Asia/Kolkata" in the g:formatDate of the field in question, the time advanced by 12h30. So pretty clearly my server was running in PST8PDT and since that wasn't PostgreSQL I came back to Spring as the potential place to change things.
Fifth, after reading a few comments about setting the locale in grails-app/conf/spring/resources.groovy I decided to try setting the locale and timezone there, as per:
// Place your Spring DSL code here
beans = {
// from http://stackoverflow.com/questions/1569446/grails-how-to-change-the-current-locale
localeResolver(org.springframework.web.servlet.i18n.SessionLocaleResolver) {
defaultLocale = new Locale("en","IN")
java.util.Locale.setDefault(defaultLocale)
println "configure spring/resources.groovy defaultLocale $defaultLocale"
defaultTimeZone = TimeZone.getTimeZone("Asia/Kolkata")
java.util.TimeZone.setDefault(defaultTimeZone)
println "configure spring/resources.groovy defaultTimeZone $defaultTimeZone"
}
}
I also used g:format timezone="Asia/Kolkata" format="dd MMM, yyyy a z" for all my date fields. And that seems to interpret all data in PostgreSQL timestamp fields in the correct timezone and at the anticipated hour (ie the hour that was entered), even though the dates were first entered "in the wrong time zone".
Sixth, g:datePicker - I read a number of posts about making this "time zone sensitive", but I found that its dates are interpreted as in the timezone used by Spring and so in my case, this is exactly what I need. Conversely, if someone wanted to enter dates in their locale and have Spring convert them on the fly to the server's time zone, I guess that would require some extra effort.
Personally I think it would be really cool if g:datePicker accepted timeZone as a parameter and used it in the same way g:formatDate does.
We had problems with time differences between using GORM and using groovy.sql.Sql (for quicker data import).
GORM was using the grails config timezone (UTC) that we set in the Bootstrap, but groovy sql was using the default system timezone (GMT).
The problem was solved by setting the timezone in the $JAVA_OPTS, although you could add the switch to grails opts or to the run-app command.
grails -Duser.timezone=UTC run-app

MySQL and international dates

Say I have multiple servers in multiple locations and I want to use MySQL's datetime type for the field date and I always want to have the field date have the UTC timestamp so I would execute a UTC_TIMESTAMP() when I add it to the database. Now say I want to have MySQL output the UNIX TIMESTAMP for it.
When I do this on Server A I get the string "2009-06-17 12:00:00" doing the UNIX_TIMESTAMP(STRING) on it gives me the number 1245240000 back. Which is 2009-06-17 12:00:00 in UTC time. Now I do the same thing on Server B.
I get the same string back since its the UTC string but when executing UNIX_TIMESTAMP(STRING) again I get back the wrong number back 1245232800 which is the UTC +2 time. How do I get around this? Should I do the convertion from string to timestamp on the PHP side?
G'day,
I'll ask the obvious here, did you check the date and time on both machines?
Edit: ... and the MySQL timezone was the same on both machines?
Update: Ok. The problem is in the fact that the timestamp string being passed into UNIX_TIMESTAMP is interpreted to be a value in the current timezone which is then converted back to UTC so, because you're in MEZ, two hours is subtracted to return it back to UTC so 7200 is subtracted from your timestamp when it is converted back to a Unix timestring.
Hence, the variation you see when using UNIX_TIMESTAMP() to convert is back to a Unix Epoch timestring.
BTW Shouldn't you be using a TIMESTAMP type for storing off your UTC_TIMESTAMPs instead of DATETIME type?
Update: Decoupling presentation time from stored time is definitely the way to go. You can then reuse the same data all around the world and only have to convert to and from local time when you are presenting the data to a user.
If you don't do this then you are going to have to store off the timezone when the timestamp was made and then go into all sorts of complicated permutations of having to work out if
the local timezone was in daylight saving time when it was stored,
what the difference is between the timezone at the time that the data was stored and the timezone where the data is to be presented.
Leaving it all storeed as UTC gets rid of that.
Most users won't be that happy if they have to work out the local time themselves based on the UTC time returned so systems usually convert to current local time for the user.
This is of course if the user wants the data expressed in local time which is usually the case. The only widely used system I can think of, off the top of my head, that stores and presents its data in UTC is system for air traffic control and flight plan management which are always kept in UTC (or ZULU time to be more precise).
HTH
cheers,
Have you tried doing this?
Execute this instructions together.
SET time_zone = 'UTC';
SELECT FROM_UNIXTIME(0), UNIX_TIMESTAMP('2009-06-17 12:00:00');
// 1970-01-01 00:00:00 1245240000
They only affect the client session, not the server configuration.