如何在Java 8(Scala)中将日期时间字符串转换为long(UNIX纪元时间)毫秒

问题描述 投票:1回答:3

这个问题解决了几秒钟的情况:How to convert a date time string to long (UNIX Epoch Time) in Java 8 (Scala)

但如果我想要毫秒,似乎我必须使用

def dateTimeStringToEpoch(s: String, pattern: String): Long = 
    LocalDateTime.parse(s, DateTimeFormatter.ofPattern(pattern))
      .atZone(ZoneId.ofOffset("UTC", ZoneOffset.ofHours(0)))
      .toInstant().toEpochMilli

对于我在另一个问题中详述的4个问题是丑陋的(我不喜欢的主要事情是魔法文字"UTC"和魔法数字0)。

不幸的是,以下内容无法编译

def dateTimeStringToEpoch(s: String, pattern: String): Long = 
     LocalDateTime.parse(s, DateTimeFormatter.ofPattern(pattern))
                  .toEpochMilliSecond(ZoneOffset.UTC)

因为toEpochMilliSecond不存在

java scala datetime java-8 epoch
3个回答
5
投票

你能不能使用LocalDateTime#atOffsetZoneOffset#UTC

LocalDateTime.parse(s, pattern).atOffset(ZoneOffset.UTC).toInstant().toEpochMilli()

正如@Andreas在评论中指出的那样,ZoneOffset是一个ZoneId,所以你可以使用

def dateTimeStringToEpoch(s: String, pattern: String): Long = 
    LocalDateTime.parse(s, DateTimeFormatter.ofPattern(pattern))
      .atZone(ZoneOffset.UTC)
      .toInstant()
      .toEpochMilli()

2
投票

您可以将this answer更改为返回epoch millis

static long dateTimeStringToEpoch(String s, String pattern) {
    return DateTimeFormatter.ofPattern(pattern).withZone(ZoneOffset.UTC)
        .parse(s, Instant::from).toEpochMilli();
}

或者,如果你甚至想避免建造一个临时的Instant

static long dateTimeStringToEpoch(String s, String pattern) {
    return DateTimeFormatter.ofPattern(pattern).withZone(ZoneOffset.UTC)
        .parse(s, ta -> ta.getLong(ChronoField.INSTANT_SECONDS)*1000
                       +ta.get(ChronoField.MILLI_OF_SECOND));
}

请注意,DateTimeFormatter.ofPattern(pattern).withZone(ZoneOffset.UTC)ta -> ta.getLong(ChronoField.INSTANT_SECONDS)*1000+ta.get(ChronoField.MILLI_OF_SECOND)都是可重复使用的组件,例如:你能做到的

static final DateTimeFormatter MY_PATTERN
    = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm").withZone(ZoneOffset.UTC);
static final TemporalQuery<Long> EPOCH_MILLIS
    = ta -> ta.getLong(ChronoField.INSTANT_SECONDS)*1000+ta.get(ChronoField.MILLI_OF_SECOND);

long millis = MY_PATTERN.parse("2018-07-21 18:30", EPOCH_MILLIS);

问题是,您希望在应用程序中出现多少种不同的格式字符串。通常,它不会像您必须解析的格式化日期那样频繁地更改。创建从格式字符串到准备好的DateTimeFormatter的缓存映射可能是有益的。无论如何,lambda表达式都是单例。


1
投票

使用UNIX Epoch时,我建议使用java.time.Instant作为纪元表示设计,并默认考虑UTC,因为它是标准的一部分。

import java.time.Instant

object InstantFormat extends App {

  //Instant.parse uses DateTimeFormatter.ISO_INSTANT
  println(Instant.parse("2019-03-12T15:15:13.147Z"))
  println(Instant.parse("2019-03-12T15:15:13Z"))
  println(Instant.parse("2019-03-12T15:15:13Z").toEpochMilli)
  println(Instant.parse("2019-03-12T15:15:13Z").getEpochSecond)
  println(Instant.ofEpochMilli(1552403713147L))
  println(Instant.ofEpochSecond(1552403713L))
}

输出

2019-03-12T15:15:13.147Z
2019-03-12T15:15:13Z
1552403713000
1552403713
2019-03-12T15:15:13.147Z
2019-03-12T15:15:13Z
© www.soinside.com 2019 - 2024. All rights reserved.