Search code examples
clojurejava-time

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


Using clj-time it is possible to parse an #inst Date literal like so:

(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"]

How would this be done using the new java.time wrapper clojure.java-time?


Solution

  • PLEASE NOTE: Joda Time and the clj-time library which wraps it are both deprecated. You should use java.time via Java interop for most tasks. There are also some helper functions here you may find useful.


    Clojure converts each #inst literal into a java.util.Date object. All you need is the built-in .toInstant() method:

    (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")))
        ))
    

    with result

    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]
    

    This extension to j.u.Date was added to Java at the same time as the java.time package exactly to facilitate transition of code away from java.util.Date to java.time.

    Note that you still have to be careful, as the sample instant yields two different LocalDate objects, depending on the time zone used.


    If you are working with the java.time package, you may be interested in some helper functions I wrote. The unit tests give good examples of both the helper functions and interop with native java.time functions.

    If you are looking for a function there and don't find it, there is a good chance that it already exists in the java.time package, and is easy to use directly via Java interop. java.time is a very well thought out library (by the author of the previous Joda Time library). Most features of java.time are simple & easy to use from Clojure, and do not benefit from having a wrapper function.