2017-07-19 187 views
0

我想一个nvarchar日期转换为日期时间,但出现此错误:我已经尝试了多种方式,包括CAST和转换(如下面的代码)与无济于事。有什么建议么 ?无法转换为nvarchar从为datetime

日期格式:星期三,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] 

错误给出:

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

+0

你什么错误? –

+3

使用'LEFT'和'RIGHT'的组合去除'周三,'和'+ 0000'。 2017年7月19日16:23:38''的值将成功转换。 – Santi

+0

使用此来帮助您解决问题https://docs.microsoft.com/en-us/sql/t-sql/functions/isdate-transact-sql –

回答

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]; 

这最大限度地减少字符串操作,所以它似乎是一个非常简单的方法。

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(所以我们可以简单地忽略它)。

如果你有价值观,使利用区偏移的,你需要考虑到这一点。

2

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

SELECT CAST(TRY_PARSE ('Wed, 19 Jul 2017 16:23:38 +0000' AS datetimeoffset) AS datetime) 
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;