【发布时间】:2020-10-05 10:01:02
【问题描述】:
我有一些数据要报告(为简洁起见):
MyDateTime (UTC) MyValue
------ -------
2020-10-01 10:00:00 24
2020-10-01 15:00:00 53
2020-10-02 12:00:00 26
etc
所有日期都存储为 UTC。通常,我会尽可能长时间地保持 UTC 时间,并根据用户的区域设置在用户浏览器中转换为本地时间。
但是对于这个特定的报告,我想按整个日期汇总数据:
SELECT CAST(MyDateTime AS DATE), AVG(MyValue)
FROM MyTable
GROUP BY CAST(MyDateTime AS DATE)
所以我需要在截断MyDateTime 列并聚合它之前将日期转换为用户的本地时间。
在 SQL Server 中,我可以将 UTC datetime 转换为本地截断日期,如下所示:
CAST(CONVERT(datetime2, (SeizeTime AT TIME ZONE 'GMT Standard Time'), 1) AS DATE)
SQL Server 有一个AT TIME ZONE 子句接受的时区名称列表,在我的示例中,我使用的是GMT Standard Time,这是英国时间,包括夏令时。
在浏览器中运行的 Javascript 有另一种命名时区的方式:
console.log(Intl.DateTimeFormat().resolvedOptions().timeZone)
--> Europe/London
所以我的问题是在 SQL Server 和 Javascript 之间没有命名时区的通用方法。如何可靠地将Europe/London 映射到GMT Standard Time,以及世界上所有其他可能的时区?
到目前为止,我的解决方法是:
- 使用硬编码的查找表 - 如果将来时区信息发生变化,可能会中断。
- 将所有预先聚合的数据发送到浏览器,将时区应用于日期,然后在客户端聚合数据 - 我想避免不必要地移动太多数据。
还有其他我想念的方法吗?
【问题讨论】:
-
在客户端使用 var date = new Date('2012-11-29 17:00:34 UTC');日期.toString();将是使用该页面的客户的当地时间
-
@sandeepjoshi 谢谢,但是我如何从浏览器中提取时区信息,将其发送到服务器,并在 SQL Server 中使用它来进行我在问题中询问的聚合?跨度>
-
对不起,我以为您想在客户端执行此操作。我想映射查找表是个好主意,但我想在旧浏览器和 IE11 中不支持它:(。如果您使用与 GMT 的时差转换日期,那么我想您可以发送
new Date().getTimezoneOffset()/60,这会给您带来时区差异以小时数为单位。-ve 值表示国家/地区早于 GMT,正数表示落后。 -
@sandeepjoshi 另一个好主意,但问题是
new Date().getTimezoneOffset()/60会及时为您提供时区偏移量。我正在寻找可能跨越夏令时边界的历史数据。 -
您如何连接到 SQL Server?你有应用层吗?是 .NET、Node.JS 还是其他?
标签: javascript sql-server datetime timezone