I make a habit of storing in UTC time, and then converting when displaying, or getting input form the user. It makes things a lot easier and more manageable. I have yet to try a large project with the new offsets data type, but worried about how they will handle daylight savings time, which is a constant source of frustration for Australian Developers (Disclaimer: I come from Queensland where our cows don’t like it either).
Most of the time we handle the conversion in the Application or Presentation layer, I don’t like to encourage developers to handle it in the SQL layer because this is the most common place of doing comparisons and means you have more opportunity for Developer error when one side of your comparison is in the wrong Time Zone.
However there are a few cases where it is needed so today I whipped up a project that is backwards compatible to SQL 2008 R2 (the earliest version running in prod systems i work on).
GitHub Link here https://github.com/HostedSolutions/SQLDates
it basically re-advertises the TimeZoneInfo object, wrapped up specific to what I use which is going back and forth from UTC to what ever time zone my users are in.
Most of my projects are either multi-tenanted, or have users in different states in Australia that need to view data in their own timezone.
Going to UTC below (i.e. form user input in a text box).
[Microsoft.SqlServer.Server.SqlFunction] public static SqlDateTime ConvertToUtc(SqlString dotNetTimeZone, SqlDateTime theDateTime) { var localDate = DateTime.SpecifyKind((DateTime)theDateTime, DateTimeKind.Unspecified); // create TimeZoneInfo by string time zone. var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(dotNetTimeZone.ToString()); // convert date local to utc date by time zone. return TimeZoneInfo.ConvertTimeToUtc(localDate, timeZoneInfo); }
Coming from UTC below (i.e. form data in a database table)
[Microsoft.SqlServer.Server.SqlFunction] public static SqlDateTime ConvertToLocalTimeZone(SqlString dotNetTimeZone, SqlDateTime theDateTime) { // create TimeZoneInfo by string time zone by time zone. var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(dotNetTimeZone.ToString()); // convert date utc to local date. return TimeZoneInfo.ConvertTimeFromUtc((DateTime)theDateTime, timeZoneInfo); }
The DataTools SQL projects these days are great, you just need to add a reference into your C# library from your SQL project, and it’ll compile into the SQL script that generates for deploy, examples are all in the github project.
Just noting that you can’t compile a C# class library for 3.5 in a SQL Data Tools project, you need to create an external C# class library project, because 3.5 reference in the SQL projects have some issue with mscorlib.
After adding the reference you also need to also set it to “unsafe”
Then when you publish the Class with output like the below into your deployment script:
CREATE ASSEMBLY [SQLDatesFunc] AUTHORIZATION [dbo] FROM 0x4D5A90000300000004000000FFFF0000B8000000000000004000... WITH PERMISSION_SET = UNSAFE;
I’ve also included a post deploy script in this example code with the other settings you need to get you database going with CLR functions
sp_configure 'clr enabled', 1 GO RECONFIGURE GO ALTER DATABASE [$(DatabaseName)] SET TRUSTWORTHY ON; GO
Pingback: Automated SSRS Report Deployments from Octopus | beerandserversdontmix
its very good i can now create clr with dll file 🙂
LikeLike
it’s good i can now create clr with dll file 🙂
LikeLike