2009-06-26 4 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" 

Другими словами, я хочу, чтобы хранить DateTime, который имеет значение «2009-06-26 18:30», учитывая первые строка.

Кроме того, мы должны считать, что сервер не находится в том же часовом поясе, что и пользователь (так что мы можем не только обнаружить DATEDIFF смещение (GetTime(), getutctime()).

Я попытался с помощью преобразования (...) и литые (... в качестве даты-времени), но не повезло.

есть ли способ сделать это в SQL Server 2005?

+3

Что случилось с хранением данных в виде даты-времени? –

+0

Данная строка не может быть преобразована; SQL Server дает эту ошибку: «Ошибка конверсии при преобразовании даты и времени из символьной строки». –

+0

«Может быть ISO» или _is_ ISO? Лучше выбрать один формат. –

ответ

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

Sweet! Это работает! Я надеялся, что это будет выглядеть не так уродливо, но что угодно. Это также требует, чтобы строка была определенной длиной, но я все равно проверяю строковый шаблон. –

1

один способ, если вы используете DateTimes запустите в a Окно

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

Как насчет часовых поясов в полчаса? как GMT-2: 30 –

Смежные вопросы