0

是否有字符串格式来表示 SQL 将能够解析并转换为另一个偏移量的日期时间(例如 EST -> UTC)。

我有一个来自用户的字符串,例如:

declare @p1 varchar(50);
declare @utcDateTime datetime;

set @p1 = "2009-06-26 14:30:00.000Z-4:00";   -- could be ISO8601

-- what do I do here to convert @p1?

set @utcDateTime = -- should be "2009-06-26 18:30:00.000"

我希望能够将字符串转换为等效的 UTC 并将其存储在日期时间字段中。这样:

select @ utcDateTime 

应该产生这个:

"2009-06-26 18:30:00.000"

换句话说,给定第一个字符串,我想存储一个值为“2009-06-26 18:30”的日期时间。

此外,我们必须假设服务器与用户不在同一个时区(因此我们不能只检测偏移量 datediff(gettime(), getutctime())。

我曾尝试使用 convert(...) 和 cast(... as datetime) 但没有运气。

在 SQL Server 2005 中有没有办法做到这一点?

4

2 回答 2

4

好的,这是我的尝试 - 这很有趣 :-)

 DECLARE  @datestr varchar(100)

SET @datestr = '2009-06-26 14:30:00.000Z+4:00'

SELECT @datestr, DATEADD(mi, -1 * CAST(SUBSTRING(@datestr,25,1)+'1' AS int) *  
    DATEDIFF(mi,'1900-01-01', CAST(SUBSTRING(@datestr,26,5) as datetime)),   
    CAST(LEFT(@datestr,23) as datetime) )

SET @datestr = '2009-06-26 14:30:00.000Z-4:00'

SELECT @datestr, DATEADD(mi, -1 * CAST(SUBSTRING(@datestr,25,1)+'1' AS int) *  
    DATEDIFF(mi,'1900-01-01', CAST(SUBSTRING(@datestr,26,5) as datetime)),   
    CAST(LEFT(@datestr,23) as datetime) )

SET @datestr = '2009-06-26 14:30:00.000Z+14:00'

SELECT @datestr, DATEADD(mi, -1 * CAST(SUBSTRING(@datestr,25,1)+'1' AS int) *  
    DATEDIFF(mi,'1900-01-01', CAST(SUBSTRING(@datestr,26,5) as datetime)),   
    CAST(LEFT(@datestr,23) as datetime) )

SET @datestr = '2009-06-26 14:30:00.000Z+4:30'

SELECT @datestr, DATEADD(mi, -1 * CAST(SUBSTRING(@datestr,25,1)+'1' AS int) *  
    DATEDIFF(mi,'1900-01-01', CAST(SUBSTRING(@datestr,26,5) as datetime)),   
    CAST(LEFT(@datestr,23) as datetime) )

SET @datestr = '2009-06-26 14:30:00.000Z-4:30'

SELECT @datestr, DATEADD(mi, -1 * CAST(SUBSTRING(@datestr,25,1)+'1' AS int) *  
    DATEDIFF(mi,'1900-01-01', CAST(SUBSTRING(@datestr,26,5) as datetime)),   
    CAST(LEFT(@datestr,23) as datetime) )

SET @datestr = '2009-06-26 14:30:00.000Z+14:30'

SELECT @datestr, DATEADD(mi, -1 * CAST(SUBSTRING(@datestr,25,1)+'1' AS int) *  
    DATEDIFF(mi,'1900-01-01', CAST(SUBSTRING(@datestr,26,5) as datetime)),   
    CAST(LEFT(@datestr,23) as datetime) )

回报:

2009-06-26 14:30:00.000Z+4:00  2009-06-26 10:30:00.000

2009-06-26 14:30:00.000Z-4:00  2009-06-26 18:30:00.000

2009-06-26 14:30:00.000Z+14:00 2009-06-26 00:30:00.000

2009-06-26 14:30:00.000Z+4:30  2009-06-26 10:00:00.000

2009-06-26 14:30:00.000Z-4:30  2009-06-26 19:00:00.000

2009-06-26 14:30:00.000Z+14:30 2009-06-26 00:00:00.000
于 2009-06-26T19:05:05.600 回答
1

如果您使用日期时间,一种方法是在窗口中运行它

declare @date varchar(100)
select @date = '2009-06-26 14:30:00.000'

select dateadd(hh,datediff(hh,getdate(),getutcdate()),@date)

输出 2009-06-26 18:30:00.000

最好始终使用 getutcdate() 并将用户偏移量存储在他的个人资料中

SQL Server 2008 有新的datetimeoffset数据类型,这使得这更容易

现在这是一个适用于您拥有的数据的答案(我还添加了 1/2 小时代码)

这里解释了代码的工作原理:Adding time offsetspassed in to a datetime to generate localized datetime

    declare @date varchar(100),@multiplier int

select @date = '2009-06-26 14:30:00.000Z+4:30'
select @multiplier = case when @date like '%+%' then -1 else 1 end


select dateadd(mi, @multiplier *convert(int,right(@date,2)),dateadd(hh
    ,-1 * convert(int,replace(substring(@date,patindex('%z%',@date)+ 1,3),':',''))
    ,left(@date,23)))
go


--2009-06-26 10:00:00.000

declare @date varchar(100),@multiplier int

select @date = '2009-06-26 14:30:00.000Z-4:30'
select @multiplier = case when @date like '%+%' then -1 else 1 end

select dateadd(mi, @multiplier *convert(int,right(@date,2)),dateadd(hh
    ,-1 * convert(int,replace(substring(@date,patindex('%z%',@date)+ 1,3),':',''))
    ,left(@date,23)))
go

--2009-06-26 19:00:00.000

declare @date varchar(100),@multiplier int

select @date = '2009-06-26 14:30:00.000Z+14:30'
select @multiplier = case when @date like '%+%' then -1 else 1 end

select dateadd(mi, @multiplier *convert(int,right(@date,2)),dateadd(hh
    ,-1 * convert(int,replace(substring(@date,patindex('%z%',@date)+ 1,3),':',''))
    ,left(@date,23)))
go

--2009-06-26 01:00:00.000


declare @date varchar(100),@multiplier int
select @date = '2009-06-26 14:30:00.000Z-14:30'
select @multiplier = case when @date like '%+%' then -1 else 1 end

select dateadd(mi, @multiplier *convert(int,right(@date,2)),dateadd(hh
    ,-1 * convert(int,replace(substring(@date,patindex('%z%',@date)+ 1,3),':',''))
    ,left(@date,23)))
go

--2009-06-27 05:00:00.000
于 2009-06-26T17:34:53.127 回答