【问题标题】:Clojure java-time: getting instant with millisClojure java-time:立即使用millis
【发布时间】:2021-05-13 13:18:56
【问题描述】:

我正在尝试使用 java-time 将本地日期转换为带有毫秒的即时,但即时返回不带毫秒的时间戳。

(def UTC (java-time/zone-id "UTC")

(defn local-date-to-instant [local-date] 
  (-> local-date
      (.atStartOfDay UTC)
      java-time/instant))

(local-date-to-instant (java-time/local-date))
=> #object[java.time.Instant 0xdb3a8c7 "2021-05-13T00:00:00Z"]

但是

(java-time/instant)
=> #object[java.time.Instant 0x1d1c27c8 "2021-05-13T13:12:31.782Z"]

下游服务需要这种格式的字符串:yyyy-MM-ddTHH:mm:ss.SSSZ

【问题讨论】:

  • 您是否需要分数始终存在以供以后使用.toString()?因为默认的printer/toString如果为零就不会输出(见github.com/openjdk/jdk/blob/…
  • 没错,下游服务需要这样格式的字符串:yyyy-MM-ddTHH:mm:ss.SSSZ
  • 那么您将不得不使用自己的格式化程序。请参阅stackoverflow.com/questions/38042134/…(已接受的答案或问题的第一条评论,仅用于格式化字符串 - 使用 java-time 更容易)
  • @Neikon 你确定这是一个要求吗?格式为ISO 8601,根据该标准,秒的小数部分在为零时是可选的。

标签: clojure java-time


【解决方案1】:

创建一个DateTimeFormatter 以毫秒(3 个小数位)打印 ISO 瞬间,即使它们是零:

(ns steffan.overflow
  (:require [java-time :as jt])
  (:import (java.time.format DateTimeFormatterBuilder)))

(def iso-instant-ms-formatter
  (-> (DateTimeFormatterBuilder.) (.appendInstant 3) .toFormatter))

使用示例:

(def today-inst (jt/truncate-to (jt/instant) :days))

(str today-inst)                                ; => "2021-05-13T00:00:00Z"
(jt/format iso-instant-ms-formatter today-inst) ; => "2021-05-13T00:00:00.000Z"

【讨论】:

    【解决方案2】:

    您需要使用DateTimeFormatter。然后你可以编写如下代码:

    LocalDate date = LocalDate.now();
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy MM dd");
    String text = date.format(formatter);
    

    特别是看看这些格式模式代码:

    S   fraction-of-second  fraction    978
    A   milli-of-day        number      1234
    n   nano-of-second      number      987654321
    

    我认为S 代码最适合您的目的。您必须进行一些试验,因为文档没有提供所有详细信息。

    这是一个例子:

    (ns tst.demo.core
      (:use tupelo.core tupelo.test)
      (:require
        [schema.core :as s]
        [tupelo.java-time :as tjt]
      )
      (:import
        [java.time Instant LocalDate LocalDateTime ZonedDateTime]
        [java.time.format DateTimeFormatter]
      ))
    
    (dotest
      (let [top-of-hour (tjt/trunc-to-hour (ZonedDateTime/now))
            fmt         (DateTimeFormatter/ofPattern "yyyy-MM-dd HH:mm:ss.SSS")
           ]
        (spyx top-of-hour)
        (spyx (.format top-of-hour fmt))
      ))
    

    结果

    -----------------------------------
       Clojure 1.10.3    Java 15.0.2
    -----------------------------------
    
    Testing tst.demo.core
    top-of-hour => #object[java.time.ZonedDateTime 0x9b64076 "2021-05-13T07:00-07:00[America/Los_Angeles]"]
    (.format top-of-hour fmt) => "2021-05-13 07:00:00.000"
    

    以上内容来自this template project 和库tupelo.java-time

    【讨论】:

    • 大写 S 确实是此处使用的正确模式字母。这些文档可能很简洁并假设了一些东西,但我相信当您正确阅读它们时,它们会包含所有细节。你错过了哪一部分?
    【解决方案3】:

    LocalDate 没有时间组件。 .atStartOfDay 在所有时间字段中置零。 LocalDateTime 可以通过.toInstant 转换为Instant

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-13
      • 2023-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-08
      • 1970-01-01
      相关资源
      最近更新 更多