SQL Server 2012 ISDATE()

12

微软文档说明ISDATE()

如果表达式是有效的日期、时间或日期时间值,则返回1;否则,返回0。

那么为什么下面的例子返回0

DECLARE @DT VARCHAR(30) = '1/4/1752'

SELECT 
    ISDATE(@DT),
    TRY_CONVERT(DATE, @DT, 101),
    TRY_CONVERT(DATETIME, @DT),
    TRY_CAST(@DT as DATE),  
    TRY_CAST(@DT AS DATETIME)

返回值

0   1752-01-04  NULL    1752-01-04  NULL

将日期更改为1753年,然后保存更改。

1   1753-01-04  1753-01-04 00:00:00.000 1753-01-04  1753-01-04 00:00:00.000

select ISDATE('17521231'), ISDATE('17530101') gives

0   1

1
请注意,17520401是有效的DATETIME2值,但不是有效的DATETIME值,因此ISDATE仍然返回0。Gordon建议的TRY_CONVERT方法也可以正确处理这种情况。(文档可能需要进行微调—— 17520401是有效的DATE,但显然不是“有效的日期值”,这是错误的。)由于向后兼容性的问题,ISDATE本身的行为可能不会更改。 - Jeroen Mostert
https://dev59.com/bXA75IYBdhLWcg3waIQJ#3310588 - TheGameiswar
2
我认为这不是重复的,文档说明“datetime数据的范围是1753-01-01到9999-12-31,而日期数据的范围是0001-01-01到9999-12-31。”并且它返回“如果表达式是有效的日期、时间或日期时间值,则返回1;否则返回0。” - TheGameiswar
4
建议在Microsoft Connect上提出问题,要求他们更改ISDATE函数的行为或修改文档,以明确ISDATE不覆盖DATE的扩展范围。请注意,翻译后的内容与原文意思相同,但更易于理解。 - Jeroen Mostert
@Jeroen,感谢您阅读这个问题。它只会保持为那些异常情况之一! - Maurice1408
1个回答

13

正如文档所解释的,最早的datetime值是 '1753-01-01'。

我建议你使用try_convert(),这可以为你提供更多的灵活性:

 try_convert(date, '17521231') is not null

date数据类型可以追溯到公元1年。


3
文档还解释说,最早的日期为“虽然日期数据的范围是0001-01-01到9999-12-31”,而ISDATE()文档表示“如果表达式是有效的日期、时间或日期时间值,则返回1;否则返回0”。所以,ISATE('17520101')肯定是一个有效的日期? 根据文档,日期数据的范围是从公元1年1月1日到公元9999年12月31日。ISDATE()函数可以用于检查日期、时间或日期时间值是否有效,并返回1或0。因此,'17520101'是一个有效的日期。 - Maurice1408
没有公元零年! - Cato

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接