Azure 上SQL Database(PaaS)Time Zone时区问题处理(进阶篇)
通常ISV在面对本地客户时对时间相关的处理,一般都时区信息都是不敏感的。但是现在云的世界里为了让大家把时间处理的方式统一起来,云上的服务都是以UTC时间为准的,现在如果作为一个ISV来说就算你面对的客户只是本地用户但是你打算利用云来为你进行的应用提供更多的功能和便捷性时,你就需要采用UTC时间来处理跟相关的代码了。
在SQL Server数据库处理时间相关的数据时,我们常常会使用DateTime类型或者DateTime2类型来处理数据,其实早在SQL Server 2008发布时,数据库就开始支持DatetimeOffset数据类型了,DatetimeOffset天生出来就是为了处理时区问题的
参考上一个Blog 《Azure 上SQL Database(PaaS)Time Zone时区问题处理》,我们同样要来解决时区的问题,我们创建appcount表时,我们采用下面语句
CREATE TABLE [dbo].[appcount2]( [Id] [int] IDENTITY(1,1) NOT NULL, [createtime] [datetime] NULL, [CreatetimeWithOffset] [Datetimeoffset] NULL, PRIMARY KEY CLUSTERED (Id) )
插入数据时使用
INSERT INTO appcount(createtime,createtimewithoffset) VALUES(GetDate(),sysdatetimeoffset() AT TIME ZONE 'China Standard Time')
插入完数据我们将数据在查询出来
我们会发现DateTimeOffset在处理时区问题时不管带不带时区的迁移语句的出来的时间都是正确的,但是DateTime字段的出来的时间明显就会有时间偏移错误。
我们用下面的C#从.NET程序里面将这些时间数据取出来会如何呢?
using (IDbConnection conn = new System.Data.SqlClient.SqlConnection(strConn)) { conn.Open(); var command = conn.CreateCommand(); command.CommandText = "Select id,createtime,CreatetimeWithOffset from appcount"; var reader = command.ExecuteReader(); while (reader.Read()) { var id = reader["id"]; var date = reader["createtime"]; var date2 = reader["createtimeWithOffset"]; var localDate = ((DateTimeOffset)date2).LocalDateTime; Console.WriteLine("id:{0},createtime:{1},DateTimeInOffSet:{2},localdate:{3}", id, date,date2, localDate); } reader.Close(); conn.Close(); }
这里是代码执行结果:
小结:
采用DatetimeOffset来存储时间,通过DatetimeOffset来处理时间可以让你的代码更加稳健,更加国际范