June 1, 2020
By: Kevin

java-time的使用笔记

Clojure的时间处理库, 得益于Java的历史积淀(包袱), 确实有点多:

  • Joda time
  • java.util.Date
  • clj-time
  • java-time(JDK 1.8 引入java.time的clj封装)

推荐在Java环境中完全使用java-time

以下是常用的场景, 欢迎补充:

(require '[java-time :as jt])

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; LocalDate LocalTime & localDateTime ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(jt/local-date)
;; => #object[java.time.LocalDate 0xebe2fd3 "2020-03-28"]
(jt/local-time)
;; => #object[java.time.LocalTime 0x194adc8d "10:05:36.388174"]
(jt/local-date-time)
;; => #object[java.time.LocalDateTime 0xb2aac10 "2020-03-28T10:05:50.075185"]
(jt/plus (jt/local-date-time) (jt/days 1))
;; => #object[java.time.LocalDateTime 0x773f36d7 "2020-03-29T10:05:59.947073"]

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; work with java.util.Date ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(java.util.Date.)
;; => #inst "2020-03-28T02:07:20.864-00:00"
(jt/instant)
;; => #object[java.time.Instant 0x5f921ac9 "2020-03-28T02:07:39.891959Z"]
(jt/instant->sql-timestamp (jt/instant))
;; => #inst "2020-03-28T02:08:03.449370000-00:00"
(.getTime (java.util.Date.))
;; => 1585361536803
(.toEpochMilli (jt/instant))
;; => 1585361556713
(.getEpochSecond (jt/instant))
;; => 1585361590

(.getNano (jt/instant))
;; => 657464000

(str (jt/instant))
;; => "2020-03-28T02:14:16.961433Z"

(str (java.util.Date.))
;; => "Sat Mar 28 10:14:29 CST 2020"

(java.util.Date/from (jt/instant))
;; => #inst "2020-03-28T02:15:16.477-00:00"

(.toInstant (java.util.Date.))
;; => #object[java.time.Instant 0x278e19fc "2020-03-28T02:16:30.395Z"]


;;;;;;;;;;;;;;;;
;; Zone Dates ;;
;;;;;;;;;;;;;;;;

;; 默认当前时区, 东八区+08:00 "Asia/Shanghai"
(jt/offset-time)
;; => #object[java.time.OffsetTime 0x155574e9 "09:46:37.214360+08:00"]

(jt/offset-date-time)
;; => #object[java.time.OffsetDateTime 0x37235d16 "2020-03-29T09:46:55.673565+08:00"]

(jt/zoned-date-time 2015 10)
;; => #object[java.time.ZonedDateTime 0x53f7e571 "2015-10-01T00:00+08:00[Asia/Shanghai]"]

;; 指定UTC时区
(jt/with-zone (jt/zoned-date-time 2015 10) "UTC")
;; => #object[java.time.ZonedDateTime 0x158e9ecd "2015-10-01T00:00Z[UTC]"]

;; 当前时区时间对应的UTC时间
(jt/with-zone-same-instant (jt/zoned-date-time 2015 10) "UTC")
;; => #object[java.time.ZonedDateTime 0x412a7db3 "2015-09-30T16:00Z[UTC]"]
;; 对应的纽约时间
(jt/with-zone-same-instant (jt/zoned-date-time 2015 10) "America/New_York")
;; => #object[java.time.ZonedDateTime 0x59e6f58 "2015-09-30T12:00-04:00[America/New_York]"]

(jt/zone-id)
;; => #object[java.time.ZoneRegion 0x737bd10b "Asia/Shanghai"]

(jt/with-clock (jt/system-clock "UTC")
  (jt/zone-id))
;; => #object[java.time.ZoneRegion 0x488ea7ad "UTC"]


;;;;;;;;;;;;;;;;;;;;;;;;
;; 基于属性的时间计算 ;;
;;;;;;;;;;;;;;;;;;;;;;;;


( java-time.repl/show-fields)
#_(:aligned-day-of-week-in-month
   :aligned-day-of-week-in-year
   :aligned-week-of-month
   :aligned-week-of-year
   :am-pm-of-day
   :clock-hour-of-am-pm
   :clock-hour-of-day
   :day-of-month
   :day-of-quarter
   :day-of-week
   :day-of-year
   :epoch-day
   :era
   :hour-of-am-pm
   :hour-of-day
   :instant-seconds
   :julian-day
   :micro-of-day
   :micro-of-second
   :milli-of-day
   :milli-of-second
   :minute-of-day
   :minute-of-hour
   :modified-julian-day
   :month-of-year
   :nano-of-day
   :nano-of-second
   :offset-seconds
   :proleptic-month
   :quarter-of-year
   :rata-die
   :second-of-day
   :second-of-minute
   :week-based-year
   :week-of-week-based-year
   :year
   :year-of-era)

(java-time.repl/show-units)
#_(:centuries
   :days
   :decades
   :eras
   :forever
   :half-days
   :hours
   :micros
   :millennia
   :millis
   :minutes
   :months
   :nanos
   :quarter-years
   :seconds
   :week-based-years
   :weeks
   :years)


(java-time.repl/show-adjusters)
#_(:day-of-week-in-month
   :first-day-of-month
   :first-day-of-next-month
   :first-day-of-next-year
   :first-day-of-year
   :first-in-month
   :last-day-of-month
   :last-day-of-year
   :last-in-month
   :next-day-of-week
   :next-or-same-day-of-week
   :previous-day-of-week
   :previous-or-same-day-of-week)

(jt/day-of-week (jt/zoned-date-time) )
;; => #object[java.time.DayOfWeek 0x5b7da80e "TUESDAY"]

;; 下周的第一个工作日
(jt/adjust (jt/local-date 2015 1 1) :next-day-of-week :monday)


;; 今天是周几
(.getValue (jt/day-of-week (jt/local-date)))
;; => 2

;; 今年是哪年
(.get (jt/local-date) (jt/field :year))
;; => 2020



;; 时间的所有域, 都可以用以上的方法获得, 比如从1970年一共有多少天
(.getLong (jt/local-date-time) (jt/field :epoch-day) )
;; => 18415

;; 现在的时间:12小时制
(.getLong (jt/local-date-time) (jt/field :hour-of-am-pm) )

;; 所有可以用的域
(jt/fields (jt/local-date-time))
#_{:proleptic-month
   #object[java.time.temporal.ChronoField 0x1bfb68ef "ProlepticMonth"],
   :aligned-week-of-month
   #object[java.time.temporal.ChronoField 0x2686ff70 "AlignedWeekOfMonth"],
   :julian-day
   #object[java.time.temporal.JulianFields$Field 0x6003c8ac "JulianDay"],
   :week-based-year
   #object[java.time.temporal.IsoFields$Field$4 0x65523986 "WeekBasedYear"],
   :epoch-day
   #object[java.time.temporal.ChronoField 0x252e89d3 "EpochDay"],
   :hour-of-am-pm
   #object[java.time.temporal.ChronoField 0x34c28f79 "HourOfAmPm"],
   :nano-of-second
   #object[java.time.temporal.ChronoField 0x4afa77e5 "NanoOfSecond"],
   :aligned-week-of-year
   #object[java.time.temporal.ChronoField 0x3e10f935 "AlignedWeekOfYear"],
   :era #object[java.time.temporal.ChronoField 0x6f219f35 "Era"],
   :rata-die
   #object[java.time.temporal.JulianFields$Field 0x4f387cef "RataDie"],
   :micro-of-day
   #object[java.time.temporal.ChronoField 0x56646fb2 "MicroOfDay"],
   :minute-of-day
   #object[java.time.temporal.ChronoField 0x6f84ed1a "MinuteOfDay"],
   :day-of-week
   #object[java.time.temporal.ChronoField 0xcbf0fe8 "DayOfWeek"],
   :clock-hour-of-day
   #object[java.time.temporal.ChronoField 0xecc594 "ClockHourOfDay"],
   :hour-of-day
   #object[java.time.temporal.ChronoField 0x758023c4 "HourOfDay"],
   :month-of-year
   #object[java.time.temporal.ChronoField 0x3d24fc53 "MonthOfYear"],
   :milli-of-second
   #object[java.time.temporal.ChronoField 0x49907450 "MilliOfSecond"],
   :micro-of-second
   #object[java.time.temporal.ChronoField 0x2f36d893 "MicroOfSecond"],
   :aligned-day-of-week-in-month
   #object[java.time.temporal.ChronoField 0x5bdc40b2 "AlignedDayOfWeekInMonth"],
   :day-of-month
   #object[java.time.temporal.ChronoField 0x4100e9fe "DayOfMonth"],
   :year #object[java.time.temporal.ChronoField 0xbf8277a "Year"],
   :day-of-year
   #object[java.time.temporal.ChronoField 0x129384d6 "DayOfYear"],
   :day-of-quarter
   #object[java.time.temporal.IsoFields$Field$1 0x2bf38fe6 "DayOfQuarter"],
   :year-of-era
   #object[java.time.temporal.ChronoField 0x6dfacc7f "YearOfEra"],
   :am-pm-of-day
   #object[java.time.temporal.ChronoField 0x2773e54d "AmPmOfDay"],
   :nano-of-day
   #object[java.time.temporal.ChronoField 0x29487041 "NanoOfDay"],
   :second-of-minute
   #object[java.time.temporal.ChronoField 0x1ef34631 "SecondOfMinute"],
   :aligned-day-of-week-in-year
   #object[java.time.temporal.ChronoField 0x2551e8a4 "AlignedDayOfWeekInYear"],
   :second-of-day
   #object[java.time.temporal.ChronoField 0x1d3038ce "SecondOfDay"],
   :modified-julian-day
   #object[java.time.temporal.JulianFields$Field 0x77908951 "ModifiedJulianDay"],
   :week-of-week-based-year
   #object[java.time.temporal.IsoFields$Field$3 0x73d68b5c "WeekOfWeekBasedYear"],
   :milli-of-day
   #object[java.time.temporal.ChronoField 0x5968494a "MilliOfDay"],
   :clock-hour-of-am-pm
   #object[java.time.temporal.ChronoField 0x4502fce1 "ClockHourOfAmPm"],
   :quarter-of-year
   #object[java.time.temporal.IsoFields$Field$2 0x362b3f11 "QuarterOfYear"],
   :minute-of-hour
   #object[java.time.temporal.ChronoField 0x71e0dee3 "MinuteOfHour"]}

;; 今年的第一天是周几?
(jt/day-of-week (jt/adjust (jt/local-date) :first-day-of-year))
;; => #object[java.time.DayOfWeek 0x4db1d95e "WEDNESDAY"]


;; 本周是今年的第几周
(jt/value (jt/property (jt/local-date) :week-of-week-based-year))
;; => 23

;; 今年第50周的日期
(jt/with-value (jt/property (jt/local-date) :week-of-week-based-year) 50)
;; => #object[java.time.LocalDate 0x5d80bd2c "2020-12-08"]


;;;;;;;;;;;;
;; 格式化 ;;
;;;;;;;;;;;;


;; data-> str
(jt/format "MM/dd" (jt/zoned-date-time 2015 9 28))
;;"09/28"

;; 格式化的字符串-> date
(local-date "MM/yyyy/dd" "09/2015/28")
;; #object[java.time.LocalDate "2015-09-28"]
Tags: clojure