![](/img/trans.png)
[英]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.