给定一个具有DateTime列的sql表和过去3年的大约100k行各种日期(本地时间PST值),将这些列值迁移到
DateTimeOffset的最佳策略是“添加”缺少的utc tz偏移量信息?
现有的DateTime值已被存储,没有任何时区/ utc偏移量的详细信息.存储的日期总是代表太平洋时间(-800或-700,取决于夏令时).目标是追溯地将tz偏移量添加到所有现有数据,假设日期来自太平洋时间(无论正确的偏移量是在当前指定的时间)
>在sql中,这种迁移的最佳做法是什么,而不会丢失任何数据或更改现有值?
>将其转到下一步,使用DateTimeOffset列和值来迁移整个中等大小的数据库(〜100b表,每个表中有2个DateTime列)的最有效的方法是什么?
> PST / PDT切换日期之后的上午2点内记录的数据时间会发生什么?是否有数据丢失发生?
sql Server 2008 C#4.5
如果这不正确的区域请指出我正确的方向,谢谢!
编辑:Yay,赏金时间.
解决方法
夏令时并不总是精确的科学.例如.北美地区使用的时间为
rule change in 2007.因此,建议填写相关日期的表格.例如. 2000 – 2013年:
-- Populate a table with PST daylight saving start/end times -- Example data for 2000-2013 - sourced from -- http://www.timeanddate.com/worldclock/timezone.html?n=137 CREATE TABLE dst (start DateTime,[end] DateTime); INSERT INTO dst (start,[end]) VALUES ('02:00 2 Apr 2000','02:00 29 Oct 2000'); INSERT INTO dst (start,[end]) VALUES ('02:00 1 Apr 2001','02:00 28 Oct 2001'); INSERT INTO dst (start,[end]) VALUES ('02:00 7 Apr 2002','02:00 27 Oct 2002'); INSERT INTO dst (start,[end]) VALUES ('02:00 6 Apr 2003','02:00 26 Oct 2003'); INSERT INTO dst (start,[end]) VALUES ('02:00 4 Apr 2004','02:00 31 Oct 2004'); INSERT INTO dst (start,[end]) VALUES ('02:00 3 Apr 2005','02:00 30 Oct 2005'); INSERT INTO dst (start,[end]) VALUES ('02:00 2 Apr 2006','02:00 29 Oct 2006'); INSERT INTO dst (start,[end]) VALUES ('02:00 11 Apr 2007','02:00 4 Oct 2007'); INSERT INTO dst (start,[end]) VALUES ('02:00 9 Apr 2008','02:00 2 Nov 2008'); INSERT INTO dst (start,[end]) VALUES ('02:00 8 Apr 2009','02:00 1 Nov 2009'); INSERT INTO dst (start,[end]) VALUES ('02:00 14 Apr 2010','02:00 7 Nov 2010'); INSERT INTO dst (start,[end]) VALUES ('02:00 13 Apr 2011','02:00 6 Nov 2011'); INSERT INTO dst (start,[end]) VALUES ('02:00 11 Apr 2012','02:00 4 Nov 2012'); INSERT INTO dst (start,[end]) VALUES ('02:00 10 Apr 2013','02:00 3 Nov 2013');
当然,你可能需要更多的这些 – 将离开做为读者的练习:-)
好的,所以让我们说,你填满了上面的表格,并且你在表格测试的字段dt中有日期/时间.然后,您可以加入上表,并进行如下转换:
-- Convert sample dates to PST offset with daylight saving where appropriate SELECT test.dt,CAST(CONVERT(VARCHAR(23),test.dt,126) + -- Convert to ISO8601 format CASE WHEN dst.start IS NULL THEN '-08:00' -- No record joined so not within DST period ELSE '-07:00' -- DST record joined so is within DST period END AS DateTimeOffset) AS dto FROM test LEFT JOIN dst -- Join on daylight savings table to find out whether DST applies ON test.dt >= dst.start AND test.dt <= dst.[end]
这是一个SQL fiddle demo.