从nvarchar到datetime的转换失败

时间:2017-07-19 18:20:21

标签: sql sql-server datetime type-conversion sql-convert

我正在尝试将nvarchar日期转换为日期时间,但是会发生此错误:我尝试了多种方式,包括CAST和Convert(如下面的代码),但没有用。有什么建议 ?

日期格式:星期三,2017年7月19日16:23:38 +0000

代码:

INSERT INTO feed.article(title,link,sourceID,[date])
    SELECT title,link,s.sourceID,
    CONVERT(DATETIME,[date],121)
    FROM feed.tempXML t
    JOIN feed.[source] s ON s.sourceName = t.[source]

给出错误:

  

从字符串转换日期和/或时间时转换失败。

4 个答案:

答案 0 :(得分:2)

如果您拥有MS SQL Server 2012或更高版本,则可以使用TRY_PARSE。

SELECT CAST(TRY_PARSE ('Wed, 19 Jul 2017 16:23:38 +0000' AS datetimeoffset) AS datetime)

答案 1 :(得分:1)

我会分两部分来做,一部分是日期,另一部分是时间:

SELECT title,link,s.sourceID,
       (CONVERT(DATETIME, SUBSTRING([date], 5, 10), 106) +
        CONVERT(DATETIME, SUBSTRING([date], 18, 8))
       )
FROM feed.tempXML t JOIN
     feed.[source] s
     ON s.sourceName = t.[source];

这可以最大限度地减少字符串操作,因此它看起来像一个非常简单的方法。

答案 2 :(得分:0)

编辑:OlegGordon查看解决方案。我实际上更喜欢他们(因为它非常复杂)。

您需要从中获取日期格式......

'Wed, 19 Jul 2017 16:23:38 +0000'

......对此...

'19 Jul 2017 16:23:38'

您可以使用LEFTRIGHT从开头和结尾删除字符。从末尾删除最后6个将如下所示:

LEFT([date], LEN[date] - 6)

我们可以使用RIGHT()的相同语法删除前5个,但[date]现在必须替换为上面的整个字符串:

-- RIGHT([date], LEN([date]) - 5) becomes...
RIGHT(LEFT(@d, LEN(@d) - 6), LEN(LEFT(@d, LEN(@d) - 6)) - 5)

总而言之,这很丑陋,但有效:

INSERT INTO feed.article(title,link,sourceID,[date])
SELECT title,link,s.sourceID,
CONVERT(DATETIME,RIGHT(LEFT([date], LEN([date]) - 6), LEN(LEFT([date], LEN([date]) - 6)) - 5),121)
FROM feed.tempXML t
JOIN feed.[source] s ON s.sourceName = t.[source]

重要提示:这是假设您的日期格式在开头总是有5个不必要的字符,并且您的时区偏移(最后的+0000)永远是0(所以我们可以忽略它)。

如果您有使用时区偏移量的值,则需要考虑到这一点。

答案 3 :(得分:0)

    Based on the format, we should be able make a few "safe assumptions"...
    1) The weekday will always be expressed as a 3 char abbreviation.
    2) The 3 char abbreviation will be followed by a comma and a space.
    3) The portion of code we're interested in will be either 19 or 20 characters. 
        (10 for single digit dates and 20 for double digit dates)
    4) There will be a space following the date.

    Based on these assumptions, you should be safe to use the following...

        CREATE TABLE #TestData (
            StringDate NVARCHAR(40) NOT NULL 
            );
        INSERT #TestData (StringDate) VALUES
            (N'Wed, 19 Jul 2017 16:23:38 +0000'),
            (N'Wed, 9 Jul 2017 16:23:38 +0000');

        SELECT 
            DateTimeDate = CAST(SUBSTRING(td.StringDate, 6, 20) AS DATETIME)
        FROM 
            #TestData td;