[英]Why does SimpleDateFormat.parse accept an invalid date string?
[英]SimpleDateFormat.parse(date_string) generate a previous date
我有一個奇怪的問題。
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy", Locale.ENGLISH);
我稱之為:
Date date = sdf.parse("06/05/2020");
它顯示“日期”是 Thu Jun 04 18:00:00 MDT 2020,即少了一天。
SimpleDateFormat 哪里錯了?
我正在使用 Android Studio 3.5.1 和 Androidx。
提前致謝。 肖恩
防彈的方法是切換到java.time,現代的Java日期和時間API。
DateTimeFormatter dateFormatter
= DateTimeFormatter.ofPattern("MM/dd/yyyy", Locale.ENGLISH);
LocalDate date = LocalDate.parse("06/05/2020", dateFormatter);
System.out.println(date);
Output 是:
2020-06-05
這當然是時區問題。 但是,它不會通過天真地運行您的代碼來復制。 還有更多的事情發生,我們只能猜測到底是什么。 我將介紹幾種可能發生這種情況的方法。
第一種可能性,JVM 的默認時區可能正在更改。 展示:
TimeZone.setDefault(TimeZone.getTimeZone("Etc/UTC"));
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy", Locale.ENGLISH);
Date date = sdf.parse("06/05/2020");
TimeZone.setDefault(TimeZone.getTimeZone("America/Edmonton"));
System.out.println(date);
2020 年 6 月 4 日星期四 18:00:00 MDT
平心而論,這不是一整天的錯誤,而是 6 個小時。 這已經夠糟糕的了,當然星期幾和月份的日期是錯誤的。 請注意,JVM 的時區設置可能已從您程序的完全不同部分或在同一 JVM 中運行的不同程序更改。 發生的事情是: SimpleDateFormat
獲得了 JVM 的默認時區,即 UTC。 因此,將日期解析為 UTC 時間 6 月 5 日的第一刻。 此時,北美仍是 6 月 4 日。 接下來,當我們打印Date
時, Date.toString()
的(更改的)時區並將其用於呈現字符串。 因此我們得到了 MDT 時間(北美山區夏令時),而不是用於解析的 UTC 時間。
不過,我們不需要像為整個 JVM 設置時區那樣激烈的東西來演示。 設置格式化程序的時區就足夠了。
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy", Locale.ENGLISH);
sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
Date date = sdf.parse("06/05/2020");
System.out.println(date);
在美國/埃德蒙頓時區運行時:
2020 年 6 月 4 日星期四 18:00:00 MDT
發生的事情與上面基本相同。
java.time 適用於較舊和較新的 Android 設備。 它只需要至少Java 6 。
org.threeten.bp
導入日期和時間類。java.time
。java.time
到 Java 6 和 7 的 backport(ThreeTen for JSR-310)。這是TimeZone
的常見問題,您需要為sdf
設置正確的時區,例如:
sdf.setTimeZone(TimeZone.getTimeZone("GMT"))
如果您設置了正確的時區,您將看到正確的日期:)
希望能幫助到你
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.