date时间从时区转换到SQL Server中的时区
我的数据库表中有一个UNIX时间戳列,它来自科威特时区的一个系统。
我的数据库服务器的时区是Eastern Time US & Canada
。 现在我需要使用SQL查询将UNIX时间戳转换为科威特时区date值。
谁能告诉我如何将这个UNIX时间戳转换成科威特时区的date值?
Unix时间戳是自1970年1月1日UTC以来的整数秒数。
假设你的意思是你的数据库中有一个整数列,那么你的数据库服务器的时区是不相关的。
首先将时间戳转换为datetime
types:
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'
本公告中更多的例子。