I have recently updated my system to record date/times as UTC as previously they were storing as local time.
I now need to convert all the local stored date/times to UTC. I was wondering if there is any built in function, similar to .NET's ConvertTime
method?
I am trying to avoid having to write a utility app to do this for me.
Any suggestions?
I do not believe the above code will work. The reason is that it depends upon the difference between the current date in local and UTC times. For example, here in California we are now in PDT (Pacific Daylight Time); the difference between this time and UTC is 7 hours. The code provided will, if run now, add 7 hours to every date which is desired to be converted. But if a historical stored date, or a date in the future, is converted, and that date is not during daylight savings time, it will still add 7, when the correct offset is 8. Bottom line: you cannot convert date/times properly between time zones (including UTC, which does not obey daylight savings time) by only looking at the current date. You must consider the date itself that you are converting, as to whether daylight time was in force on that date. Furthermore, the dates at which daylight and standard times change themselves have changed (George Bush changed the dates during his administration for the USA!). In other words, any solution which even references getdate() or getutcdate() does not work. It must parse the actual date to be converted.
We can convert ServerZone
DateTime
to UTC and UTC to ServerZoneDateTime
Simply run the following scripts to understand the conversion then modify as what you need
Note: This(
AT TIME ZONE
) working on only SQL Server 2016+ and this advantage is automatically considering Daylight while converting to particular Time zoneHere's my quick and dirty version. I know all of my dates were using the US Eastern time zone. You can change the offset or otherwise make it smarter as you need to. I was doing a one-time migration so this was Good Enough.
With SQL Server 2016, there is now built-in support for time zones with the
AT TIME ZONE
statement. You can chain these to do conversions:Or, this would work as well:
Either of these will interpret the input in Pacific time, properly account for whether or not DST is in effect, and then convert to UTC. The result will be a
datetimeoffset
with a zero offset.More examples in the CTP announcement.
Depending on how far back you need to go, you can build a table of daylight savings times and then join the table and do a dst-sensitive conversion. This particular one converts from EST to GMT (i.e. uses offsets of 5 and 4).
Unless I missed something above (possible), all of the methods above are flawed in that they don't take the overlap when switching from daylight savings (say EDT) to standard time (say EST) into account. A (very verbose) example:
Simple hour offsets based on date and time won't cut it. If you don't know if the local time was recorded in EDT or EST between 01:00 and 01:59, you won't have a clue! Let's use 01:30 for example: if you find later times in the range 01:31 through 01:59 BEFORE it, you won't know if the 01:30 you're looking at is [3 or [6. In this case, you can get the correct UTC time with a bit of coding be looking at previous entries (not fun in SQL), and this is the BEST case...
Say you have the following local times recorded, and didn't dedicate a bit to indicate EDT or EST:
Times [2] and [3] may be in the 5 AM timeframe, the 6 AM timeframe, or one in the 5 AM and the other in the 6 AM timeframe . . . In other words: you are hosed, and must throw out all readings between 01:00:00 and 01:59:59. In this circumstance, there is absolutely no way to resolve the actual UTC time!