我有一个奇怪的问题。
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy", Locale.ENGLISH);
我称呼它为:
Date date = sdf.parse("06/05/2020");
它显示“日期”是星期四04 MDT 2020 18:00:00,也就是少一天。
SimpleDateFormat在哪里出错?
我正在使用Android Studio 3.5.1和Androidx。
谢谢。肖恩
这是TimeZone
的常见问题,您需要为sdf
设置正确的时区,例如:
sdf.setTimeZone(TimeZone.getTimeZone("GMT"))
如果您设置了正确的时区,则会看到正确的日期:)
希望有帮助
防弹方式是切换到现代Java日期和时间API java.time。
DateTimeFormatter dateFormatter
= DateTimeFormatter.ofPattern("MM/dd/yyyy", Locale.ENGLISH);
LocalDate date = LocalDate.parse("06/05/2020", dateFormatter);
System.out.println(date);
输出为:
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()
抓住JVM的(已更改)时区并将其用于呈现字符串。因此,我们得到的是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(JSR-310的ThreeTen)。