我的数据库表中有一个 UNIX 时间戳列,它来自科威特时区的系统。
我的数据库服务器的时区是 Eastern Time US & Canada
.现在我需要使用 SQL 查询将 UNIX 时间戳转换为科威特时区日期值。
谁能告诉我如何将此 UNIX 时间戳转换为科威特时区日期值?
最佳答案
Unix 时间戳是自 1970 年 1 月 1 日 UTC 以来的整数秒数。
假设您的意思是您的数据库中有一个带有此数字的整数列,那么您的数据库服务器的时区是无关紧要的。
首先将时间戳转换为 datetime
类型:
SELECT DATEADD(second, yourTimeStamp, '1970-01-01')
这将是 UTC
datetime
对应于您的时间戳。然后您需要知道如何将此值调整为您的目标时区。在世界上的大部分地区,由于夏令时,单个区域可以有多个偏移量。
不幸的是,SQL Server 无法直接处理工作时区。因此,例如,如果您使用美国太平洋时间,您将无法知道应该减去 7 小时还是 8 小时。其他数据库(Oracle、Postgres、MySql 等)有内置的方法来处理这个问题,但遗憾的是,SQL Server 没有。因此,如果您正在寻找通用解决方案,则需要执行以下操作之一:
xp_regread
获取包含时区数据的 Windows 注册表项,并再次使用一堆自定义逻辑来解析特定日期的偏移量。当然,xp_regread
是一件坏事,需要授予某些权限,并且不受支持或文档。 TimeZoneInfo
的 SQLCLR 函数.Net 中的类。不幸的是,这个requires an "unsafe" SQLCLR assembly ,并可能导致不好的事情发生。 恕我直言,这些方法都不是很好,并且没有直接在 SQL 中执行此操作的好的解决方案。最好的解决方案是将 UTC 值(原始整数或 UTC 中的
datetime
)返回到您的调用应用程序代码,并在那里进行时区转换(例如,在 .Net 中使用 TimeZoneInfo
或其他平台中的类似机制)。但是 - 您很幸运,科威特(并且一直)处于夏令时不会改变的区域。一直是UTC+03:00。所以你可以简单地添加三个小时并返回结果:
SELECT DATEADD(hour, 3, DATEADD(second, yourTimeStamp, '1970-01-01'))
但请注意,这不是适用于任何时区的通用解决方案。
如果需要,您可以返回其他 SQL 数据类型之一,例如
datetimeoffset
,但这只会帮助您反射(reflect)该值对于可能会查看它的人来说是三个小时的偏移量。它不会使转换过程有任何不同或更好。更新答案
我创建了一个项目来支持 SQL Server 中的时区。您可以安装它from here .然后你可以像这样简单地转换:
SELECT Tzdb.UtcToLocal('2015-07-01 00:00:00', 'Asia/Kuwait')
您可以使用 any time zone from the IANA tz database ,包括使用夏令时的那些。
您仍然可以使用我上面展示的方法从 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'
More examples in this announcement.
关于timezone - sql server中从时区到时区的日期时间转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16872007/