SimpleDateFormat时区解析
我很难解析这个日期,它末尾的 +0 导致了问题,有人知道我的格式字符串有什么问题吗?如果我从日期字符串中删除 +0 并从格式字符串中删除 Z,则它可以正常工作,但不幸的是,对于我的应用程序来说,这不是一个选项。
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
SimpleDateFormat dateFormater = new SimpleDateFormat("E, dd MMM yyyy kk:mm:ss zZ");
try {
Date d = dateFormater.parse("Sun, 04 Dec 2011 18:40:22 GMT+0");
System.out.println(d.toLocaleString());
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
一种方法是使用普通的字符串操作技术将字符串从您期望的形式转换为
SimpleDateFormat
能够理解的形式。您还没有确切地说什么范围的时区格式是可以接受的,但一种可能性是这样的:除了仍然支持任何内容之外,还支持 GMT 加或减一位或两位数的小时偏移量
SimpleDateFormat
已支持,例如EST
或GMT+1030
。或者,如果您知道它始终是 GMT,那么您可以只在格式化程序上设置时区,并忽略字符串中的时区:
您也可以分割差异。我注意到字符串中的时区格式与
TimeZone.getTimeZone()
的预期相匹配。这是故意的吗?如果是这样,您可以从字符串中获取该时区格式,预先将其传递给dateFormat.setTimeZone
,然后在实际解析过程中忽略它:One approach is to use normal string-manipulation techniques to translate your string from a form that you're expecting to a form that
SimpleDateFormat
will understand. You haven't said exactly what range of time-zone formats are acceptable, but one possibility is something like this:That would support GMT plus-or-minus a one-or-two-digit hour offset, in addition to still supporting anything already supported by
SimpleDateFormat
, such asEST
orGMT+1030
.Alternatively, if you know it will always be GMT, then you can just set the time-zone on the formatter, and ignore the time-zone in the string:
You can also split the difference. I notice that the time-zone format in your string matches what's expected by
TimeZone.getTimeZone()
. Is that intentional? If so, you can grab that time-zone format out of the string, pass it todateFormat.setTimeZone
beforehand, and then ignore it during actual parsing:如果格式一致,您可以将
0:00
附加到日期字符串。(请注意,我修复了
SimpleDateFormat
构造以显式指定用于解析星期几和月份名称的区域设置,否则在不使用英语作为默认值的平台上可能会失败我还想知道您是否实际上 需要HH
而不是kk
,但除此之外)If the format is that consistent, you could append
0:00
to the date string.(note that I fixed the
SimpleDateFormat
construction to explicitly specify the locale which would be used to parse the day of week and month names, otherwise it may fail on platforms which does not use English as default locale; I also wonder if you don't actually needHH
instead ofkk
, but that aside)tl;dr
使用现代的 java.time 类。
现代 Java 中的 java.time
避免使用存在严重缺陷的遗留类,例如
Calendar
、Date
和SimpleDateFormat
。仅使用 Java 8+ 中的 java.time 类。RFC 822 和 RFC 822 1123
您的输入字符串
"Sun, 04 Dec 2011 18:40:22 GMT+0"
似乎是 RFC 822 & RFC 1123。 Java 附带了一个预定义的格式化程序RFC_1123_DATE_TIME
对于这些标准,但您的输入变化太大,无法正常工作。提示:要以文本方式存储和交换日期时间值,请仅使用 ISO 8601 格式。
DateTimeFormatter
因此我们需要定义自己的模式来匹配您的输入。使用 <代码>DateTimeFormatter类。
Locale
我们需要一个
Locale
来指定翻译月份名称和星期名称时使用的人类语言和文化规范。OffsetDateTime
解析为
OffsetDateTime
,表示从 UTC 时间子午线偏移所看到的时刻。在这种情况下,与 UTC 的偏移量为零小时-分钟-秒。如下所示为
Z
,发音为“Zulu”。结果:
tl;dr
Use modern java.time classes.
java.time in modern Java
Avoid the terribly-flawed legacy classes such as
Calendar
,Date
, andSimpleDateFormat
. Use only the java.time classes in Java 8+.RFC 822 & 1123
Your input string
"Sun, 04 Dec 2011 18:40:22 GMT+0"
seems to be a screwy version of the outmoded standard format defined in RFC 822 & RFC 1123. Java comes with a predefined formatterRFC_1123_DATE_TIME
for those standards, but your input varies a bit too much for that to work.Tip: For storing and exchanging date-time values textually, use only ISO 8601 formats.
DateTimeFormatter
So we need to define our own pattern to match your input. Use
DateTimeFormatter
class.Locale
We need a
Locale
to specify the human language and cultural norms to be used in translating the name of the month and name of the day-of-week.OffsetDateTime
Parse as a
OffsetDateTime
, to represent a moment as seen with an offset from the temporal meridian of UTC.In this case the offset is zero hours-minutes-seconds from UTC. Shown below as
Z
, pronounced “Zulu”.Result: