2014-01-23 104 views
1

下面的代码正在执行没有任何问题。但从逻辑上来说,这似乎是不正确的。为什么这样?在SimpleDateFormat中使用〜#解析()

import java.sql.Date; 
import java.text.DateFormat; 
import java.text.SimpleDateFormat; 

DateFormat df =new SimpleDateFormat("MM/dd/yyyy"); 

new Date(df.parse("09/01/3~34").getTime()); // Produces '09/01/3' 
new Date(df.parse("09/01/100000").getTime()); // Produces ' 000-09-01' 
+2

1.解析器在阅读可解释的内容后停止。 2.解析器可以是* lenient *。 –

+0

'parsedDate'的价值是什么?我猜'3-01-09'。 – 2014-01-23 14:04:10

+0

是的,我得到了'0003-09-01'。这是我得到'df.parse(“09/01/3〜qwwww”)' – gowthamvelusamy

回答

0

第一个问题:

new Date(df.parse("09/01/3~34").getTime()); // Produces '09/01/3' 

根据DateFormat#parse() JavaDoc

从给定字符串产生日期的开始解析文本。 该方法可能不会使用给定字符串的整个文本。

因此,在它解析来自String的值之后,它停止在其上搜索。当它找到~符号时,它将3值解析为年,并停止查看字符串。

第二个问题:

new Date(df.parse("09/01/100000").getTime()); // Produces ' 000-09-01' 

它不生产 '000-09-01'。以下代码:

DateFormat df = new SimpleDateFormat("MM/dd/yyyy"); 
java.util.Date parsedDate = df.parse("09/01/100000"); 

System.out.println(parsedDate); 
System.out.println(df.format(parsedDate)); 

输出:

Fri Sep 01 00:00:00 BRT 100000 
09/01/100000 

然而,这似乎是与JDK的java.sql.Date#toString方法中的错误。要正确显示此java.sql.Date,试图将它传递给你的DateFormat#format方法:

java.sql.Date sqlDt = new java.sql.Date(df.parse("09/01/10000").getTime()); 
System.out.println(df.format(sqlDt)); 

输出:09/01/100000

+0

为什么'Date parsedDate = new Date(df.parse(“09/01/100000”)。getTime());'正在返回'000-09-01' – gowthamvelusamy

+0

我没有使用java.util.date。 。我正在使用java.sql.date。你能检查一下sql.date如何处理'09/01/100000' – gowthamvelusamy

+0

这似乎是'java.sql.Date#toString'方法的一个错误。显然,它不能正确理解年代超过9999年。要正确显示此日期,请尝试使用相同的DateFormat:'df.format(parsedDt)'。 – everton

0

关于第一个问题:

SimpleDateFormat是非常宽松的,只是停止时一些无效的字符被击中。即使您明确指示它通过df.setLenient(false);解析严格,您在这里也会注意到相同的输出并且没有例外。 JodaTime,JSR-310或我的时间库会在严格模式下正确拒绝包含无效字符的输入。所以这里我们在JDK中有一个明确的错误。

关于第二个问题:

嘛,你使用java.sql.Date而不是java.util.Date。 SQL版本的设计年限不超过9999年。甚至可以在javadoc中指定它:

“1970年1月1日以后的日期毫秒,00:00:00 GMT不超过年份8099的毫秒表示”

javadoc中不太清楚,但甲骨文说1900年的年份抵消,所以最后java.sql.Date只支持年的范围高达9999。这符合ANSI-SQL,所以没有年限制本身不是一个错误,但必要与SQL进行互操作。相反,另一个方面是不好的,在我看来是一个错误,即:如果你给构造函数提供了一个无效的年份,那么你不会得到任何异常,但是内部状态将被默默地设置为愚蠢和不可预测的东西。

结论:

避免使用java.sql.Date为别的比在JDBC层。它不适用于应用程序层。此外,java.util.DateSimpleDateFormat(它们是Java-pre8中的“标准”)或多或少被破坏。好的选择是JodaTime,在Java 8中,新的JSR-310-API或我的库(如果它有一天达到非alpha状态)。