【问题标题】:How to convert a date time string to long (UNIX Epoch Time) in Java 8 (Scala)如何在 Java 8(Scala)中将日期时间字符串转换为长(UNIX 纪元时间)
【发布时间】:2019-06-18 04:26:26
【问题描述】:

我想要一些pattern 中的字符串的UNIX 纪元时间(Posix 时间,Unix 时间),该字符串是正常格式的(所以是UTC)。请使用 Java 8,而不是 Joda 或旧 Java。

(毫秒请见How to convert a date time string to long (UNIX Epoch Time) Milliseconds in Java 8 (Scala)

到目前为止,我有以下内容,但出于多种原因我讨厌这个:

  1. 对于最常见的日期处理方法(转换为 UNIX 纪元时间)来说,它太冗长了。 7 个方法调用应该是 1。
  2. 它必须指定UTC,但UTC肯定只是一个默认值,为什么我必须在这里明确?
  3. 它有一个字符串文字"UTC"
  4. 它有一个幻数ZoneOffset.ofHours(0)

目前为止我最好的:

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

另外,额外的问题,它有效吗?通过DateTimeFormatter.ofPattern(pattern) 创建DateTimeFormatter 是否有任何开销?如果有,为什么?

【问题讨论】:

  • 至少有一个UTC常量ZoneOffset.UTC
  • 输入是什么样的?
  • “太冗长了”:这就是为什么在计算机历史的早期就发明了子例程(又名函数或方法)的原因。
  • 是的,每次创建DateTimeFormatter 可能都会产生开销。如果担心并且模式相同,请将其设为常数。你可以安全地做到这一点,它是线程安全的。每次调用一个方法调用更少…
  • 我会认为这个问题是重复的(例如Convert a date format in epoch),但即使我永远不会使用方法调用的计数作为代码质量的指标,也有一些非常答案中出现了有趣的点。

标签: java scala datetime java-8 epoch


【解决方案1】:

您可以使用以下 Java 代码的等效代码:

static long dateTimeStringToEpoch(String s, String pattern) {
    return DateTimeFormatter.ofPattern(pattern).withZone(ZoneOffset.UTC)
        .parse(s, p -> p.getLong(ChronoField.INSTANT_SECONDS));
}

当然,处理DateTimeFormatter.ofPattern(pattern).withZone(ZoneOffset.UTC) 意味着在多次遇到相同的模式字符串时可以避免的工作。这些工作量是否与您的应用程序相关,取决于除此操作之外正在做什么。

【讨论】:

  • 非常好! 4 个方法调用而不是 7 个(我不同意提问者认为它应该是 1;我们想在转换中明确指定许多东西)。
  • @OleV.V. ...并且DateTimeFormatter.ofPattern(pattern).withZone(ZoneOffset.UTC) 的结果可以重复使用,因此实际操作是唯一的parse 调用,返回所需的值而不是需要转换的值。
【解决方案2】:

这个比它短两倍多(只有 3 个方法调用):

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

顺便说一句,我会在dateTimeStringToEpoch 之外构建DateTimeFormatter 并将其作为方法参数传递:

def dateTimeStringToEpoch(s: String, formatter: DateTimeFormatter): Long = 
     LocalDateTime.parse(s, formatter).toEpochSecond(ZoneOffset.UTC)

在实际运行了性能测试后,在方法外初始化 DateTimeFormatter 时性能几乎没有差异(几乎是 2 倍)。

scala> val pattern = "yyyy/MM/dd HH:mm:ss"
pattern: String = yyyy/MM/dd HH:mm:ss

scala>   time(() => randomDates.map(dateTimeStringToEpoch(_, pattern)))
Took: 1216

scala>   time(() => randomDates.map(dateTimeStringToEpochFixed))
Took: 732

【讨论】:

  • 这里没有.toEpochMilli 方法:(
【解决方案3】:

你能试试这个吗,根据你所说的,它正在解析 UTC 时间,所以我有这个作为示例。

Instant.parse("2019-01-24T12:48:14.530Z").getEpochSecond

【讨论】:

    猜你喜欢
    • 2019-08-03
    • 1970-01-01
    • 2012-04-03
    • 2018-02-18
    • 2017-11-10
    • 2018-10-01
    • 2021-02-19
    • 2016-09-15
    相关资源
    最近更新 更多