简单日期格式 24 小时

发布于 12-01 16:06 字数 630 浏览 0 评论 0原文

我有一个 SimpleDateFormat 来将 String 解析为 Date

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssZ");

当我解析这个时:

format.parse("2011-08-29T12:44:00+0200");

结果将是,当使用 <代码>Date.toLocaleString:

8月29日2011年00:44:00

这当然应该是:

8月29日2011年12:44:00

当我解析这个时:

format.parse("2011-08-29T13:44:00+0200");

那么结果正如预期的那样:

8月29日2011年13:44:00

我该如何解决这个问题?

I've got a SimpleDateFormat to parse a String into a Date:

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssZ");

When I'm parsing this:

format.parse("2011-08-29T12:44:00+0200");

The result will be, when using Date.toLocaleString:

29 aug. 2011 00:44:00

This should be ofcourse:

29 aug. 2011 12:44:00

And when I'm parsing this:

format.parse("2011-08-29T13:44:00+0200");

Then the result is as expected:

29 aug. 2011 13:44:00

How can I fix this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无法言说的痛2024-12-08 16:06:12

使用 HH 而不是 hh 表示小时模式

H   Hour in day (0-23)  Number  0
k   Hour in day (1-24)  Number  24
K   Hour in am/pm (0-11)    Number  0
h   Hour in am/pm (1-12)    Number  12

Use HH instead of hh for the hours pattern:

H   Hour in day (0-23)  Number  0
k   Hour in day (1-24)  Number  24
K   Hour in am/pm (0-11)    Number  0
h   Hour in am/pm (1-12)    Number  12
好听的两个字的网名2024-12-08 16:06:12

java.time 通过脱糖

我建议您使用 java.time(现代 Java 日期和时间 API)来进行日期和时间工作。

您的字符串采用 ISO 8601 格式。为其定义一个格式化程序:

private static final DateTimeFormatter ISO_FORMATTER
        = new DateTimeFormatterBuilder()
                .append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
                .appendOffset("+HHMM", "Z")
                .toFormatter(Locale.ROOT);

使用格式模式字符串可能会更短,但我更喜欢重用内置的 ISO_LOCAL_DATE_TIME ,它已经处理 ISO 8601。正如您的问题所证明的那样,编写格式模式字符串容易出错。我还指定根据 ISO 8601,距 UTC 的零偏移量应被接受为 Z(解析器也将接受 +0000)。

像这样解析:

    String isoString = "2011-08-29T12:44:00+0200";
    OffsetDateTime dateTime = OffsetDateTime.parse(isoString, ISO_FORMATTER);
    System.out.println(dateTime);

输出是:

2011-08-29T12:44+02:00

要获取针对用户区域设置格式化的字符串,请使用第二个格式化程序:

private static final DateTimeFormatter LOCALE_FORMATTER
        = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);

我们仍然不需要编写任何格式模式字符串。格式如下:

    String localeString = dateTime.format(LOCALE_FORMATTER);
    System.out.println(localeString);

输出正是它应该的样子。我在 nl_NL 语言环境中运行并得到:

8月29日2011年12:44:00

请跳过下一节。

如果我需要老式的 java.util.Date 怎么办?

没有人应该再使用 Date 类。仅当您必须为旧版 API 需要一个 Date 且您现在无法升级到 java.time 时,才需要转换:

    Date oldfashionedDate = Date.from(dateTime.toInstant());
    System.out.println(oldfashionedDate);

Funnyly 输出将取决于时区。在我的时区,我得到:

2011 年欧洲中部夏令时间 8 月 29 日星期一 12:44:00

问:java.time 不需要 Android API 级别 26 吗?

java.time 在旧版和新版 Android 设备上都能很好地工作。它只需要至少 Java 6

  • 在 Java 8 及更高版本以及较新的 Android 设备(从 API 级别 26 开始)中,现代 API 是内置的。
  • 在非 Android Java 6 和 7 中,获取 ThreeTen Backport,即现代类的向后移植(ThreeTen for JSR 310;请参阅底部的链接)。
  • 在较旧的 Android 上,可以使用脱糖或 Android 版本的 ThreeTen Backport。它被称为 ThreeTenABP。在后一种情况下,请确保使用子包从 org. Threeten.bp 导入日期和时间类。

链接

java.time through desugaring

I suggest that you use java.time, the modern Java date and time API, for your date and time work.

Your string is in ISO 8601 format. Define a formatter for it:

private static final DateTimeFormatter ISO_FORMATTER
        = new DateTimeFormatterBuilder()
                .append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
                .appendOffset("+HHMM", "Z")
                .toFormatter(Locale.ROOT);

It could have been shorter with a format pattern string, but I prefer to reuse the built-in ISO_LOCAL_DATE_TIME, which already handles ISO 8601. As your question testifies, writing a format pattern string is error-prone. I have also specified that an offset of zero from UTC should be accepted as Z in accordance with ISO 8601 (the parser will accept +0000 too).

Parse like this:

    String isoString = "2011-08-29T12:44:00+0200";
    OffsetDateTime dateTime = OffsetDateTime.parse(isoString, ISO_FORMATTER);
    System.out.println(dateTime);

Output is:

2011-08-29T12:44+02:00

To obtain a string formatted for the user’s locale use a second formatter:

private static final DateTimeFormatter LOCALE_FORMATTER
        = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);

We still need not write any format pattern string. Format like this:

    String localeString = dateTime.format(LOCALE_FORMATTER);
    System.out.println(localeString);

Output is exactly what it should be. I ran in nl_NL locale and got:

29 aug. 2011 12:44:00

Please skip the next section.

What if I need an old-fashioned java.util.Date?

No one should use the Date class anymore. Only if you indispensably need a Date for a legacy API that you cannot afford to upgrade to java.time right now, convert:

    Date oldfashionedDate = Date.from(dateTime.toInstant());
    System.out.println(oldfashionedDate);

Funnily output will be time zone dependent. In my time zone I got:

Mon Aug 29 12:44:00 CEST 2011

Question: Doesn’t java.time require Android API level 26?

java.time works nicely on both older and newer Android devices. It just requires at least Java 6.

  • In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
  • In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
  • On older Android either use desugaring or the Android edition of ThreeTen Backport. It’s called ThreeTenABP. In the latter case make sure you import the date and time classes from org.threeten.bp with subpackages.

Links

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文