(Thanks Bing Image Creator for this totally accurate portrayal of a Clojure library for working with datetimes that is also a second date)
Second Date provides a handful of utility functions for working with java.time. The most important are:
Can parse almost any temporal literal String to the correct java.time class.
(require '[second-date.core :as second-date]) (second-date/parse "2020-04") ;; -> #object[java.time.LocalDate 0x1998e54f "2020-04-01"] (second-date/parse "2020-04-01") ;; -> #object[java.time.LocalDate 0x1998e54f "2020-04-01"] (second-date/parse "2020-04-01T15:01") ;; -> #object[java.time.LocalDateTime 0x121829b7 "2020-04-01T15:01"] (second-date/parse "2020-04-01T15:01-07:00") ;; -> #object[java.time.OffsetDateTime 0x7dc126b0 "2020-04-01T15:01-07:00"] (second-date/parse "2020-04-01T15:01-07:00[US/Pacific]") ;; -> #object[java.time.ZonedDateTime 0x351fb7c8 "2020-04-01T15:01-07:00[US/Pacific]"]parse handles ISO-8601 strings as well as SQL literals (e.g. 2020-04-01 15:01:00).
You can also use the built-in literal reader second-date/t:
#second-date/t "2020-04-01T15:01" ;; -> #object[java.time.LocalDateTime 0x121829b7 "2020-04-01T15:01"]For more convenience, you may want to give this a shorter data reader tag, for example #t, in your own project.
Optionally, you can also have Second Date print Temporals in a REPL-friendly format by installing print methods with second-date/install-print-methods!:
#second-date/t "2020-04-01T15:01" ;; -> #object[java.time.LocalDateTime 0x121829b7 "2020-04-01T15:01"] (second-date/install-print-methods!) #second-date/t "2020-04-01T15:01" ;; -> #second-date/t "2020-04-01T15:01" ;; use a different data reader tag (second-date/install-print-methods! 't) #t "2020-04-01T15:01" ;; -> #t "2020-04-01T15:01"Formats any of the main java.time temporal instant classes as a String. Uses ISO-8601 by default, but can use any java.time.format.DateTimeFormatter or keywords naming static formatters as understood by clojure.java-time.
(require '[java-time :as t] '[second-date.core :as second-date]) (second-date/format (t/zoned-date-time "2020-04-01T15:01-07:00[US/Pacific]")) ;; -> "2020-04-01T16:01:00-07:00" (second-date/format (t/offset-date-time "2020-04-01T15:01-07:00")) ;; -> "2020-04-01T16:01:00-07:00" (second-date/format (t/local-date-time "2020-04-01T15:01")) ;; -> "2020-04-01T15:01:00" ;; with a different formatter (second-date/format :basic-iso-date (t/local-date-time "2020-04-01T15:01")) ;; -> "20200401" ;; it even handles Instants (second-date/format :iso-week-date (t/instant "2020-04-01T15:01:00-07:00")) ;; "2020-W14-3Z"Check the value of java-time.format/predefined-formatters for all supported predefined formatters.
second-date.parse.builder/formatter is a Clojure interface for java.time.format.DateTimeFormatterBuilder, used to create DateTimeFormatters.
(require '[java-time :as t] '[second-date :as second-date] '[second-date.parse.builder :as b]) (def my-time-formatter (b/formatter (b/case-insensitive (b/value :hour-of-day 2) (b/optional ":" (b/value :minute-of-hour 2) (b/optional ":" (b/value :second-of-minute)))))) ;; -> #object[java.time.format.DateTimeFormatter "ParseCaseSensitive(false)Value(HourOfDay,2)[':'Value(MinuteOfHour,2)[':'Value(SecondOfMinute)]]"] ;; you can now use the formatter to format and parse (second-date/format my-time-formatter (t/zoned-date-time "2020-04-01T15:23:52.878132-07:00[America/Los_Angeles]")) ;; -> "15:23:52" (second-date/parse my-time-formatter "15:23:52") ;; -> #object[java.time.LocalTime 0x514c293c "15:23:52"]Some example formatters can be found in second-date.parse.
