2009-06-26 57 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