2009-06-26 58 views
0

是否有字符串格式来表示SQL将能够解析并转换为另一个偏移量(例如,EST - > UTC)的日期时间。从全球化的日期/时间格式(也许ISO8601)转换为SQL Server日期时间类型

我有一个字符串从用户,例如:

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())。

我一直在使用转换尝试(......)和CAST(...的日期时间),但没有运气。

有没有办法在SQL Server做这个2005?

+3

有什么不对存储的数据为日期? – 2009-06-26 17:26:10

+0

给定的字符串不能被转换; SQL Server出现此错误:“从字符串转换日期时间时转换失败。” – 2009-06-26 18:22:28

+0

“可能是ISO”或_is_ ISO?选择一种格式会更好。 – 2009-06-26 18:27:02

回答

3

OK是我在它的尝试 - 这很有趣:-)

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 
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数据类型使这很容易

现在这里是一个答案,将与你(我加了半小时代码也)

代码是如何工作的,这里解释了处理数据:Adding time offsets passed 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