如何使用来自#inst Date 文字的 clojure.java-time 获得 java.time DateTime?

How can one get a java.time DateTime using clojure.java-time from #inst Date literal?

使用 clj-time 可以像这样解析 #inst Date 文字:

(require '[clj-time.coerce :as c])
(c/from-date #inst "2012-12-12")
;; => #object[org.joda.time.DateTime 0x4a251269 "2012-12-12T00:00:00.000Z"]

如何使用新的 java.time 包装器 clojure.java-time 完成此操作?

请注意:Joda Time 和包装它的 clj-time 库均已弃用。 您应该通过 Java 互操作使用 java.time对于大多数任务。还有 some helper functions here 你可能会觉得有用。


Clojure 将每个 #inst 文字转换为一个 java.util.Date 对象。您只需要内置的 .toInstant() 方法:

(ns tst.demo.core
  (:use demo.core tupelo.core tupelo.test)
  (:import [java.time ZonedDateTime ZoneId]))

(defn inst->date-time
  "Convert a java.time.Instant to a DateTime for the supplied ZoneId"
  [inst zoneid]
  (.toLocalDate zdt-utc
    (ZonedDateTime/ofInstant instant zoneid)))
    
(dotest
  (let [may-4    #inst "2018-05-04T01:23:45.678-00:00" ; a java.util.Date
        instant  (.toInstant may-4) ]
    (spyxx may-4)
    (spyx instant)
    (println "utc =>" (inst->date-time instant (ZoneId/of "UTC")))
    (println "nyc =>" (inst->date-time instant (ZoneId/of "America/New_York")))
    ))

结果

may-4    => <#java.util.Date #inst "2018-05-04T01:23:45.678-00:00">
instant  => #object[java.time.Instant 0x2207eb9f "2018-05-04T01:23:45.678Z"]
utc      => #object[java.time.LocalDate 0x62b5a16f 2018-05-04]
nyc      => #object[java.time.LocalDate 0x379b6a27 2018-05-03]

这个 j.u.Date 的扩展与 java.time 包同时添加到 Java 正是为了方便代码从 java.util.Date 到 [=13 的转换=].

请注意,您仍然需要小心,因为示例瞬间会产生两个不同的 LocalDate 对象,具体取决于所使用的时区。


如果您正在使用 java.time 程序包,您可能会对 some helper functions I wrote. The unit tests 给出辅助函数和与本机 java.time 函数互操作的良好示例感兴趣。

如果你正在寻找一个功能但没有找到它,很有可能它已经存在于 java.time 包中,并且很容易直接通过 Java 使用互操作。 java.time 是一个经过深思熟虑的库(由前一个 Joda Time 库的作者设计)。 java.time 的大多数功能在 Clojure 中都很简单易用,并且不会从包装函数中获益。