Java中用于解析任何日期格式的单一类

3

我一直在解析以下格式的日期。我维护这些格式的数组,并解析所有这些格式中的每个日期字符串。

我使用的代码是-

SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat);
simpleDateFormat.setTimeZone(timeZone); //timeZone is a java.util.TimeZone object       
Date date = simpleDateFormat.parse(dateString);

现在我想要解析 yyyy-MM-dd'T'HH:mm:ss.SSSSSSXXX 格式,但使用 SimpleDateFormat 时,6 位数的微秒不会被考虑在内。因此,我研究了 java.time 包。
要解析 yyyy-MM-dd'T'HH:mm:ss.SSSSSSXXX 格式,我需要使用 OffsetDateTime 类;对于其他格式,我需要使用 ZonedDateTime 类。日期时间格式将在 DateTimeFormatter 类中设置。 是否有一种方法可以使用单个类(如 SimpleDateFormat)来传递所有格式?

可能是Java字符串转日期转换的重复问题,请查看此答案https://dev59.com/SW855IYBdhLWcg3wp2N0#4216767。 - xxxvodnikxxx
这取决于您需要的结果。如果类似于“日期”(即没有时区或偏移量)的东西对您来说可以接受,只需使用“Instant”和“yourDateTimeFormatter.parse(yourString, Instant::from)”即可。 - Ole V.V.
1
你的搜索结果是什么?已经有几个非常相似的问题了。 - Ole V.V.
1
“任何格式”显然是不可能的。您能否更具体地说明您的格式要求?可以给出5个例子吗? - Ole V.V.
1
相关:SimpleDateFormat 忽略字符。请查看并搜索更多内容。 - Ole V.V.
显示剩余7条评论
1个回答

2
由于您的Java 8不像合理预期的那样运行,我建议尝试首先解析没有时区的字符串。如果从字符串中解析出时区或偏移量,则将使用它。如果没有时区的解析失败,请尝试使用时区。以下方法可以实现这一点:
private static void parseAndPrint(String formatPattern, String dateTimeString) {
    // Try parsing without zone first
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(formatPattern);
    Instant parsedInstant;
    try {
        parsedInstant = formatter.parse(dateTimeString, Instant::from);
    } catch (DateTimeParseException dtpe) {
        // Try parsing with zone
        ZoneId defaultZone = ZoneId.of("Asia/Calcutta");
        formatter = formatter.withZone(defaultZone);
        parsedInstant = formatter.parse(dateTimeString, Instant::from);
    }
    System.out.println("Parsed instant: " + parsedInstant);
}

让我们试试:
    parseAndPrint("yyyy-MM-dd'T'HH:mm:ss.SSSSSSXXX", "2018-10-22T02:17:58.717853Z");
    parseAndPrint("yyyy-MM-dd'T'HH:mm:ss.SSSSSS", "2018-10-22T02:17:58.717853");
    parseAndPrint("EEE MMM d HH:mm:ss zzz yyyy", "Mon Oct 22 02:17:58 CEST 2018");

Java 8 的输出为:
Parsed instant: 2018-10-22T02:17:58.717853Z
Parsed instant: 2018-10-21T20:47:58.717853Z
Parsed instant: 2018-10-22T00:17:58Z
第一个例子在字符串中有一个偏移量,最后一个例子在字符串中有一个时区缩写,并且在这两种情况下都会被尊重:打印的瞬间已经调整了时间到UTC(因为Instant始终以UTC打印,它的toString方法会确保)。中间的例子在字符串中既没有偏移量也没有时区,因此使用了方法中指定的Asia/Calcutta的默认时区。
话虽如此,解析三个或四个字母的时区缩写(如CEST)是一种危险和不鼓励的做法,因为这些缩写通常是模糊的。我只是为了演示而包含了这个例子。
“是否有一种方式可以使用单个类...?”
我对所有情况都使用了Instant,所以是的,有一种方法只使用一个类。局限性在于您事后不知道字符串中是否有任何时区或偏移量,也不知道它是什么。您使用SimpleDateFormat和Date时也不知道,所以我觉得这没问题?
Java 8中的一个错误?
你在 REX 测试器上的演示结果令人失望且错误,并且与我在 Java 11 上得到的结果不一致。我觉得你可能遇到了 Java 8 中的一个 bug,可能是这个:DateTimeFormatter.withZone 解析并没有按照 javadocs 中的描述行事。

1
我已经使用OffsetDateTime来处理这个特定的格式。谢谢你的帮助。 - Forever NewUser

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接