我试图将我们系统中输入的日期作为YYYYMMDD
格式的文本转换为日期。不幸的是,我们的系统允许使用任何月份的第31个月来表示它是一个重要的月份的最后一天,对于某些功能,如应计利息等。
我的日期显示为20160931
,显然无法通过
CONVERT(DATETIME, CONVERT(CHAR(8), [FIELD]))
并抛出超出范围的值错误。
我如何克服这个问题,以便将其转换为正确的值,在这种情况下30/09/2016
?
答案 0 :(得分:2)
改编@ Shnugo的技术,我觉得最好让SQL决定月底。因此:
SELECT eomonth(CAST(y+m+'01' AS DATE))
FROM (VALUES(LEFT(@YourDate,4)
,SUBSTRING(@YourDate,5,2)
,SUBSTRING(@YourDate,7,2))) AS Parts(y,m,d)
将给予'2016-02-29'代替'2016-02-28',并为2月提供恒定的'28'。
答案 1 :(得分:1)
您可以尝试这样的事情:
DECLARE @YourDate VARCHAR(100)='20160231';
SELECT CAST(y+m+dNew AS DATE)
FROM (VALUES(LEFT(@YourDate,4)
,SUBSTRING(@YourDate,5,2)
,SUBSTRING(@YourDate,7,2))) AS Parts(y,m,d)
CROSS APPLY
(
SELECT CASE WHEN CAST(m AS INT) IN(4,6,9,11) AND CAST(d AS INT)>30 THEN '30'
ELSE CASE WHEN CAST(m AS INT)=2 AND CAST(d AS INT)>28 THEN '28' ELSE d END
END AS dNew
) AS NewDay
2月29日你还有 - 另外 - 要检查年份是否除以4: - )
现在我要发展@ Irawan的技术: - )
由于SQL Server 2005没有EOMONTH
函数,但让SQL Server进行计算肯定会更好(2月29日隐式解决了!),我建议这样做:
DECLARE @YourDate VARCHAR(100)='20160231';
SELECT DATEADD(SECOND,-1,DATEADD(MONTH,1,CAST(y+m+'01' AS DATETIME)))
FROM (VALUES(LEFT(@YourDate,4)
,SUBSTRING(@YourDate,5,2)
,SUBSTRING(@YourDate,7,2))) AS Parts(y,m,d)
这将 - 无论如何 - 交付当月的最后一秒......
如果你想要一个普通的DATE
(没有时间),你可以将SECOND
更改为DAY
,这将首先跳到第一天的午夜下一个月,而不是一天回来......
简单的语法......
DECLARE @YourDate VARCHAR(100)='20160229';
SELECT CASE WHEN ISDATE(@YourDate)=1 THEN @YourDate
ELSE DATEADD(SECOND,-1,DATEADD(MONTH,1,CAST(LEFT(@YourDate,4) + SUBSTRING(@YourDate,5,2) +'01' AS DATETIME)))
END AS CorrectDate;