Импортируйте или конвертируйте ISO 8601, расширенный данными о часовых поясах в TSQL - PullRequest
0 голосов
/ 28 сентября 2018

Требуется импортировать плоский файл в таблицу SQL Server, и в нем есть данные меток времени в следующем формате:

20171207T000131.000-0600  

Я импортировал как строку и попытался преобразовать, но мне не повезло.

Ответы [ 3 ]

0 голосов
/ 29 сентября 2018

Попробуйте это:

SELECT CONVERT(DATETIME,
  STUFF(STUFF(STUFF(STUFF(STUFF(STUFF('20171207T000131.000-0600',20,5,''),14,0,':'),12,0,':'),9,1,' '),7,0,'-'),5,0,'-'),120) 
0 голосов
/ 29 сентября 2018

Ну, как я уже писал в комментарии, SQL Server использует DateTimeOffset для хранения даты и времени с учетом часового пояса.
Проблема в том, что вам нужно перевести ISO без разделителей.Формат 8601, который вы используете сейчас, для удобочитаемой версии формата ISO 8601 - YYYY-MM-DDThh:mm:ss[.nnnnnnn][{+|-}hh:mm], чтобы преобразовать это значение в DateTimeOffset.
. Это делается путем добавления разделителей там, где они необходимы, с использованием STUFF:

Stuff вставляет новую строку в существующую строку, начиная с указанного индекса, вместо существующей подстроки указанной длины.Поскольку вы не хотите удалять любую существующую часть исходной строки, вы используете длину 0.

Я также добавил в свои демонстрационные предложения способы конвертации этих данных в date и * 1017.* (Не для DateTime, есть ошибка с этим типом данных !), Если вам не нужна точная информация (только часовой пояс может легко объяснить изменение даты):

DECLARE @DTOString varchar(100) = '20171207T000131.000-0600'

SELECT  CAST(LEFT(@DTOString, 8) As Date) As [Date],

    CAST(
        STUFF(
            STUFF(
                STUFF(
                    LEFT(@DTOString,19)
                , 14, 0, ':')
            , 12, 0, ':')
        ,9, 1, ' ') -- Replacing the T with a space
    As DateTime2) AS [DateTime2], -- NOT to DateTime! there's a bug!      

    CAST(
        STUFF(
            STUFF(
                STUFF(
                    STUFF(
                        STUFF(@DTOString, 23, 0, ':')
                    , 14, 0, ':')
                , 12, 0, ':')
            , 7, 0, '-')
        , 5, 0, '-') 
    As DateTimeOffset) As [DateTimeOffset]

Результат:

Date        DateTime2               DateTimeOffset
07.12.2017  07.12.2017 00:01:31     07.12.2017 00:01:31 -06:00
0 голосов
/ 29 сентября 2018

Если вам нужна только дата, импортируйте ее в виде строки и выполните следующий запрос

select cast(substring('20171207T000131.000-0600',1,8) as date)  

Я извлекаю '20171207' и преобразовываю ее в дату

...