【问题标题】:Migrate SQL Server DateTime column to DateTimeOffset将 SQL Server DateTime 列迁移到 DateTimeOffset
【发布时间】:2010-01-05 19:27:44
【问题描述】:

我有一个旧表,其中有几行有一个日期时间列。我想将其切换为datetimeoffset,但我希望能够传输已经存在的数据。所以我正在做类似的事情:

SET IDENTITY_INSERT Table_Temp ON

INSERT INTO Table_Temp
    (Col0, ... ColN,)
SELECT 
    COl0,.... ColN, from 
Table_Original;
    
SET IDENTITY_INSERT Table_Temp OFF

这可行,但是当我执行 datetimedatetimeoffset 分配时,偏移量设置为 0。幸运的是,我想设置的偏移量是当前系统的偏移量。我似乎想不出一个简单的方法来做到这一点。

我希望能够在转换中设置偏移量。我打算使用 C# 实用程序(或 PowerShell),但我宁愿保持简单。

【问题讨论】:

  • --- 谢谢大家,我应该很清楚,我只是想添加偏移量而不改变时间本身。但是你们让我到了那里! ;)

标签: sql sql-server tsql sql-server-2008 datetimeoffset


【解决方案1】:

请参阅下面的文档,您可能想要类似的内容:

-- up here set the @time_zone variable.

INSERT INTO Table_Temp
    (Col0, ... ColN,)
SELECT 
    COl0, TODATETIMEOFFSET(COLDATE, @time_zone),.... ColN, from 
Table_Original;

来自MSDN

SWITCHOFFSET 函数调整 将 DATETIMEOFFSET 值输入到 指定时区,同时保留 UTC 值。语法是 SWITCHOFFSET(datetimeoffset_value, 时区)。例如,以下 代码调整当前系统 时区 GMT 的 datetimeoffset 值 +05:00:

选择 SWITCHOFFSET(SYSDATETIMEOFFSET(), '-05:00');

所以如果当前系统 datetimeoffset 值为 2 月 12 日, 2009 10:00:00.0000000 -08:00,这 代码返回 2 月 12 日的值, 2009 13:00:00.0000000 -05:00。

TODATETIMEOFFSET 函数设置 输入日期的时区偏移量和 时间价值。它的语法是 TODATETIMEOFFSET(日期和时间值, 时区)。

此功能不同于 SWITCHOFFSET 有几种方式。第一的, 它不限于 datetimeoffset 值作为输入;相当 它接受任何日期和时间数据 类型。第二,它不尝试 根据时区调整时间 源值之间的差异 和指定的时区但是 而是简单地返回输入日期 和指定时间的时间值 zone 作为 datetimeoffset 值。

主要目的 TODATETIMEOFFSET 函数是 转换非时区类型 知道给定的 DATETIMEOFFSET 时区偏移。如果给定日期 时间值是 DATETIMEOFFSET, TODATETIMEOFFSET 函数更改 DATETIMEOFFSET 值基于 相同的原始本地日期和时间 值加上新的给定时区 偏移量。

例如,当前系统 datetimeoffset 值为 2 月 12 日, 2009 10:00:00.0000000 -08:00,而你 运行以下代码:

选择 TODATETIMEOFFSET(SYSDATETIMEOFFSET(), '-05:00');

2009 年 2 月 12 日的值 返回 10:00:00.0000000 -05:00。 请记住,SWITCHOFFSET 函数于 2009 年 2 月 12 日返回 13:00:00.0000000 -05:00 因为它 根据时间调整时间 输入之间的区域差异 (-08:00) 和指定的时区 (-05:00)。

如前所述,您可以使用 TODATETIMEOFFSET 函数与任何 日期和时间数据类型作为输入。为了 例如,以下代码采用 当前系统日期和时间值和 将其作为 datetimeoffset 值返回 时区 -00:05:

选择 TODATETIMEOFFSET(SYSDATETIME(), '-05:00');

【讨论】:

  • 对此诉旧帖子的评论。时区和日期时间的偏移量是不同的。时区考虑夏令时,而偏移量只是偏移量。
【解决方案2】:

如果您使用的是知道 datetimeoffset 类型的 SQL Server 版本,则此语法将用于获取服务器的本地 tz 偏移量:

select datepart(tz,sysdatetimeoffset())

结果以分钟为单位。

【讨论】:

  • 谢谢你,正是我需要的。现在他们使用了太多重叠的术语,甚至搜索文档都变得困难......
【解决方案3】:

如果 DST 保存在目标时区处于活动状态,这些转换功能将无法正常工作,因为时区偏移量在同一年内发生变化。

【讨论】:

  • 考虑到夏令时,您将如何正确执行?
  • 不是真的回答 - 更适合发表评论。
【解决方案4】:

你可以用下面的方法弄清楚当前SQL server的偏移量是多少。

select datediff(MI,getdate(), getutcdate())

您需要以分钟而不是小时为单位获取偏移量,因为有许多半小时甚至四分之一小时的时区。

使用分钟值,您可以使用类似的东西来更改您的值(假设它们在历史上都记录为当地时间)

select dateadd(mi,datediff(MI,getdate(), getutcdate()), yourDateField)

为了提高效率,我会将其计算为一个变量并使用它,因为差异不会改变。

【讨论】:

  • 如果您需要考虑夏令时,这不适用于历史日期。对?您正在根据 getdate 查找当前的 UTC 偏移量,然后将其添加到历史日期字段。但是,如果您想考虑 DST,偏移量会发生变化。东部标准时间是 UTC-5,但东部夏令时间是 UTC-4。如果要转换历史日期,则必须注意夏令时转换。 (想想就头疼)。
  • 改正,然后批量转移历史数据,然后考虑每个年份的转移时间点不同。
  • 你将如何找到历史日期的偏移量?
【解决方案5】:

这是已经提供的答案的轻微变化,不考虑 DST 的变化。但是,它对于许多用途可能已经足够了:

dateadd(minute, -datepart(tz, sysdatetimeoffset()), @legacyDatetime)

【讨论】:

    【解决方案6】:

    对于任何试图正确解决这个问题的人来说,在这里考虑 DST 是解决问题的工具。

    https://github.com/mj1856/SqlServerTimeZoneSupport

    【讨论】:

      猜你喜欢
      • 2013-08-15
      • 1970-01-01
      • 1970-01-01
      • 2019-09-25
      • 1970-01-01
      • 2019-09-02
      • 2018-11-10
      • 2012-03-12
      • 2011-06-24
      相关资源
      最近更新 更多