2009-06-26 19 views
0

SQLが解析して別のオフセット(たとえばEST-> UTC)に変換できる日時を表す文字列形式はありますか?私は、日時フィールドでその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" 

は、私は、ユーザーからのような文字列を持っています。このようなこと:

select @ utcDateTime 

この得なければならない。言い換えれば

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

を、私が最初に与えられた「2009年6月26日午後6時30分」の値を持つ日時を保存したいです文字列。

また、我々は、サーバーが(ので、我々はちょうどオフセットDateDiff関数(gettime()、getutctime())を検出することができないユーザーと同じタイムゾーンではないと仮定しなければなりません。

私は変換を使用して試してみました(...)と(日時など...)のキャストが、運と。

あなたは日付時刻 実行にこの中を使用している場合は、SQL Server 2005の?

+3

日時などのデータを格納して何が悪いのでしょうか? –

+0

指定された文字列は変換できません。 SQL Serverにこのエラーが表示されます。「datetimeを文字列から変換するときに変換に失敗しました。 –

+0

「ISOかどうか」、または_is_ISO? 1つの形式を選択する方が良いでしょう。 –

答えて

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 
+0

+1それはクリーナーなので – SQLMenace

+0

甘い!これは動作します!私はそれがとても醜く見えないと思っていたが、何でも。これはまた、文字列が特定の長さであることを必要とします - しかし、私はとにかく途中で文字列パターンを検証しています。 –

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 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 
+0

しかし、ユーザーから渡された文字列とユーザーのタイムゾーンオフセットサーバーとは異なります。 (サーバーはGMT-4:00、ユーザーはGMT + 8:00の文字列を渡すことができます) –

+0

追加コード – SQLMenace

+0

30分のタイムゾーンはどうなりますか? GMT-2のように:30 –

関連する問題