用可变的纳秒数解析Java中的时间戳字符串

时间:2018-11-07 14:58:41

标签: java time

我有一个CSV,其中包含以下格式的时间戳:

yyyy-MM-dd HH:mm:ssX

yyyy-MM-dd HH:mm:ss.SX

yyyy-MM-dd HH:mm:ss.SSX

yyyy-MM-dd HH:mm:ss.SSSX

yyyy-MM-dd HH:mm:ss.SSSSX

yyyy-MM-dd HH:mm:ss.SSSSSX

yyyy-MM-dd HH:mm:ss.SSSSSSX

如何解析可能包含上述任何一种格式的字符串?

以下代码可以在存在3-6纳秒时解析时间戳,但是在不存在或小于3纳秒时失败。

String time = "2018-11-02 11:39:03.0438-04";
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSSX");            
Date date = sdf.parse(time);
System.out.println("Date and Time: " + date.getTime());

我目前有一个从0-6迭代并生成一个字符串的方法,该字符串的数字“ S”等于迭代变量的值。该方法尝试在try / catch中解析字符串,直到成功解析字符串为止。例如,字符串2018-11-02 11:39:03.0438-04将在成功之前尝试解析五次。

CSV是PostgreSQL表的导出,该表具有类型为TIMESTAMP WITH TIME ZONE的列,并且似乎切断了尾随的“ 0”纳秒位置。

我正在使用Java 8,并且可以使用任何外部库(Joda?)。

3 个答案:

答案 0 :(得分:3)

最好使用java.time软件包中的Java Time API 1

DateSimpleDateFormatterCalendar类是flawed且已过时。

DateTimeFormatter类提供了许多选项,因此您可以配置所需的所有内容。请注意,通过使用方法appendFraction,可以对nanos进行右填充。

String[] dateStrs = {
    "2018-11-02 11:39:03.4-04",
    "2018-11-02 11:45:22.71-04",
    "2018-11-03 14:59:17.503-04"
};

DateTimeFormatter f = new DateTimeFormatterBuilder()
    .appendPattern("yyyy-MM-dd HH:mm:ss.")
    .appendFraction(ChronoField.NANO_OF_SECOND, 1, 9, false)
    .appendPattern("X")
    .toFormatter();

// Single item:
LocalDateTime date = LocalDateTime.parse("2018-11-02 11:39:03.7356562-04", f);

// Multiple items:
List<LocalDateTime> dates = Arrays.asList(dateStrs).stream()
    .map(t -> LocalDateTime.parse(t, f))
    .collect(Collectors.toList());

1 Java 8的新日期和时间API受Joda Time的影响很大。实际上,主要作者是《乔达时报》的作者斯蒂芬·科尔本(Stephen Colebourne)。

答案 1 :(得分:0)

前19个字符相同。

此外,在不同情况下,您有不同的length。您可以使用switch测试length中的String,并为不同的可能值处理单独的case

答案 2 :(得分:0)

我不确定,但是类似的东西似乎对我有用:

String time = "2018-11-02 11:39:03.0438-04";
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSSX");            
Date date = sdf.parse(time);
System.out.println("Date and Time: " + date.getTime());

通常,您希望使用最长的格式,在这种情况下,请使用6倍S