简单日期格式 24 小时
我有一个 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 技术交流群。
发布评论
评论(2)
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 导入日期和时间类。
链接
- Oracle 教程:日期时间 解释如何使用 java.time。
- 维基百科文章:ISO 8601
- Java 规范请求 (JSR) 310,其中首次描述了
java.time
。 - ThreeTen Backport 项目,将
java.time
向后移植到 Java 6 和7(JSR-310 为 ThreeTen)。 - 通过脱糖提供 Java 8+ API
- ThreeTenABP,Android 版 ThreeTen 反向移植
- 问题:如何在Android项目中使用ThreeTenABP,有非常详尽的解释。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
使用
HH
而不是hh
表示小时模式:Use
HH
instead ofhh
for the hours pattern: