Why does Azure lose timezone information in DateTimeOffset fields? - sql-server

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.

Related

Skype persistent chat timestamp converstion

I am building a tool which displays Skype persistent chat information along with participants information. For one of the requirement, I need to filter the tblComplianceParticipant table in a given date range.
I tried many different approaches to convert tblComplianceParticipant.joinedAt column to human-readable format like 'yyyy-mm-dd', etc. but no luck so far. Data in this column are 18 digit numbers, starting with "63" for example 636572952018269911 and 636455769656388453.
These values are also not in 'windows file time' format because https://www.epochconverter.com/ldap gives the future dates with above values.
I tried looking at #JonSkeet's answer on 18 digit timestamp to Local Time but that is c# specific. I tried to replicate similar logic in SQL but no luck.
Is there any way to convert this 18 digit numbers to normal date format and perform where clause on it?
Online converter which gives desired output: https://www.venea.net/web/net_ticks_datetime_converter#net_ticks_to_date_time_and_unix_timestamp_conversion
However, I was looking for underlying logic to convert it myself as I need to perform where clause on it in SQL server stored procedure.
Our Skype administrator provided me with a SQL function (fnDateToTicks) which was part of Skype database (mgc) (Earlier, I didn't have permission so could not see it). I am verifying with him whether it is an internal IP or standard solution by Microsoft so I can share it with the larger community.
The only thing i can think is worth trying:
select CAST ([Timestamp Column] as datetime)
Which will format it as yyyy-mm-dd 00:00:00:000
This may work for SQL Server 2008 and onwards

SQL Query - Change my long date format to DD-MM-YYYY

I have been researching a lot of similar questions on how to convert date format to DD-MM-YYYY but none work for the date format I'm using.
This is the date format I'm working with:
Wednesday, October 14, 2015 5:57 PM
And this IS a "date" field not a text field. I have a feeling that the inclusion of the day of the week is precluding my other attempts from working.
I'm new to SQL so forgive me if I'm overlooking something obvious.
Thank you!
On SQL Server, there are generally four ways to control date formatting.
Control it in your application. Most queries to the database return result sets that are typed. So a datetime column will be of data type datetime or timestamp in your application. You then apply the formatting from your application. The drawback to this is that, well, you wouldn't be asking this question if this were your problem.
Use the CONVERT() function, which allows limited formatting of datetime, datetime2, date, and time fields. SELECT CONVERT(VARCHAR(10),GETDATE(),103) will format the column to dd/mm/yyyy. The drawback to this is that you have to do it for every field you want to format every time you want to format them, and you lose the data typing since you're actually converting them to strings.
Use the SET DATEFORMAT command or the SET LANGUAGE command prior to executing your query. You can execute SET DATEFORMAT dmy; SELECT GETDATE() and your dates will be in dmy format. The drawback here is that you have to run it every time you run a query. Also note that since this returns your columns with data type intact, it's possible that your query analyzer will reformat the dates on you.
If you want to permanently set the date format, then ultimately you need to change the language away from us_english (or whatever the default was that was specified when you installed the server). You can see the list of available language configurations by running exec sp_helplanguage, and you can see the currently configured language for your session by running SELECT ##LANGUAGE. I know it's possible to set up your own languages if you need to, but be aware that's a custom configuration you'd have to deploy if you're running that kind of application.
Language configuration is potentially very complicated, since it's determined by the user, login, database or server, depending on where exactly it's specified. As far as I'm aware, logins inherit the server's default language, and users inherit the database's default language. User language is usually not specifed, but I believe it overrides the login language when present. I've only ever run in configurations where everything was defaulted to us_english, so I've not had much experience with this set up. You can modify it with ALTER LOGIN or ALTER USER, and you can set the default language on the server with sp_configure and on the database with ALTER DATABASE.

How to deal with DateTime and TimeZone in Silverlight?

I am working on Silverlight Application with SQL Azure. As I know if DateTime Kind is Unspecified, Silverlight will change it to Local and it will save to Azure as UTC time.
Everything working as expect but when I get DateTime data from SQL Azure, its Kind is Unspecified and Silverlight does not convert back to Local time when its display on UI.
For example: I use my application in Rome (UTC +1), I set date to 15:00 then save to database. In database it will save as 14:00 (UTC).
Now I open page to edit that data, it query from database as 14:00 with Unspecified kind and it also show 14:00 in page, which obviously incorrect.
I tried to set DateTime kind at DomainService (before return those data to client) by checking if its kind is unspecified, set it to UTC. This time when I change DateTime on my page its kind is always UTC.
It seems like silverlight will convert date only if its kind is Unspecified, otherwise it do nothing, it also can't convert DateTime from database to display properly even those DateTime has Kind.
I want to know, are there any solutions or work around for this problem?
If you know its stored in UTC, have you tried setting datetime, then using having Silverlight explicitly convert to local time? I am not familiar with Silverlight, but in other forms of .NET, you have to do this conversion explicitly for UI operations.
DateTime dt = GetDateFromDB();
dt = dt.SpecifyKind(DateTimeKind.UTC);
DateTime dtAsLocal = dt.ToLocalTime();

about date in database question

i need to find data between 2 date's and time's.
i use one field for date , and one field for time.
is it be better to use only one field for date & time ?
i see that it came in dd/mm/yyyy hh:mm:ss format that
can contain date and time.
this question is for acceess and for sql-server
thank's in advance
In nearly all circumstances, date and time are needed together. Both Access and SQL server have a date/time data type. In Access, even if you specify the format as time, you can show a date. This is because all datetime data is stored as a number, and time is the decimal portion:
Say I store data: 10:31:46, I can type lines in the immediate window that illustrate the storage of datetime, like so:
?CDec(DlookUp("TimeFormattedField", "Test"))
0.438726851851852
?Year(DlookUp("TimeFormattedField", "Test"))
1899
?Format(dlookup("F4", "Table2"),"dd/mm/yyyy")
30/12/1899
This is because zero (0) is a valid date.
It is very easy to get the different portions of a datetime field, so store datetime as a single fields, because that is what you are going to get, anyway.
I like to store date and time separately. In general, I almost never need time in my apps. One case where I store them separately is in some of my logging routines. This is mostly because I only ever query on dates and never on date+time.
If you need to query on both date and time, then storing them separately is really problematic, because then you have to concatenate two fields for comparison, and that means your criteria won't use any indexes on the two fields. This may not be an issue for a few thousand records, but for anything above that, it can quickly become quite a performance drag. It's also a major issue if you're using a server back end, since all the rows will have to be pulled across the wire, instead of Access/Jet/ACE being able to hand off the selection to the server.
depends on the requirement. If you are using sql server 2008+ then if you store in separate is not a problem, as well as it is as easy option to write the query

Invariant dates with WCF RIA Services

Is there any way to prevent Silverlight/RIA Services from converting a datetime object on the wire?
Right now, I see datetimes set to 'Local' or 'Unspecified' being converted to the local time of the server when they are sent over the wire.
For example:
The client and server are both in UTC -04:00:00.
I use DateTime.Today (kind is either Local or Unspecified, it doesn't make a difference) on the Silverlight client. I see 23/08/2010 00:00:00.
I submit my changes and watch the data go over the wire. The field is expressed at 23/08/2010 00:00:00 (-04:00:00).
Great. Now I change my client to be in UTC +12:00:00
I use DateTime.Today on the client and now I see 24/08/2010 00:00:00.
HOWEVER - I submit my changes and watch the data again. Now I see 23/08/2010 08:00:00 (-04:00:00).
So it is apparent that the serializer is converting to the local time of the server, which I do not want. The value I want in the DB is 24/08/2010 00:00:00.
Using UTC is not a great option for this field as the database is part of our legacy application and the column contains invariant dates at this time. I don't want to start inserting UTC datetimes alongside the existing data.
Any ideas?
Thanks in advance
If I create the DateTime like this, it works:
new DateTime(DateTime.Now.Ticks, DateTimeKind.Unspecified).Date;

Resources