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.
Related
We're working on a IOS app using Microsoft's Azure Mobile Services. The web GUI creates date-time as DateTimeOffset fields, which is fine. But when we have the mobile put datetimes into the database, then read them from the database, via Entity Framework, we're seeing them adjusted to UCT. (We see the same thing when we view the records in SSMS.)
I've always been frustrated by the lack of timezone support, in SQL's standard datetime types, and I'd thought that DateTimeOffset would be better. But if I wanted my times in UTC, I'd have stored them in UTC. If a user enters a time as 3:00 AM, CST, I want to know he entered CST. It makes as little sense to me to convert it to UTC, and throw away the offset, as it did to assume that 3:00 AM CST and 3:00 AM PDT were the same.
Is there some kind of database configuration I can do to keep the Azure database from storing the dates in UTC?
The issue is that at some point in Azure Mobile Services, the property is converted to a JavaScript Date object, which cannot not retain the offset.
There are a couple of blog posts describing this issue, and possible workarounds:
https://blogs.msdn.microsoft.com/carlosfigueira/2013/05/13/preserving-date-time-offsets-in-azure-mobile-services/
http://michele-colombo.it/2014/11/azure-mobileservices-how-to-properly-save-datetimeoffset-with-offset/
Essentially, they both take the same approach of splitting out the offset into a separate field. However, looking closely at these, they both make a crucial mistake:
dto.DateTime.ToUniversalTime()
Should actually be:
dto.UtcDateTime
The DateTime of a DateTimeOffset will always have DateTimeKind.Unspecified, and thus ToUniversalTime will assume the source is local, rather than using the offset of the DTO.
There are a few other similar errors I see in the code in these posts, so be careful to test thoroughly. However, the general approach is sound.
We're using a Node.js backend and noticed the same thing with DATETIMEOFFSETs read from our SQL Server database being returned in UTC regardless of the offset. Another alternative is to convert the DATETIMEOFFSET at the query-level so that it is outputted as a string with the timezone information. The following converts a DATETIMEOFFSET(0) field to the ISO8601 format; however, other possible styles can be used as documented here:
SELECT CONVERT(VARCHAR(33), [StartDate], 126) AS [StartDate] FROM [Products];
The new output is now: "2016-05-26T00:00:00-06:00" instead of "2016-05-26T06:00:00+00:00"
Of course, this means that the client must serialize the string into their respective format. In iOS, the ISO8601 library can be used to read the output as either a NSDateComponents or NSDate.
One benefit of this approach is that any database-level checks or triggers can do date comparisons using the DATETIMEOFFSET instead of trying to take into account a separate offset column with a basic DATETIME.
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.
I have recently starter working with sql server instead of mysql.
I have a time column which I've noticed stores time as such: hh:mm:ss:nnnnnnn
Thing is I only want to to store hh:mm:ss, and I can't seem to figure out how to do that.
I do apologize if this is really obvious, I have had a long day and my searches did not return anything that helped.
time has a precision parameter which is "fractional second precision" so if you need hh:mm:ss you have to use time(0) as datatype
use the Time datatype which is available since 2008 onwards
If on SQL 2008, use the time datatype, and just store the hh:mm:ss; the nanoseconds will be 0. Just display the value back in the desired format in your presentation layer.
If on SQL 2005 (or older), you'll need to store the data as a datetime, and input the date version as some constant (usually 1900-01-01). Again, format the data at the presentation layer, not at the database.
Is there a function in SQL Server that will convert a DateTime saved as UTC time to the local time? The problem is that I have times saved as UTC times, and I used to calculate time zone offset as
select #tzoffset = datediff(mi,SYSDATETIMEOFFSET(),SYSDATETIME())
and adding that to my UTC times, which worked fine until daylight saving came.
As that selects the current time zone offset, the calculation is invalid for pre-DST values.
As the dates are rendered in ASP.NET web form, I have worked around the issue by rendering the dates as TimeZoneInfo.ConvertTimeFromUtc((DateTime)Eval("maxtime"), TimeZoneInfo.Local), which works automagically.
Is there something similarly elegant in T-SQL?
It is not that simple. Read this http://blogs.msdn.com/b/bartd/archive/2009/03/31/the-death-of-datetime.aspx
I transfer data from one SQL Server to another using SELECT * INTO .... statement (in Management Studio). Both databases have different timezone settings.
Is it possible to adjust all date/time fields to different timezone automatically? Maybe some query parameters or connection settings?
Since you are on SQL Server 2008, you could use the built-in functionality of the DATETIMEOFFSET datatype, and the SWITCHOFFSET function.
You could do something like:
INSERT INTO dbo.YourTargetTable( ...... )
SELECT
SWITCHOFFSET(TODATETIMEOFFSET(YourSourceTime, '+04:00'), '-09:00'),
.......
TODATETIMEOFFSET converts your "regular" date without any timezone information into a DATETIMEOFFSET type with a time zone (of your source location), and then you can apply a SWITCHOFFSET call to that value to "switch" your date/time to your target location's time zone.
This can be done in the scope of the INSERT....SELECT statement - no separate "row-by-row" updating necessary.
I think this will be helpful, please follow the link:
Effectively Converting dates between UTC and Local (ie. PST) time in SQL 2005
Shortly, you do need to build time zone and DST tables to get some help with time zones.
Thanks