将数字格式的时间戳转换为 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
了解现代日期时间 API
在 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
了解现代日期时间 API