英文版:https://github.com/clj-time/clj-time
clj-time
Clojure的日期和时间库,封装了Joda时间库。
Project Status
Joda Time网站上说:
注意,从Java SE 8开始,用户被要求迁移到Java。时间(JSR-310)——JDK的核心部分,用来替代这个项目。
如果您正在使用Java 8或更高版本,请考虑使用内置的Java时间而不是Joda时间,并查看clojure。如果您希望为此使用Clojure包装器,则使用java-time,或者cljc。瘦Clojure(脚本)包装器的java时间。参见将Joda时间转换为java。现在来详细了解这两个库之间的相似性和不同点。
Artifacts
clj-time工件被发布到clojar中。
如果使用Maven,请将以下存储库定义添加到pom.xml:
<repository>
<id>clojars.org</id>
<url>http://clojars.org/repo</url>
</repository>
最新版本
Leiningen版本:
[clj-time "0.15.2"]
Maven版本:
<dependency>
<groupId>clj-time</groupId>
<artifactId>clj-time</artifactId>
<version>0.15.2</version>
</dependency>
缺陷和改进
请在Github上打开针对官方clj-time repo的问题。clj时间是Joda时间的一个非常薄的包装。这意味着,如果Joda时间具有“特殊的行为”,那么它也可能直接在clj-time中出现。clj-time就是一个很好的例子。format/unparse简单地调用Joda Time的.print方法——如果传入的日期恰好为nil,那么您将无声地返回当前的日期/时间(许多人希望出现异常!)
邮件列表
请在clj-time邮件列表上提问。
使用
clj-time.core
clj-time库中用于日期-时间操作的主要名称空间是clj-time.core。
(require '[clj-time.core :as t])
用date-time创建一个DateTime实例,指定年、月、日、小时、分钟、秒和毫秒:
(t/date-time 1986 10 14 4 3 27 456)
=> #<DateTime 1986-10-14T04:03:27.456Z>
不太重要的字段可以省略:
(t/date-time 1986 10 14)
=> #<DateTime 1986-10-14T00:00:00.000Z>
用now获取当前时间,用epoch获取Unix纪元的开始时间。
一旦你有了日期-时间,使用像小时和秒这样的访问器来访问相应的字段:
(t/hour (t/date-time 1986 10 14 22))
=> 22
date-time构造函数总是返回UTC时区中的时间。如果您想要在不同时区使用指定字段的时间,请使用from-time-zone:
(t/from-time-zone (t/date-time 1986 10 22) (t/time-zone-for-offset -2))
=> #<DateTime 1986-10-22T00:00:00.000-02:00>
另一方面,如果你想在不同的时区得到一个给定的绝对时间点,可以使用to-time-zone:
(t/to-time-zone (t/date-time 1986 10 22) (t/time-zone-for-offset -2))
=> #<DateTime 1986-10-21T22:00:00.000-02:00>
除了time-zone for-offset之外,还可以使用time-zone for-id和默认时区函数以及utc Var来构造或获取DateTimeZone实例。
如果您只想要一个没有时间组件的日期,请考虑使用local-date和today函数。这些返回没有时间组件的LocalDate实例(因此不受时区相关迁移的影响)。
(t/local-date 2013 3 20)
=> #<LocalDate 2013-03-20>
函数equal?,after?,and before?确定两个DateTime实例的相对位置:
(t/equal? (t/date-time 1986 10) (t/date-time 1986 10))
=> true
(t/after? (t/date-time 1986 10) (t/date-time 1986 9))
=> true
(t/before? (t/date-time 1986 9) (t/date-time 1986 10))
=> true
通常情况下,你会想要从一个给定的日期中找到一个日期。例如,从给定日期-时间中找出1个月和3周的时间:
(t/plus (t/date-time 1986 10 14) (t/months 1) (t/weeks 3))
=> #<DateTime 1986-12-05T00:00:00.000Z>
你也可以做减法运算:
(t/minus (t/date-time 1986 10 14 6) (t/hours 2))
=> #<DateTime 1986-10-14T04:00:00.000Z>
Interval用于表示两个DateTime实例之间的时间跨度。构造一个使用interval,然后使用within?, overlaps?, and abuts?
(t/within? (t/interval (t/date-time 1986) (t/date-time 1990))
(t/date-time 1987))
=> true
in-seconds和in-minutes函数可以用来描述对应时间单位内的时间间隔:
(t/in-minutes (t/interval (t/date-time 1986 10 2) (t/date-time 1986 10 14)))
=> 17280
利用重叠函数得到表示两个区间重叠的区间:
(t/overlap (t/interval (t/date-time 1986) (t/date-time 1990))
(t/interval (t/date-time 1987) (t/date-time 1991)))
=> #<Interval 1987-01-01T00:00:00.000Z/1990-01-01T00:00:00.000Z>
today-at 在当前UTC日期的给定小时、分钟和秒返回时间中的某个时刻;不是当前系统日期:
(t/today-at 12 00)
=> #<DateTime 2013-03-29T12:00:00.000Z>
(t/today-at 12 00 05)
=> #<DateTime 2013-03-29T12:00:05.000Z>
;; System clock says 11PM on 12/20/2016 UTC-5
(t/today-at 7 00 00)
=> #<DateTime 2016-12-21T7:00:00.000Z>
clj-time.format
如果您需要格式化日期时间,请使用clj-time.format:
(require '[clj-time.format :as f])
格式化程序控制解析和打印。您可以使用ISO8601格式器中构建的格式之一,也可以定义自己的格式
(def built-in-formatter (f/formatters :basic-date-time))
(def custom-formatter (f/formatter "yyyyMMdd"))
记得那个mm分钟,MM是月,ss是秒,SS是毫秒。你可以找到一个comp
一旦你有了一个格式化程序、分析和打印非常简单:
(f/parse custom-formatter "20100311")
=> #<DateTime 2010-03-11T00:00:00.000Z>
(f/unparse custom-formatter (t/date-time 2010 10 3))
=> "20101003"
以多种格式解析日期和日期的格式在一个格式,可以这样做:
(def multi-parser (f/formatter (t/default-time-zone) "YYYY-MM-dd" "YYYY/MM/dd"))
(f/unparse multi-parser (f/parse multi-parser "2012-02-01"))
=> "2012-02-01"
(f/unparse multi-parser (f/parse multi-parser "2012/02/01"))
=> "2012-02-01"
注意:Joda Time的.print方法接受一个空的date/ Time对象并替换当前的date/ Time,因此(f/unparse my-fmt nil)不会抛出异常——它只会静静地返回当前的date/ Time !