![]() |
1
10
如果它们都是本地的,那么这里是偏移量:
您应该能够使用以下方法更新所有数据:
这会起作用吗,还是我遗漏了这个问题的另一个角度? |
|
2
74
我不相信上面的代码会起作用。原因是它取决于本地时间和UTC时间的当前日期之间的差异。例如,在加利福尼亚州,我们现在使用的是PDT(太平洋夏令时);此时间与UTC之间的时差为7小时。如果现在运行,所提供的代码将为希望转换的每个日期增加7小时。但是,如果转换了历史存储日期或将来的日期,而该日期不在夏令时期间,则当正确的偏移量为8时,它仍将添加7。底线:您不能仅通过查看当前日期在时区(包括不遵守夏令时的UTC)之间正确转换日期/时间。您必须考虑转换的日期本身,以及夏令时是否在该日期生效。此外,白天和标准时间的变化日期也发生了变化(乔治·布什在为美国执政期间改变了日期!)换句话说,任何引用getDate()或getutcdate()的解决方案都不起作用。它必须分析要转换的实际日期。 |
![]() |
3
36
使用SQL Server 2016,现在有了内置的时区支持,
或者,这也可以:
其中任何一个都将解释太平洋时间的输入,正确说明DST是否有效,然后转换为UTC。结果将是
|
![]() |
4
16
如前所述,在SQL Server中没有执行时区规则感知日期转换的内置方法(至少从SQL Server 2012开始)。 您基本上有三个选择来正确执行此操作:
虽然SQL Server不提供执行时区规则感知日期转换的工具,.NET框架提供了,只要您可以使用SQL CLR,就可以利用它。 在Visual Studio 2012中,请确保已安装数据工具(否则,SQL Server项目不会作为选项显示),然后创建新的SQL Server项目。 然后,添加一个新的SQL clr c用户定义函数,称之为“converttoutc”。Vs将为您生成锅炉板,其外观应如下所示:
我们想在这里做一些改变。首先,我们要返回
您的修订代码应如下所示:
在这一点上,我们准备尝试一下。最简单的方法是在Visual Studio中使用内置的发布工具。右键单击数据库项目并选择“发布”。设置数据库连接和名称,然后单击“发布”将代码推送到数据库中,或者单击“生成脚本”(如果要为后代存储脚本,或将位推送到生产环境中)。 一旦您在数据库中拥有了UDF,您就可以看到它在运行:
|
![]() |
5
6
下面是一个测试过程,它将我的数据库从本地时间升级到了UTC时间。升级数据库所需的唯一输入是输入本地时间从UTC时间偏移到@offset的分钟数,如果时区需要通过设置@applydaylightsavings进行夏令时调整,则输入@applydaylightsavings。 例如,美国中央时间将输入@offset=-360和@apply daylight savings=1,持续6小时,是应用夏令时调整。 支持数据库功能
升级脚本
|
![]() |
6
4
如果必须将今天以外的日期转换为不同的时区,则必须处理夏令时。我想要一个不需要担心数据库版本、不需要使用存储函数以及可以轻松移植到Oracle的解决方案。 我认为沃伦在获得夏令时的正确日期方面走上了正确的道路,但为了使其更适用于多个时区和国家的不同规则,甚至是2006年至2007年在美国发生变化的规则,上述解决方案在此有所不同。注意这不仅有美国的时区,还有中欧。中欧在4月的最后一个星期日和10月的最后一个星期日之后。你还将注意到,美国在2006年遵循的是4月的第一个星期日,10月的最后一个星期日规则。 这个SQL代码看起来可能有点难看,但只需复制粘贴到SQL Server中并尝试一下。请注意,有三个部分用于年份、时区和规则。如果你想再过一年,就把它加到年会上。对于其他时区或规则也是如此。
对于规则,在第一个、第二个、第三个或最后一个星期日使用1、2、3或l。“日期”部分给出了规则类型L的月份,具体取决于规则、月份的第一天或月份的最后一天。 我把上面的查询放到一个视图中。现在,只要我想要一个时区偏移或转换为UTC时间的日期,我就加入到这个视图中,并选择以日期格式获取日期。我将这些转换为datetimeoffset,而不是datetime。
|
![]() |
7
2
这是我的快速和肮脏版本。我知道我所有的约会都在使用美国东部时区。您可以更改偏移量,或者根据需要使其更智能。我做过一次迁移,所以这就足够了。
|
|
8
1
除非我错过了上面提到的(可能的)东西,否则上面所有的方法都有缺陷,因为它们在从夏时制(比如EDT)切换到标准时间(比如EST)时不考虑重叠。(非常详细)示例:
基于日期和时间的简单小时偏移不会减少它。如果你不知道当地时间是在01:00到01:59之间记录在EDT或EST中,你就没有线索了!例如,让我们使用01:30:如果您在01:31到01:59范围内找到以后的时间,您将不知道您正在查看的01:30是[3还是[6]。在这种情况下,您可以通过一点编码获得正确的UTC时间来查看以前的条目(在SQL中不是很有趣),这是最好的情况… 假设您已经记录了以下当地时间,并且没有专门指出EDT或EST:
时间[2]和[3]可能在上午5点的时间范围内,也可能在上午6点的时间范围内,或者在上午5点的时间范围内,或者在上午6点的时间范围内。…换言之:你被冲洗了,必须在01:00:00到01:59:59之间扔掉所有的读数。在这种情况下,绝对没有办法解决实际的UTC时间! |
|
9
0
下面的工作原理是,它计算正在运行的服务器的日期和utc date之间的差异,并使用该偏移量计算传递给它的任何日期的UTC等效值。在我的示例中,我尝试在澳大利亚阿德莱德将“2012年11月1日06:00”的UTC等效值转换为-630分钟,如果将其添加到任何日期,将导致任何本地日期的UTC等效值。 选择dateadd(分钟,datediff(分钟,getdate(),getutcdate())和'1-nov-2012 06:00') |
![]() |
10
0
根据您需要往回走多远,您可以构建一个夏令时表,然后加入该表并进行DST敏感转换。这个特殊的方法将EST转换为GMT(即使用5和4的偏移量)。
|
![]() |
11
0
我们可以转换serverzone
只需运行以下脚本来理解转换,然后根据需要进行修改
注释
这个:
|
![]() |
12
0
Matt Johnson's answer 绝对是Microsoft SQL Server 2016+中的最佳方法。但他建议在时区使用的确有一个弱点需要注意。无法确定DST结束时与UTC之间的正确偏移量。据我所知,没有可能的方法来解决这个问题。考虑下面的例子。
默认的Microsoft SQL Server行为是假定输入的日期值偏移量为-05:00。然而,根据DST是否结束,这一时间实际上可以表示-05:00或-06:00偏移。没有附带的偏移量是无法确定的,因此Microsoft SQL Server猜测哪些偏移量可能是正确的,哪些偏移量可能不正确。 |