你的位置:首页 > 数据库

[数据库]Azure 上SQL Database(PaaS)Time Zone时区问题处理


在Azure上面的PaaS时间都是以UTC时间为准(云的世界里基本上都是以UTC时间为标准的),所以以前在本地SQL Server上面常用的GetDate()方法会碰到问题,在中国获取的时间会被当前时间少了8个小时,因为Azure上的时间都是UTC之间,中国的时区是+8.所以你通过GetDate()获取的时间少了8个小时是正常的。但是碰到这个问题有什么好办法可以解决呢?怎样才能获取带上时区偏移之后的时间呢?。在Azure SQL Database上面是没有办法直接通过设置某个参数或者变量就可以解决的。不过SQL Database V12之后开始支持SQL Server 2016才支持的一个新的语法:AT Time Zone

Syntax

inputdate AT TIME ZONE timezone

Arguments

inputdate

Is an expression that can be resolved to a smalldatetime, datetime, datetime2, or datetimeoffset value.

timezone

Name of the destination time zone. SQL Server relies on time zones that are stored in the Windows Registry. All time zones installed on the computer are stored in the following registry hive: KEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones. A list of installed time zones is also exposed through the sys.time_zone_info (Transact-SQL) view.

有了这个新的语法之后我们解决这个时区的问题就容易一些了。

假设我们有一张表appcount有两个字段一个是自增长字段id,和另外一个字段是日期型字段Createdate

CREATE TABLE [dbo].[appcount](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [createtime] [datetime] NULL,
    PRIMARY KEY CLUSTERED (Id)
)

通常我们往这个表里面插进去一条数据时会用下面这个语句:

INSERT INTO appcount(createtime) VALUES(getdate())

用来标记着这条记录的创建时间是当前时间的,但是直接在Azure SQL Database上面执行出来会变成这个结果:

image

如果我们在显示这个记录创建时间的时候不带上Time Zone相关的处理,时间就跟当前时间对不上号了。

如果要获取到当前时区的时间的话,我们可以将GetDate()这个方法稍微改一下

INSERT INTO appcount(createtime) VALUES(CONVERT(DATETIME,SYSDATETIMEOFFSET() AT TIME ZONE 'China Standard Time'))

image

从图里我们会发现时间变回了我们想要的本地时间了

 

注意:因为AT Time Zone语法是Azure SQL Database V12的功能,所以如果你的数据库不是V12版本的话是不支持这个语法的,你执行语句是会抛出下面的错误

image

 

老版本的的Azure SQL Datbase解决办法可以参考下面这个博客,通过自定义函数来解决

http://wely-lau.net/2011/07/10/managing-timezone-in-sql-azure-2/