0

我正在尝试将 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

4 回答 4

2

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

SELECT CAST(TRY_PARSE ('Wed, 19 Jul 2017 16:23:38 +0000' AS datetimeoffset) AS datetime)
于 2017-07-19T18:37:17.497 回答
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];

这最大限度地减少了字符串操作,因此它似乎是一种非常简单的方法。

于 2017-07-19T18:40:20.697 回答
0

编辑:查看OlegGordon的解决方案。我实际上更喜欢它们而不是我自己的(因为它很复杂)。


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

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

……到这……

'19 Jul 2017 16:23:38'

LEFT您可以使用and删除开头和结尾的字符RIGHT。从末尾删除最后 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(所以我们可以简单地忽略它)。

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

于 2017-07-19T18:28:59.053 回答
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;
于 2017-07-19T18:45:04.587 回答