我想将getdate()
SQL Server 转换为 EST 时间。
11 回答
更新答案 (05-29-2020)
Azure SQL 团队发布了一项新功能,使这变得更加容易。 SELECT CURRENT_TIMEZONE_ID()
将返回您服务器的时区。将此函数添加到下面的 ORIGINAL ANSWER 中会产生一个查询,该查询将在所有 Azure SQL Server 上全局运行。
SELECT CONVERT(DATETIME,GETDATE() AT TIME ZONE (SELECT CURRENT_TIMEZONE_ID()) AT TIME ZONE 'Eastern Standard Time')
此查询适用于任何 Azure SQL Server。
原始答案:
这里有很多不必要的复杂答案,或者没有考虑夏令时。不需要大量的CASE
声明。不需要新的存储过程或标量/用户定义的函数。从 SQL Server 2016 开始,可以使用一行本机 sql 来完成时区之间的转换。这有优势。例如,它可以从报告中调用或用于只读数据库。
SELECT CONVERT(DATETIME,GETDATE() AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time')
而已。上面,我们正在使用这些功能,这里AT TIME ZONE
有更详细的描述。这里可能有一些新的功能和特性,因此有必要进行解释。上面的查询调用并将其时区设置为 UTC,使用. 隐含地,这也将其数据类型从 a 更改为。接下来,我们将再次调用以将其切换到 EST。最后,我们将把整个东西包装起来,让它回到 a ,在这个过程中去掉不需要的 +/- 小时部分。GETDATE()
AT TIMEZONE
datetime
datetimeoffset
AT TIMEZONE
CONVERT()
datetime
逐步查询...
SELECT [GetDate] = GETDATE()
SELECT [GetDateAtUtc] = GETDATE() AT TIME ZONE 'UTC'
SELECT [GetDateAtUtcAtEst] = GETDATE() AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time'
SELECT [GetDateEst] = CONVERT(DATETIME,GETDATE() AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time')
您是否考虑过 GETUTCDATE() 并从那里执行偏移?如果您的意思是标准时间的 EST,那么就是 UTC-5,所以
select dateadd(hour,-5,GETUTCDATE())
EST 是 GMT-5 小时,而 EDT 是 GMT-4 小时。
获取 EST:
select dateadd(hour,-5,GETUTCDATE())
要获得 EDT:
select dateadd(hour,-4,GETUTCDATE())
SQL 服务器本身具有current_utc_offset
夏季和冬季时间偏移正确的表。请尝试查询select * from current_utc_offset
,在您的服务器上将日期更改为不同的季节,然后再次查看表格。所以获取 EST 的正确函数是:
CREATE FUNCTION [dbo].[Getestlocaldatetime] ()
returns DATETIME
AS
BEGIN
DECLARE @zz NVARCHAR(12);
DECLARE @hh NVARCHAR(3);
DECLARE @dd DATETIME;
SET @zz = (SELECT current_utc_offset
FROM sys.time_zone_info
WHERE NAME = N'US Eastern Standard Time')
SET @hh = Substring(@zz, 1, 3);
SET @dd = Dateadd(hh, CONVERT(INT, @hh), Getutcdate())
RETURN @dd
END
SELECT CONVERT(VARCHAR, CONVERT(DATETIME, GETDATE() AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time'), 100) AS [Date_Result]
GetDate()
是来自服务器本身的系统时间。
以现在的小时差GetDate()
和现在在 EST 中的时间使用此代码,其中 1 是所说的差(在这种情况下,服务器位于中央时区)(这也假设您的服务器正在考虑 DST)
SELECT Dateadd(hour, 1, Getdate()) AS EST
如果您尝试使用夏令时输出本地时间(例如东部时间),则需要一个功能来检测夏令时的开始和结束,然后应用变量偏移量:我发现了这个:http:/ /joeyiodice.com/convert-sql-azure-getdate-utc-time-to-local-time/有用。
对于那些使用最新版本的 sql server 的人可以创建一个 .net 函数
标量值函数 (SVF) 返回单个值,例如字符串、整数或位值。您可以使用任何 .NET Framework 编程语言在托管代码中创建标量值用户定义函数。Transact-SQL 或其他托管代码可以访问这些函数。有关 CLR 集成的优势以及在托管代码和 Transact-SQL 之间进行选择的信息。
由于 .NET 可以访问操作系统中的所有时区,因此您不必计算夏令时 -4 或 -5 基础。
var timeUtc = DateTime.UtcNow;
TimeZoneInfo easternZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
DateTime easternTime = TimeZoneInfo.ConvertTimeFromUtc(timeUtc, easternZone);
选择 CONVERT(DATETIME,GETUTCDATE() AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time')
如果您想在不调用函数的情况下执行此操作,也可以使用 CASE 语句来执行此操作。下面的代码将 UTC 字段转换为山区时间,以考虑夏令时。对于 EST,您只需将所有 -6 更改为 -4 并将所有 -7 更改为 -5。
--Adjust a UTC value, in the example the UTC field is identified as UTC.Field, to account for daylight savings time when converting out of UTC to Mountain time.
CASE
--When it's between March and November, it is summer time which is -6 from UTC
WHEN MONTH ( UTC.Field ) > 3 AND MONTH ( UTC.Field ) < 11
THEN DATEADD ( HOUR , -6 , UTC.Field )
--When its March and the day is greater than the 14, you know it's summer (-6)
WHEN MONTH ( UTC.Field ) = 3
AND DATEPART ( DAY , UTC.Field ) >= 14
THEN
--However, if UTC is before 9am on that Sunday, then it's before 2am Mountain which means it's still Winter daylight time.
CASE
WHEN DATEPART ( WEEKDAY , UTC.Field ) = 1
AND UTC.Field < '9:00'
--Before 2am mountain time so it's winter, -7 hours for Winter daylight time
THEN DATEADD ( HOUR , -7 , UTC.Field )
--Otherwise -6 because it'll be after 2am making it Summer daylight time
ELSE DATEADD ( HOUR , -6 , UTC.Field )
END
WHEN MONTH ( UTC.Field ) = 3
AND ( DATEPART ( WEEKDAY , UTC.Field ) + 7 ) <= DATEPART ( day , UTC.Field )
THEN
--According to the date, it's moved onto Summer daylight, but we need to account for the hours leading up to 2am if it's Sunday
CASE
WHEN DATEPART ( WEEKDAY , UTC.Field ) = 1
AND UTC.Field < '9:00'
--Before 9am UTC is before 2am Mountain so it's winter Daylight, -7 hours
THEN DATEADD ( HOUR , -7 , UTC.Field )
--Otherwise, it's summer daylight, -6 hours
ELSE DATEADD ( HOUR , -6 , UTC.Field )
END
--When it's November and the weekday is greater than the calendar date, it's still Summer so -6 from the time
WHEN MONTH ( UTC.Field ) = 11
AND DATEPART ( WEEKDAY , UTC.Field ) > DATEPART ( DAY , UTC.Field )
THEN DATEADD ( HOUR , -6 , UTC.Field )
WHEN MONTH ( UTC.Field ) = 11
AND DATEPART ( WEEKDAY , UTC.Field ) <= DATEPART ( DAY , UTC.Field )
--If the weekday is less than or equal to the calendar day it's Winter daylight but we need to account for the hours leading up to 2am.
CASE
WHEN DATEPART ( WEEKDAY , UTC.Field ) = 1
AND UTC.Field < '8:00'
--If it's before 8am UTC and it's Sunday in the logic outlined, then it's still Summer daylight, -6 hours
THEN DATEADD ( HOUR , -6 , UTC.Field )
--Otherwise, adjust for Winter daylight at -7
ELSE DATEADD ( HOUR , -7 , UTC.Field )
END
--If the date doesn't fall into any of the above logic, it's Winter daylight, -7
ELSE
DATEADD ( HOUR , -7 , UTC.Field )
END