TSQL Convert DateTime & Timezone Offset (in Minutes) to another Time Zone - sql-server

In my SQL Server 2008 R2 database, I have a LastHWScan column (datetime) and a TimzoneOffset column (int).
The LastHWScan column stores the datetime that is local to the workstation being scanned. The TimezoneOffset column stores the timezone offset as either a positive or negative number of minutes. Dallas is -300, Bucharest is 180.
How can I, in a SQL query, convert these datetime from various timezones to Dallas time?
Would it be easier to convert everything to UTC and then convert it to Dallas time?

In my SQL Server 2008 R2 database, I have a LastHWScan field (datetime) and a TimzoneOffset field (int).
That's fine, though you might also consider that SQL Server has a datetimeoffset field which can combine these into a single type.
Or, if the time zone offset is unimportant to your scenario, you might consider storing just the equivalent UTC value in a datetime or datetime2 field.
The LastHWScan field stores the datetime that is local to the workstation being scanned. The TimezoneOffset field stores the timezone offset as either a positive or negative number of minutes. Dallas is -300, Bucharest is 180.
Be careful here. The offset should be aligned to the specific date and time. Dallas may be -300 (UTC-5) in the summer when DST is in effect, but most of the year it's -360 (UTC-6). Likewise, Bucharest alternates between 180 (UTC+3) and 120 (UTC+2).
Do not detach the offset from the date/time, or assume that the offset for one location and date/time is valid for all possible other date/time values within that location.
How can I, in a SQL query, convert these datetimes from various timezones to Dallas time?
That's difficult to do in SQL, because you have to account for the daylight saving time rules of Dallas. Other DBs have functions like CONVERT_TZ, but SQL Server doesn't have anything like that built in. You can write your own functions, or you might consider my SQL Server Time Zone Support project.
Would it be easier to convert everything to UTC and then convert it to Dallas time?
"Easier" is subjective. Many people prefer storing values in UTC. Storing them in a datetimeoffset (or in two fields like you have done) is fine - and it's preferable when the local time is important in the context of the application domain (See DateTime vs DateTimeOffset). The only thing that you shouldn't do is drop the offset and store only local time.
Even if you did convert to UTC, that wouldn't help with the conversion. Though you've properly identified a specific instant in time, you still have to account for time zone rules of the destination time zone. If you only need US Central time, you might consider hardcoding the transition rules and offsets into a UDF or stored proc. Otherwise, use my time zone integration project with the "America/Chicago" time zone id.
Example:
SELECT Tzdb.UtcToLocal(dateadd(mi, -offset, localdatetime), 'America/Chicago')
Note the negation of the offset to convert from local back to UTC before calling the custom UDF.

Related

How to get timezone offset from the timezone name

I have a timezone name like America/Vancouver saved in a SQL Server database.
I want to get the UTC offset from the timezone name in SQL like America/Vancouver has -08:00 offset. So how can I write a query in SQL?
Your help is much appreciated
Unfortunately SQL Server doesn't yet support IANA time zone identifiers (like America/Vancouver) directly. For now, the best option is to convert from the IANA identifier to a corresponding Windows time zone identifier in your application layer, and store that in your SQL Server.
For example, if you are running .NET in your application layer you can use my TimeZoneConverter project:
string tz = TZConvert.IanaToWindows("America/Vancouver");
// Result: "Pacific Standard Time"
Then you can use the AT TIME ZONE function in your SQL Server code:
SELECT sysdatetimeoffset() AT TIME ZONE 'Pacific Standard Time'
The above will give you the current date, time, and offset in the given time zone, which you can use as the basis for your query against the user's availability (mentioned in the question comments).
Keep in mind that the offset adjustment will be different depending on whether daylight saving time is in effect or not. Despite the word "Standard" in the Windows identifier, DST is indeed taken into account where applicable.
Alternatively, if for some reason you must do this entirely in SQL Server without converting to Windows time zones, then you will need to rely on projects such as my SqlServerTimeZoneSupport project. That one is a bit old and not very well maintained, so I recommend against that approach if you can help it.
Use DATEPART with TZ parameter. Example :
SELECT DATEPART(tz, (CAST('2021-01-01' AS DATETIMEOFFSET) AT TIME ZONE 'Central European Standard Time'));
The result is in minutes.

Correct way to handle dates in SQL Server when only datetime is available

We use a PLM software called "Aras Innovator" and need to store a date as a custom item property. The software uses Microsoft SQL Server to store its data and accessing properties on the database level is officially supported.
However, our issue is that the software only supports datetime, not date.
And dates are stored in UTC - so when we store "2020-01-01" from a client in Central Europe, it becomes "2019-12-31 23:00" or so in the database (1 hour before midnight on the day before). And queries checking for ">= 2020-01-01" then consequently fail to find these rows.
The software manufacturer says:
There is no standard feature for storing only the month and day; a
quick option may be to store it as a string instead and do
programmatic validation on the inputted string if required.
Regarding direct SQL queries, all dates are stored in UTC for
compatibility with multiple time zones. They are automatically
converted when accessed via the standard API. When accessing direct
with SQL, you can use the function ConvertToLocal described in the
Aras Innovator 11.0 - Configuring Internationalization guide on the CD
Image, section 5.3:
SELECT item_number, innovator.ConvertToLocal(created_on, 'Eastern
Standard Time') AS CreatedOn FROM innovator.Document
ConvertFromLocal can be used for specifying dates you wish to query
against rather than requiring those dates to be sent in UTC.
I'm not convinced that working with string would be a good solution.
But not convinced that their "ConvertTo/FromLocal" functions would be a good solution either.
Surely there must be some other way to handle this directly in SQL Server?
SQL Server 2016 introduced the AT TIME ZONE statement.
Consider:
SELECT CONVERT(date, TheDateTime AT TIME ZONE 'UTC'
AT TIME ZONE 'Central Europe Standard Time')
The above will first convert TheDateTime field from a datetime or (datetime2) to a datetimeoffset type with zero offset (UTC). Then it will convert it to the Central Europe Standard Time zone, and lastly will convert it to a date type, removing any time information.
As far as your statement:
... >= 2020-01-01" then consequently fail to find these rows.
You should consider instead converting the opposite direction such that you are querying against UTC time - which would be sargable. For example:
SELECT ...
WHERE TheDateTime >= CONVERT(datetime,
'2020-01-01' AT TIME ZONE 'Central Europe Standard Time'
AT TIME ZONE 'UTC')
Of course, you could do the whole right-side of the expression ahead of time and use a local variable instead. Likewise, if you are calling this query from an application, you could convert to UTC in your application code and not have to bother doing it in SQL Server at all.

MS SQL to Excel - Timezones

I have
an SQL Server 2012, where datetime fields are stored in UTC time
an Excel File, that is integrated via ADO DB command objects to the SQL server
a function to check the current system settings, which allows to see the current system's difference to UTC
I need to display dates/times in Excel in local time (varies).
Until SQL Server 2016 (which we can't currently upgrade to), there is no Timezone support built-in to T-SQL.
There are various options that are playing around in my head, but I can't decide which one is worth pursuing:
- transmit the current time difference as a parameter to the Stored Procedure, and amend all date fields to apply that difference
- retrieve the UTC times, and return the field(s) as a formula (so instead of return field, field, created, modified I might return field, field, =fnUtcToLocal(#created#)... and so on
- retrieve UTC times, and use an adjacent formula (with QueryTable.FillAdjacentFormulas)
Regardless of the option, I've still got a problem left: When, for example, checking the system difference now in Excel when the user is in Eastern Standard Time, it is -5 hours. When my created date falls into the EDT time, the correction would still be -5 instead of -4 hours.
Does anyone have a smart idea on how I should approach this? Please let me know if any additonal detail is required.

Convert stored utc dates to datetimeoffset datatype

We have thousands of historical UTC datetimes stored in a SQL Server database and we now want to change those columns to use the datetimeoffset datatype (currently datetime)
So I have altered the columns and changed the datatype. Now they all have a '+00:00' offset.
Since we are in NZ, I'm guessing next we would just update the data using SWITCHOFFSET with a '+12:00' offset?
However, that won't take into consideration DST, which makes the offset '+13:00' during DST periods?
Is there anyway to do this in SQL without a mapping table to DST switchover dates for the historical period?
Thanks
Keeping them as +00:00 is perfectly fine. However, if you want to project them to a particular time zone (including DST calculation), you can use the SwitchZone method from my SQL Server Time Zone Support project.
UPDATE yourtable SET dto = Tzdb.SwitchZone(dto, 'Pacific/Auckland')

Microsoft SQL Server 2005 time of day data type

Is there a data type which represents time of day? Such as a datetime data type without the date.
when i format 41 seconds into a datetime data type this is what I get:
1/1/1900 12:00:41 AM
I'm trying to store a duration of time in a table.
In SQL Server 2008, there is a Time data type which only stores the time. In versions of SQL Server prior to 2008, your only choice is the DateTime data type (and SmallDateTime) which stores both the date and the time. However, there are means in most languages including T-SQL to show the time portion. What are you trying to accomplish?
Not in 2005 no, there are plenty of discussions around on this subject.
This being just one of them

Resources