将数字格式的时间戳转换为 Java 中的 LocalDateTime

Convert Timestamp in numerical format to LocalDateTime in Java

在 API 调用中,我收到的时间戳为:1591290491238。我需要将其转换为 Java 中的 LocalDateTime。我把代码写成:

String timestamp = "1584453053825";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMdduuHHmmss");
LocalDateTime localDateTime = LocalDateTime.parse( timestamp , formatter );

但它抛出一个错误:

Text '1584453053825' could not be parsed at index 12

该数字表示 Unix 格式的时间,即自纪元以来经过的毫秒数,即 1970 年 1 月 1 日午夜 UTC。

您可以像这样将其转换为 LocalDateTime

LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(Long.parseLong(timestamp)), ZoneId.systemDefault());

使用 ZonedDateTime 作为日期和时间

您的时间戳是自 Java/Unix 纪元 1970 年 1 月 1 日开始的毫秒数(UTC 时间)。要将其转换为一天中的日期和时间,您首先需要为其确定一个时区,因为它在所有时区中都不会是同一时间(甚至不是同一日期)。只要计数大于1000,Java直接解析包含它的字符串。

    ZoneId zone = ZoneId.of("America/New_York");
    DateTimeFormatter numericalFormatter = new DateTimeFormatterBuilder()
            .appendValue(ChronoField.INSTANT_SECONDS, 1, 19, SignStyle.NEVER)
            .appendValue(ChronoField.MILLI_OF_SECOND, 3)
            .toFormatter()
            .withZone(zone);
    
    String timestamp = "1591290491238";
    
    ZonedDateTime dateTime = ZonedDateTime.parse(timestamp, numericalFormatter);
    
    System.out.println(dateTime);

此示例片段的输出是:

2020-06-04T13:08:11.238-04:00[America/New_York]

正如 Basil Bourque 在评论中所说的那样,LocalDateTime 与您的日期和时间不符 class。 ZonedDateTime 为您提供相同且更多,因为它还包含时区,因此定义了原始时间戳字符串定义的时间点。您可以转换为 LocalDateTime 从而丢弃您想要保留的信息。因此,仅当您需要 LocalDateTime 用于 API 时才这样做,而这些 API 是由不明白这是错误的 class.

的人设计的
    LocalDateTime amputatedDateTime = dateTime.toLocalDateTime();
    System.out.println(amputatedDateTime);

2020-06-04T13:08:11.238

您注意到我们现在已经丢失了与 UTC 和时区的偏移量。

你的代码出了什么问题?

您尝试使用 MMdduuHHmmss 格式模式解析字符串。该模式定义了 12 个数字,但字符串中有 13 个数字。您使用的模式假设 1591290491238 指的是 2090 年第 159 个月的第 12 天 49:12:38 的 24 小时时钟,或类似的东西。这是无稽之谈。也因为正如我所说,数字指的是时间点,而不是日期和时间,要获得后者,我们首先需要提供时区。

您的时间戳实际上是从 1970-01-01T00:00:00Z 纪元算起的毫秒数,其中 Z 代表 Zulu 日期时间或 UTC 日期时间(即时区偏移量) +00:00 小时)。您应该将其解析为 long,然后从中获取 Instant

一旦你有了Instant的对象,你就可以从中获取其他日期时间类型的对象,如下所示:

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String timestamp = "1584453053825";
        long epochMilli = Long.parseLong(timestamp);
        Instant instant = Instant.ofEpochMilli(epochMilli);

        // Convert instant to ZonedDateTime with the time zone of JVM
        ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());

        // Get LocalDateTime from instant
        LocalDateTime ldt = zdt.toLocalDateTime();

        // Display ldt in the default format i.e. the value returned by ldt#toString
        System.out.println(ldt);

        // Display ldt in a custom format e.g. EEE MMMM dd, uuuu hh:mm:ss a
        System.out.println(ldt.format(DateTimeFormatter.ofPattern("EEE MMMM dd, uuuu hh:mm:ss a", Locale.ENGLISH)));
    }
}

输出:

2020-03-17T13:50:53.825
Tue March 17, 2020 01:50:53 PM

Trail: Date Time.

了解现代日期时间 API