将历史日期从 UTC 转换为本地时间
Posted
技术标签:
【中文标题】将历史日期从 UTC 转换为本地时间【英文标题】:Convert historic dates from utc to local time 【发布时间】:2011-02-21 19:13:47 【问题描述】:我有一个包含如下数据的 sql 表:
| theDate (datetime) | theValue (int) |
----------------------------------------
| 2010-05-17 02:21:10 | 5 |
| 2009-03-12 04:11:35 | 23 |
| 2010-02-19 18:16:53 | 52 |
| 2008-07-07 22:54:11 | 30 |
日期以 UTC 格式存储在 datetime 列中,如何将它们转换为本地时间(挪威)?请记住,由于冬季/夏季时间,UTC 偏移量在一年中并不相同。
更新:我使用的是 Microsoft SQL Server 2005,我需要从 SQL 中执行此操作,因为稍后会在报告中显示数据。
【问题讨论】:
【参考方案1】:此语句将针对您列出的表起作用。使用该逻辑,您可以将其应用于任何日期字段。
SELECT CASE
WHEN [theDate] BETWEEN
Convert(DATETIME, Convert(VARCHAR(4), Year([theDate])) + '-03-' + Convert(VARCHAR(2), (31 - (5 * Year([theDate])/4 + 4) % 7)) + ' 02:00:00', 20)
AND
Convert(DATETIME, Convert(VARCHAR(4), Year([theDate])) + '-10-' + Convert(VARCHAR(2), (31 - (5 * Year([theDate])/4 + 1) % 7)) + ' 03:00:00', 20)
THEN Dateadd(hh, 2, [theDate])
ELSE Dateadd(hh, 1, [theDate])
END AS [theDate],
[theValue]
FROM [YOURTABLE]
【讨论】:
如何考虑到 UTC-offset 全年不一样? 太棒了!但是你能描述一下这个逻辑吗,真的不明白这是怎么回事..(巫术!)【参考方案2】:编写 CLR 函数,将 SqlDateTime 从 UTC 转换为本地 CLR,如下所示:
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlDateTime ToLocalTime(SqlDateTime dt)
try
return TimeZone.CurrentTimeZone.ToLocalTime(dt.Value);
catch
return SqlDateTime.Null;
【讨论】:
【参考方案3】:如果可以的话,使用 php...
$dateFormat = 'r';
$tz = 'Australia/Perth';
function convertDate($epochDate)
global $dateFormat, $tz;
$tzOld = getenv("TZ");
putenv("TZ=$tz");
$ret = date($dateFormat, ($epochDate*1));
putenv("TZ" . ($tzOld ? "=$tzOld" : ""));
return $ret;
【讨论】:
【参考方案4】:这是我从当地时间返回当地冬季时间的函数
基于 3 月最后一个星期日 2:00 和 10 月最后一个星期日 3:00 的时间变化
use your_DB
go
CREATE function [dbo].[ConvertToLocalWinterTime](@instime datetime)
returns datetime
as
begin
declare @localtm datetime = @instime
declare @localwintertm datetime
declare @lastmarchsunday datetime
declare @lastoctobersunday datetime
declare @tmpmd datetime = '03.31.' + convert(char(4),year(@localtm))
declare @tmpod datetime = '10.31.' + convert(char(4),year(@localtm))
--- last sunday in march
declare @DOFWEEKM int = datepart (weekday,@tmpmd-1)
if @DOFWEEKM <7
begin
set @lastmarchsunday = @tmpmd - @DOFWEEKM
end
else
begin
set @lastmarchsunday = @tmpmd
end
----last sunday in October
declare @DOFWEEKO int = datepart (weekday,@tmpod-1)
if @DOFWEEKO <7
begin
set @lastoctobersunday = @tmpod - @DOFWEEKO
end
else
begin
set @lastoctobersunday = @tmpod
end
-------------------------------
if (@localtm > dateadd(hh,2,@lastmarchsunday)) and (@localtm < dateadd(hh,3,@lastoctobersunday))
begin
set @localwintertm = dateadd(hh,-1, @localtm)
end
else
begin
set @localwintertm = @localtm
end
return @localwintertm
end
【讨论】:
以上是关于将历史日期从 UTC 转换为本地时间的主要内容,如果未能解决你的问题,请参考以下文章
如何将 UTC 日期字符串转换为本地时间 (systemTimeZone)