![](/img/trans.png)
[英]Parsing SimpleDateFormat a Date as “yyyy-MM-dd” is not working in a appropieted way
[英]Why SimpleDateFormat("MM/dd/yyyy") parses date to 10/20/20128?
我有這個代碼:
DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
dateFormat.setLenient(false);
Date date = dateFormat.parse("10/20/20128");
我希望 dateFormat.parse 調用拋出 ParseException,因為我提供的年份是 5 個字符,而不是我定義的格式中的 4 個字符。 但出於某種原因,即使將 lenient 設置為 false,此調用也會返回 10/20/20128 的 Date 對象。
這是為什么? 這對我來說沒有多大意義。 是否有其他設置使其更加嚴格?
20128是一個有效的年份,Java希望世界能夠存活這么長時間。
如果模式字母的數量大於2,則無論數字位數如何,都按字面解釋年份。
如果您想驗證日期是否有限,您可以定義一個並檢查 -
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date maxDate = sdf.parse("01/01/2099"); // This is the limit
if(someDate.after(maxDate)){
System.out.println("Invalid date");
}
請參閱javadoc
年份:如果格式化程序的日歷是公歷,則應用以下規則。
- 對於格式化,如果模式字母的數量為2,則年份被截斷為2位數; 否則它被解釋為一個數字。
- 對於解析,如果模式字母的數量大於2, 則無論數字位數如何,都按字面解釋年份 。 所以使用“MM / dd / yyyy”模式,“01/11/12”解析到公元12年1月11日
- 對於使用縮寫年份模式(“y”或“yy”)進行解析,SimpleDateFormat必須解釋相對於某個世紀的縮寫年份。 它通過將日期調整為創建SimpleDateFormat實例之前的80年和20年之后來實現此目的。 例如,使用“MM / dd / yy”模式和SimpleDateFormat
在1997年1月1日創建的實例,字符串“01/11/12”將是
解釋為2012年1月11日,而字符串“05/04/64”將是
解釋為1964年5月4日。在解析期間,只包含字符串
正好由Character.isDigit(char)定義的兩位數字將被解析為默認世紀。 任何其他數字字符串,例如a
一個數字字符串,三個或更多個數字字符串,或者不是所有數字的兩位數字符串(例如,“ - 1”)按字面解釋。
所以使用相同的模式解析“01/02/3”或“01/02/003”
1月2日,3日。 同樣,“01/02 / -3”被解析為公元前1月2日。- 否則,將應用日歷系統特定表單。 對於格式化和解析,如果模式字母的數量是4或
更多,使用日歷特定的長形式。 否則,一個日歷
使用特定的簡短或縮寫形式。
因此,它將讀取最后一個/
作為年份之后的所有字符。
請參閱java.text.SimpleDateFormat
API,模式字母y
:對於解析,如果模式字母的數量大於2,則無論數字位數如何,都將按字面解釋年份。
在java中使用SimpleDateFormat,您可以實現許多人類可讀的格式。 請考慮以下代碼段:
Date curDate = new Date();
SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
String DateToStr = format.format(curDate);
System.out.println(DateToStr);
format = new SimpleDateFormat("dd-M-yyyy hh:mm:ss");
DateToStr = format.format(curDate);
System.out.println(DateToStr);
format = new SimpleDateFormat("dd MMMM yyyy zzzz", Locale.ENGLISH);
DateToStr = format.format(curDate);
System.out.println(DateToStr);
format = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z");
DateToStr = format.format(curDate);
System.out.println(DateToStr);
查看各種格式生成的各種輸出:
2014年5月11日
11-5-2014 11:11:51
2014年5月11日東歐夏令時
太陽,2014年5月11日23:11:51 EEST
隨意修改格式字符串,您可能會得到所需的結果。
我始終建議您使用 java.time,現代 Java 日期和時間 API,進行日期工作。 此外,碰巧 java.time 會給你你要求的異常。
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("MM/dd/uuuu")
.withResolverStyle(ResolverStyle.LENIENT);
LocalDate date = LocalDate.parse("10/20/20128", dateFormatter);
結果:
線程“main”中的異常 java.time.format.DateTimeParseException:無法在索引 6 處解析文本“10/20/20128”
提到的索引 6是字符串中 5 位數年份的位置。
也就是說,其他人建議的范圍檢查仍然是一個好主意。 使用 java.time 這很容易。 比如說我們不想接受任何未來的日期:
LocalDate date = LocalDate.parse("10/20/8012", dateFormatter);
if (date.isAfter(LocalDate.now(ZoneId.systemDefault()))) {
System.err.println("Date must not be in the future, was " + date);
}
日期不能在未來,是 8012-10-20
教程鏈接: Trail:Date Time(Java™ 教程)解釋了如何使用 java.time。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.