【问题标题】:How to convert multiple string of date formats to timestamp with timezone format [duplicate]如何将多个日期格式字符串转换为具有时区格式的时间戳[重复]
【发布时间】:2023-03-08 00:22:01
【问题描述】:

我想将多字符串日期格式转换成时间戳

例如,我有以下日期字符串,如下所示

String date1 = "2020-01-01 12:23:30.345"
String date2 = "2020-01-01 12:23:30"
String date3 = "2020-01-01 12:23"
String date4 = "2020-01-01 12"

我想将上述所有字符串格式转换为时间戳,

For date1, Timestamp should be 2020-01-01 12:23:30.345 UTC
For date2, Timestamp should be 2020-01-01 12:23:30.000 UTC
For date3, Timestamp should be 2020-01-01 12:23:00.000 UTC
For date4, Timestamp should be 2020-01-01 12:00:00.000 UTC

你能帮我解决这个问题吗?任何信息都会非常有帮助。我无法定义为解析器格式化的单个字符串,因为字符串格式在我的场景中是不可预测的。

【问题讨论】:

  • 还有时间戳现在是遗留的,我建议学习java.time library

标签: java date utc java-time


【解决方案1】:

您可以对缺少的部分使用可选模式(方括号内)。您还可以使用DateTimeFormatterBuilder#parseDefaulting 将缺少的时间部分默认为0 或任何其他值。

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtfForFormating = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSS", Locale.ENGLISH);

        // Tests
        System.out.println(getLocalDateTime("2020-01-01 12:23:30.345"));
        System.out.println(getLocalDateTime("2020-01-01 12:23:30.345").format(dtfForFormating));
        
        System.out.println(getLocalDateTime("2020-01-01 12:23:30"));
        System.out.println(getLocalDateTime("2020-01-01 12:23:30").format(dtfForFormating));
        
        System.out.println(getLocalDateTime("2020-01-01 12:23"));
        System.out.println(getLocalDateTime("2020-01-01 12:23").format(dtfForFormating));
        
        System.out.println(getLocalDateTime("2020-01-01 12"));
        System.out.println(getLocalDateTime("2020-01-01 12").format(dtfForFormating));
    }

    static LocalDateTime getLocalDateTime(String text) {
        DateTimeFormatter multiFormatter = new DateTimeFormatterBuilder()
                                            .appendPattern("uuuu-MM-dd HH[:mm][:ss][.SSS]")
                                            .parseDefaulting(ChronoField.NANO_OF_SECOND, 0)
                                            .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
                                            .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)                                         
                                            .toFormatter(Locale.ENGLISH);

        return LocalDateTime.parse(text, multiFormatter);
    }
}

输出:

2020-01-01T12:23:30.345
2020-01-01 12:23:30.345
2020-01-01T12:23:30
2020-01-01 12:23:30.000
2020-01-01T12:23
2020-01-01 12:23:00.000
2020-01-01T12:00
2020-01-01 12:00:00.000

更新

这是根据 OP 的要求更新时区的日期时间。

LocalDateTime 没有时区信息。为了获得时区信息,您需要将其转换为ZonedDateTime

演示:

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtfForFormating = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSS z", Locale.ENGLISH);

        // Tests
        System.out.println(getZonedDateTime("2020-01-01 12:23:30.345"));
        System.out.println(getZonedDateTime("2020-01-01 12:23:30.345").format(dtfForFormating));

        System.out.println(getZonedDateTime("2020-01-01 12:23:30"));
        System.out.println(getZonedDateTime("2020-01-01 12:23:30").format(dtfForFormating));

        System.out.println(getZonedDateTime("2020-01-01 12:23"));
        System.out.println(getZonedDateTime("2020-01-01 12:23").format(dtfForFormating));

        System.out.println(getZonedDateTime("2020-01-01 12"));
        System.out.println(getZonedDateTime("2020-01-01 12").format(dtfForFormating));
    }

    static ZonedDateTime getZonedDateTime(String text) {
        DateTimeFormatter multiFormatter = new DateTimeFormatterBuilder()
                                            .appendPattern("uuuu-MM-dd HH[:mm][:ss][.SSS]")
                                            .parseDefaulting(ChronoField.NANO_OF_SECOND, 0)
                                            .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
                                            .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
                                            .toFormatter(Locale.ENGLISH);

        return LocalDateTime.parse(text, multiFormatter).atZone(ZoneId.of("Etc/UTC"));
    }
}

输出:

2020-01-01T12:23:30.345Z[Etc/UTC]
2020-01-01 12:23:30.345 UTC
2020-01-01T12:23:30Z[Etc/UTC]
2020-01-01 12:23:30.000 UTC
2020-01-01T12:23Z[Etc/UTC]
2020-01-01 12:23:00.000 UTC
2020-01-01T12:00Z[Etc/UTC]
2020-01-01 12:00:00.000 UTC

【讨论】:

  • 您好 Arvind,感谢您的解决方案,它工作正常。还有一个问题,在时间戳中,如何将时区添加为可选模式。例如:如果我的输入字符串是“2020-01-01 12:30”,我的输出字符串应该是“2020-01-01 12:30:00.000 UTC”
  • 嗨,Arvind,我想我的问题已经结束了。您能否在此聊天中粘贴更新的内容?我试图重新打开它,但我得到了一些错误。
  • @saravanakumar - 不客气。祝你成功!我已将其添加为更新。
  • 很好的答案。 (1) 我会嵌套括号,因为我们只在有分钟时允许秒,而在有秒时只允许毫秒。 (2) 虽然对parseDefaulting() 的调用可能有助于理解,但如果我们愿意,我们也可以不使用它们(只要我们想默认为 0)。所以只需:DateTimeFormatter multiFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH[:mm[:ss[.SSS]]]", Locale.ENGLISH);.
【解决方案2】:

您可以使用两种格式化程序,一种将String 转换为LocalDateTime,另一种将LocalDateTime 转换为预期的String

String[] dates = {date1, date2, date3, date4};
DateTimeFormatter formatterIn = DateTimeFormatter.ofPattern("yyyy-MM-dd HH[:mm][:ss][.SSS]");
DateTimeFormatter formatterOut = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");

for (String date : dates) {
    LocalDateTime ldtIn = LocalDateTime.parse(date, formatterIn);
    String ldtOut = ldtIn.format(formatterOut);
    System.out.println(ldtOut);
}

输出

2020-01-01 12:23:30.345
2020-01-01 12:23:30.000
2020-01-01 12:23:00.000
2020-01-01 12:00:00.000

【讨论】:

  • 使用uuuu 比使用yyyy 更安全。请检查this discussion作为参考。
猜你喜欢
  • 1970-01-01
  • 2023-03-27
  • 2021-07-15
  • 2014-08-10
  • 2021-11-30
  • 2012-04-19
  • 1970-01-01
  • 2021-11-06
相关资源
最近更新 更多