![](/img/trans.png)
[英]Why does SimpleDateFormat.parse().getTime() return an incorrect (negative) value?
[英]Why does SimpleDateFormat.parse not throw an exception here?
首先請注意我在這里遇到了java6。
我試圖從字符串中獲取可能有不同格式的日期。 出於某種原因,我沒有得到ParseException,我期待一個......
import java.text.SimpleDateFormat;
import java.util.Date;
public class test1{
public static void main(String argc[]){
System.out.println(parseAllDateFormats(argc[0]));
}
private static final String[] dateFormats = "yyyyMMdd,yyyy/MM/dd,yyyy-MM-dd,dd/MM/yyyy,dd-MM-yyyy,dd-MMM-yyyy,yyyy MM dd".split(",");
public static Date parseAllDateFormats(String date) {
if (date == null)
return null;
for (int f = 0; f < dateFormats.length; f++) {
String format = dateFormats[f];
try {
SimpleDateFormat dateFormat = new SimpleDateFormat(format);
System.out.println("trying " + format);
return dateFormat.parse(date);
}
catch (Exception e) {}
}
return null;
}
}
run:java test1 1980-04-25
我希望得到:
trying yyyyMMdd trying yyyy/MM/dd trying yyyy-MM-dd Fri Apr 25 00:00:00 EST 1980
但我只得到:
trying yyyyMMdd Tue Dec 04 00:00:00 EST 1979
知道什么是錯的嗎?
SimpleDateFormat默認是寬松的,即使給定日期的格式可能與其配置解析的格式不匹配,也不會拋出異常。 您可以將其設置為不那么寬松,如下所示:
SimpleDateFormat dateFormat = new SimpleDateFormat(format);
dateFormat.setLenient(false);
這樣它將檢查字符實際上是否對該日期有效。
知道什么是錯的嗎?
這是SimpleDateFormat
真正麻煩的地方之一。 當試圖使用模式yyyyMMdd
解析1980-04-25
,它按照預期解析1980
年,然后-0
作為月份,因為它應該是兩個字符,然后4
作為月份的日期,即使它應該是兩個字符太。 它忽略了-25
因為它已經完成了解析。
具有標准設置的SimpleDateFormat
也忽略了沒有月份-0
的事實。 它取為0,所以在1980年1月之前的那個月,這就是為什么你得到1979年12月。
SimpleDateFormat
非常麻煩,而且Date
的設計也很差。 兩者都很久了。 我建議你不要使用SimpleDateFormat
。 永遠。
private static final String[] dateFormats
= "yyyyMMdd,yyyy/MM/dd,yyyy-MM-dd,dd/MM/yyyy,dd-MM-yyyy,dd-MMM-yyyy,yyyy MM dd"
.split(",");
public static LocalDate parseAllDateFormats(String date) {
if (date == null) {
return null;
}
for (String format : dateFormats) {
try {
System.out.println("trying " + format);
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(format, Locale.ENGLISH);
return LocalDate.parse(date, dateFormatter);
}
catch (DateTimeParseException e) {
// Ignore, try next format
}
}
return null;
}
讓我們用你的示例字符串嘗試:
System.out.println(parseAllDateFormats("1980-04-25"));
輸出是預期的:
trying yyyyMMdd trying yyyy/MM/dd trying yyyy-MM-dd 1980-04-25
我正在使用java.time,現代Java日期和時間API。 與舊的日期時間類相比,使用起來更好。 現代DateTimeFormatter
可以將解析后的值解析為三種樣式的日期:strict,smart和lenient。 Smart是默認設置,它只接受1到12之間的月號。此外, LocalDate.parse
將堅持解析整個字符串,否則將引發異常。
與您的代碼相比,我也進行了一些小修改。 在大多數情況下,我會創建一個DateTimeFormatter
數組(不是String
),但它不允許我打印trying yyyyMMdd
,所以在這里我沒有。 我把花括號放在第一個if
語句中。 我在格式化程序上指定了語言環境,因為月份縮寫在語言之間有所不同,我想控制使用哪種語言。 我捕獲了特定的DateTimeParseException
並添加了注釋,為什么我忽略它,因為否則忽略異常是一件壞事,壞事。 在方法的底部,如果沒有格式工作而不是返回null
,您還應該考慮拋出異常。
請注意我在這里遇到了java6。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.