繁体   English   中英

SimpleDateFormat.parse(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 和 ThreeTenABP

防弹的方法是切换到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 API 26级吗?

java.time 适用于较旧和较新的 Android 设备。 它只需要至少Java 6

  • 在 Java 8 及更高版本以及更新的 Android 设备(来自 API 级别 26)中,现代 ZDB9734A 内置23871083ACE16。
  • 在非 Android Java 6 和 7 中,获得 ThreeTen Backport,现代类的后向端口(JSR 310 的 ThreeTen;参见底部的链接)。
  • 在(旧版)Android 上,使用 ThreeTen Backport 的 Android 版本。 它被称为 ThreeTenABP。 并确保从带有子包的org.threeten.bp导入日期和时间类。

链接

这是TimeZone的常见问题,您需要为sdf设置正确的时区,例如:

sdf.setTimeZone(TimeZone.getTimeZone("GMT"))

如果您设置了正确的时区,您将看到正确的日期:)

希望能帮助到你

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM