我有一个插入过程作为其中一个值通过GETDATE()
,因为每个插入插入时也存储。这是托管在使用GMT的SQL Azure上。如何将GMT(UTC)datetime转换为本地日期时间?
现在,当我收到消息时,我在他们的时间戳列中为每个人存储了GMT日期,如何将此日期转换为当地的datetime
,无论您身处何处?
谢谢。
我有一个插入过程作为其中一个值通过GETDATE()
,因为每个插入插入时也存储。这是托管在使用GMT的SQL Azure上。如何将GMT(UTC)datetime转换为本地日期时间?
现在,当我收到消息时,我在他们的时间戳列中为每个人存储了GMT日期,如何将此日期转换为当地的datetime
,无论您身处何处?
谢谢。
你可以做这样的事情:
declare @InputUtcDateTime datetime2 = '2011-05-20 06:30:18'
declare @LocalDateTime datetime2 = dateadd(minute, datepart(TZoffset, sysdatetimeoffset()), @InputUtcDateTime)
print @LocalDateTime
或
declare @InputUtcDateTime datetime2 = '2011-05-20 06:30:18'
declare @LocalDateTime datetime2 = dateadd(minute, datediff(minute, sysutcdatetime(), sysdatetime()), @InputUtcDateTime)
print @LocalDateTime
对于MST作为一个例子......考虑到每个DTM被存储在格林尼治标准时间已经,它简化了的东西..
SWITCHOFFSET(CONVERT(DATETIMEOFFSET, [ColumnName]), '-07:00')
现在,如果您的本地日期/时间不是GMT/UTC,您可能需要使用以下...
SWITCHOFFSET(TODATETIMEOFFSET([ColumnName], datepart(tz,sysdatetimeoffset())),'+00:00')
下面是故障。
SWITCHOFFSET
- 将DateTimeOffset值转换为不同的时区,同时保留偏移量。TODATETIMEOFFSET
- 将DateTime值转换为指定时区的DateTimeOffset值。DATEPART
- 在这种情况下获取本地日期时间的时区部分。'+00:00'
- 目标偏移量,在第二个示例中是UTC/GMT目标,从本地...前一个示例是MST。注意/警告:我不相信这会占用夏令时,这可能是您的问题。如果绝对保存不是必需的,您可能只需添加一个辅助列,并进行粗略转换并安全地前进。
您可能想将逻辑抽象为一个函数调用,以便说明DST的保留情况......但这不应该太过困难。
这是一个对历史数据有效的函数。我写了英国夏令时 - 不幸的是发生在三月和十月的最后一个星期天,使得逻辑有点复杂。
基本上硬编码的日期部分01/03正在寻找3月份的最后一个星期日,而01/10正在寻找10月份的最后一个星期日(这是时钟前进和返回的时间)。注意:如果您的服务器正在使用美国的日期,请将这两个日期部分反转到03/01和10/01 !!!!
所以你给它一个UTC日期,它会自动判断一个历史日期是BST还是GMT。在大数据集上使用并不是最好的选择,但它是一个解决方案。
运行此脚本以创建该函数并在您的选择中调用它内联。SQL 2008对用户定义的函数有一个问题,看起来,它在代码下放置了一条红线,但只要您使用dbo前缀(SELECT dbo.UTCConvert(yourdate)来运行它),它仍然运行它。
CREATE FUNCTION [dbo].[UTCConvert]
(
@p1 datetime
)
RETURNS datetime
AS
BEGIN
DECLARE @Result datetime
RETURN CASE
WHEN
@p1 >
(DATEADD(day,DATEDIFF(day,'19000107',DATEADD(month,DATEDIFF(MONTH,0,'01/03/' + CAST(DATEPART(year,@p1) as CHAR)),30))/7*7,'19000107'))
AND
@p1<
(DATEADD(day,DATEDIFF(day,'19000107',DATEADD(month,DATEDIFF(MONTH,0,'01/10/' + CAST(DATEPART(year,@p1) as CHAR)),30))/7*7,'19000107'))
THEN (DATEADD(HH, 1, @p1))
ELSE @p1
END
END
如果您的服务器使用原生美国日期,因为它位于美国,那么您很可能会遇到更严重的问题。如果你正在看这个问题,可能性很大,你至少要在夏令时适用的一个地方存储日期。这意味着至少你必须担心在换班日期2007年的变化。您可能不得不担心多个时区,可能是亚利桑那州,甚至可能是纳瓦霍族。您真的想要在SQL Server中存储UTC或datetimeoffset,并在业务层中进行日期数学计算。 – MattW 2015-10-13 20:44:36
除了夏令问题,为什么不简化与:
yourDateTime - getutcdate() + getdate()
做了服务器时间的变化?你可以检查一下吗? – 2011-05-19 20:46:14
嗯,它在SQL Azure上运行。我将如何检查? – slandau 2011-05-19 20:46:41
你不能简单地做一个“SELECT GETDATE()GO”,看看它是否符合你的期望? – Mat 2011-05-19 20:48:32