数据库中的所有内容都以UTC(日期时间)
存储我们有不同时区的人,我们希望在当地时间为他们生成图表。
存储的数据由
组成Id
TimeOfOrder
ValueOfOrder
在存储过程中给出两个日期,我想输出
Date OrderCount OrderValue
2016-01-01 10 30000
因此OrderCount是该日期所有行的COUNT OrderValue是SUM(ValueOfOrder)
这部分我设法使用CTE快速完成了
declare @dtStartDate datetime
set @dtStartDate='2016-01-01'
declare @dtEndDate datetime
set @dtEndDate ='2016-01-31'
;WITH DateSequence([PlotPointDate]) AS
(
SELECT @dtStartDate AS [PlotPointDate]
UNION ALL
SELECT DATEADD(DAY, 1, [PlotPointDate])
FROM DateSequence
WHERE [PlotPointDate] < @dtEndDate
)
SELECT CAST(@dtStartDate AS Date), COUNT(1), SUM(ValueOfOrder) WHERE TimeOfOrder > [PlotPointDate] And TimeOfOrder < DATEADD(d,1,[PlotPointDate])
到目前为止很简单,但是如果我现在想要以非UTC(任何其他时区)获取数据,那么它会变得有点棘手,因为日期并不能很好地对齐。
有任何建议让这个时区有意识吗?
答案 0 :(得分:1)
我传递一个参数,即时区偏移量。建议分钟,因为有些国家是5.5小时。只需将偏移分钟添加到您的CTE
即可答案 1 :(得分:1)
如果要生成历史报告,一般情况下很难正确执行。 UTC的偏差在夏季/冬季变化,但夏令时的规则在历史上发生了变化。
有些州/地区/国家引入了夏令时,然后放弃了它,然后把它带回来。要正确地执行此操作,您需要一个历史数据库,该数据库将UTC转换为过去几年的给定时区。例如,Perth观察到1991年和1992年的时间变化,然后是2006年至2009年。从那以后,它们的时间偏移全年都是UTC + 8。
在Moscow中,到2011年有夏令时变化,然后没有变化,然后在2014年发生了一次变化,此后没有变化。
说了这么多,在SQL Server 2016中有一个新的AT TIME ZONE
子句可以帮助转换时区之间的时间戳。
实际上,我将时间戳存储在本地和UTC时区。生成数据事件时,通常很容易将本地时间转换为UTC,所以我这样做并存储两者。有些报告需要当地时间,有些是UTC。以后对历史数据进行此转换变得更加困难。
如果您需要支持大量时区,这种方法将变得不切实际,但如果您知道您的用户位于几个明确定义的时区,则可能没问题。