【问题标题】:DateTimeFormatter to parse string with both Zone offset and timezoneDateTimeFormatter 解析带有区域偏移量和时区的字符串
【发布时间】:2021-12-05 06:10:59
【问题描述】:

这个问题听起来可能与 Stackoverflow 上的大多数其他问题相似,但我无法弄清楚我的问题。 我想把字符串值解析成日期。

String dateTime = "2020 年 10 月 23 日 02:44:58 +1000"

这个问题的解决方法是:

DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
builder.parseCaseInsensitive();
builder.appendPattern("d MMM yyyy HH:mm[:ss] Z");
DateTimeFormatter dtf = builder.toFormatter();

ZonedDateTime zonedDateTime = ZonedDateTime.parse(dateTime, dtf);
Instant instant = zonedDateTime.toInstant();
Date finalDate = Date.from(instant);

如果我想用时区解析日期,而不是像 String dateTime = "23 Oct 2020 02:44:58 AEST" 那么我需要更改 builder.appendPattern ("d MMM yyyy HH:mm[:ss] Z"); 从大写 Z 到小 z 如提到的here

这里的问题是如何使我的解析器足够灵活,以便它处理时区或偏移值?

注意。我使用 [ss] 作为秒字段是可选的。根据文档,使用 VV 与 z 类似,而“V”对我不起作用。

【问题讨论】:

  • 尽可能避免解析时区缩写,如AEST。虽然AEST 可能是明确的,但大多数最常见的缩写都是模棱两可的,你不知道你得到了什么。

标签: java datetime java-8 zoneddatetime datetimeformatter


【解决方案1】:

您可以将它们作为可选部分添加到格式化程序中,就像您对秒部分所做的那样:

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    .parseCaseInsensitive()
    .appendPattern("d MMM yyyy HH:mm[:ss] [Z][z]")
    .toFormatter(Locale.ROOT);

Online demo

[] 表示可选部分:如果可以通过括号内的模式成功解析相应的文本,则消耗相应的文本,否则不消耗任何文本,并且其中的模式被跳过。

【讨论】:

  • 非常感谢您的回答。如果我可以向您提出建议,您如何推荐某人来提高他们的 Java 技能? ?
  • 我将Locale.ROOT 传递给toFormatter,因为DateTimeFormatter 对区域设置敏感,而对于我的默认区域设置,“Oct”不起作用。
  • 嗯,关于提高 Java 技能——通过试验,但也阅读这件事。并确保您获取没有过时的教程或书籍。
【解决方案2】:

您可以尝试使用 try-catch 块

DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder(); 
builder.parseCaseInsensitive(); 
builder.appendPattern("d MMM yyyy HH:mm[:ss] Z"); 
DateTimeFormatter dtf = builder.toFormatter();

DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder(); 
builder.parseCaseInsensitive(); 
builder.appendPattern("d MMM yyyy HH:mm[:ss] z"); 
DateTimeFormatter dtf = builder.toFormatter();

ZonedDateTime zonedDateTime;
try {
    zonedDateTime = ZonedDateTime.parse(dateTime, dtf1);
} catch (DateTimeParseException e) {
    zonedDateTime = ZonedDateTime.parse(dateTime, dtf2);
}
Instant instant = zonedDateTime.toInstant();
Date finalDate = Date.from(instant);

【讨论】:

  • 非常感谢您的回答和帮助。我觉得MC Emperor给出的答案更简洁,所以将他的答案标记为正确的
猜你喜欢
  • 2015-10-27
  • 1970-01-01
  • 1970-01-01
  • 2015-02-02
  • 1970-01-01
  • 2015-08-23
  • 2014-04-24
  • 2017-10-16
相关资源
最近更新 更多