date时间从时区转换到SQL Server中的时区

我的数据库表中有一个UNIX时间戳列,它来自科威特时区的一个系统。

我的数据库服务器的时区是Eastern Time US & Canada 。 现在我需要使用SQL查询将UNIX时间戳转换为科威特时区date值。

谁能告诉我如何将这个UNIX时间戳转换成科威特时区的date值?

Unix时间戳是自1970年1月1日UTC以来的整数秒数。

假设你的意思是你的数据库中有一个整数列,那么你的数据库服务器的时区是不相关的。

首先将时间戳转换为datetimetypes:

 SELECT DATEADD(second, yourTimeStamp, '1970-01-01') 

这将是与您的时间戳相对应的UTC datetime时间。

那么你需要知道如何调整这个值到你的目标时区。 在世界的大部分地区,由于夏令时,单个地带可以有多个偏移量。

不幸的是,SQL Server无法直接处理工作时区。 所以,如果你使用美国太平洋时间,你将无法知道你是否应该减去7小时或8小时。 其他数据库(甲骨文,Postgres,MySql等)有内置的方式来处理这个,但唉,SQL Server不。 所以,如果您正在寻找一个通用的解决scheme,您将需要执行以下操作之一:

  • 将时区数据导入到表中,并将该表作为时区规则更改。 使用该表与一堆自定义逻辑来解决特定date的偏移量。

  • 使用xp_regread获取包含时区数据的Windowsregistry项,并再次使用一堆自定义逻辑来parsing特定date的偏移量。 当然, xp_regread是一件坏事,需要授予某些权限,并且不受支持或文档。

  • 编写一个在.Net中使用TimeZoneInfo类的SQLCLR函数。 不幸的是,这需要一个“不安全的”SQLCLR程序集 ,并可能导致不好的事情发生。

恕我直言,这些方法都不是很好,没有好的解决scheme直接在SQL中做这个。 最好的解决scheme是将UTC值(原始整数或UTC的datetime时间)返回到调用的应用程序代码,然后进行时区转换(例如,使用.Net中的TimeZoneInfo或其他类似的机制平台)。

然而,你已经幸运了,因为科威特是(而且一直)在一个夏时制不变的地区。 它始终是UTC + 03:00。 所以你可以简单地添加三个小时并返回结果:

 SELECT DATEADD(hour, 3, DATEADD(second, yourTimeStamp, '1970-01-01')) 

但是要认识到,这不是一个通用的解决scheme,可以在任何时区使用。

如果你愿意的话,你可以返回其他SQL数据types之一,比如datetimeoffset ,但是这只能帮你反映出这个值是三个小时的时间偏移到任何人看的。 它不会使转换过程有任何不同或更好的。


更新的答案

我创build了一个在SQL Server中支持时区的项目。 你可以从这里安装它。 那么你可以简单地转换如下:

 SELECT Tzdb.UtcToLocal('2015-07-01 00:00:00', 'Asia/Kuwait') 

您可以使用IANA tz数据库中的任何时区 ,包括使用夏时制的那些时区。

您仍然可以使用上面显示的方法从unix时间戳转换。 把它们放在一起:

 SELECT Tzdb.UtcToLocal(DATEADD(second, yourTimeStamp, '1970-01-01'), 'Asia/Kuwait') 

再次更新

在SQL Server 2016中,现在内置了AT TIME ZONE语句对时区的支持。 这在Azure SQL数据库(v12)中也是可用的。

 SELECT DATEADD(second, yourTimeStamp, '1970-01-01') AT TIME ZONE 'Arab Standard Time' 

本公告中更多的例子。