处理 UTC、时区并使用 LocalTime 对其进行 GROUP BY
我被困住了。需要帮助。
我将 UTC 日期存储在数据库中。
示例行:
GenerateAt:
- 2011-06-08 23:30
- 2011-06-09 03:30
- 2011-06-09 15:30
我的用户的当地时间是 -2 小时(中欧)。当我想要 09 开始的行时,我有 3 行。
问题在于用于报告目的的 GROUP BY day 。我有 1 代表 08 年,2 代表 09 年,但对于我的当地时间来说,情况并非如此。
我到处都看到:“以 UTC 格式存储数据”。如何正确地做到这一点?
更新1:
对于数据访问,我使用 NHibernate,并且我更喜欢独立于数据库引擎的解决方案。所以,我正在寻找诸如日期/时间维度表(或类似的东西)之类的解决方案。
我的数据表具有如下列:
- GenerateAt(日期时间)
- GenerateAt_Year(int)
- GenerateAt_Month(int)
- GenerateAt_Day(int)
- GenerateAt_Hour(int)
感谢我可以轻松地按以下方式分组:年,年+月,年+月+日,年+月+日+小时。不幸的是,这是 UTC。 :(
如何重构这个解决方案来处理用户时区?
I'm stuck. Need help.
I store UTC dates in database.
Example rows:
GeneratedAt:
- 2011-06-08 23:30
- 2011-06-09 03:30
- 2011-06-09 15:30
Local time for my user is -2 hours (Central Europe). When I want rows from 09 then I have 3 rows.
Problem is with GROUP BY day for reporting purposes. I have 1 for 08 and 2 for 09 but this is not true for my local time.
Everywhere I see: "store data in UTC". How to do this properly?
UPDATE 1:
For data access I'm using NHibernate and I prefer solution independent of the database engine. So, I'm looking for solution with something like Date/Time Dimension table (or something like that).
My data table has columns like this:
- GeneratedAt (datetime)
- GeneratedAt_Year (int)
- GeneratedAt_Month (int)
- GeneratedAt_Day (int)
- GeneratedAt_Hour (int)
Thanks to that I can easily grouping by: year, year+month, year+month+day, year+month+day+hour. Unfortunately this is UTC. :(
How to refactor this solution to deal with user timezones?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以创建该表的视图,通过应用 DATEADD 函数提供所需中欧时区的日期时间值。
因此,如果您的表列是:
id, other_id, evt_time
,那么 select 语句(用于视图定义)将是:
那么您可以使用该视图并将
GROUP_BY
应用于evt_time_ce
列You could create a view of that table which provides the datetime value in the desired Central Europe timezone by applying a DATEADD function.
So if your table columns are:
id, other_id, evt_time
then the select statement (for the view definition) would be:
then you can use the view and apply the
GROUP_BY
to theevt_time_ce
column我一般也有类似的问题,但我的时差是8小时。
我使用
dateadd(hour,
8, [Timestamp])
选择当地时间,然后使用dateadd(hour, -8
, @dateFrom)
在 WHERE 子句中 - 这也适用于 GROUP BY。例如:
I have a similar issue in general, but my time difference is 8 hours.
I use
dateadd(hour,
8, [Timestamp])
to select the local time, anddateadd(hour,
-8, @dateFrom)
in WHERE clauses - which should work for GROUP BY as well.For example:
SQL Server 2016 引入了
AT TIME ZONE
可以帮助解决此问题,包括处理夏令时。AT TIME ZONE
允许您在 Windows 注册表中列出的时区之间转换日期。您可以通过运行简单的 SELECT 来查看可用的时区:下面的 SQL 将 UTC 存储的日期转换为另一个时区的日期
因此,根据本地时区按天分组的 SQL 可能如下所示:
如果您想了解更多内容,这里有一篇关于该主题的好文章。
SQL Server 2016 has introduced
AT TIME ZONE
that can help with this, including handling daylight savings time.AT TIME ZONE
lets you convert dates between time zones listed in the windows registry. You can see what timezones are available by running a simple SELECT:Here's the SQL that converts your UTC stored date into a date at another timezone
So your SQL to group by day based on a local timezone might look something like this:
Here's a good article about the topic if you want to read more.