Julia - 日期和时间

Julia 有一个名为 Dates 的标准包,它为我们提供了以下两个处理日期和时间的函数 −

  • Using Dates

  • Import Dates

这两个函数之间的区别在于,如果我们使用 import Dates 函数,那么我们必须在每个函数中显式地添加日期前缀,例如 Dates.dayofweek(dt)。 另一方面,如果我们使用 using Dates 函数,那么我们不必在每个函数中显式添加前缀 Dates,因为它将把所有导出的 Dates 函数带入 main 中。

类型之间的关系

Julia 使用各种类型来存储日期、时间和日期时间。 下图展示了这些类型之间的关系 −

日期和时间

日期和时间1

Date, Time, 和 DateTimes

为了使用日期和时间,Julia 具有以下三种数据类型 −

Dates.Time − 该对象精确到纳秒,代表一天中的精确时刻。

Dates.Date − 顾名思义,它只代表一个日期。

Dates.DateTime − 该对象精确到毫秒,表示日期和一天中的时间的组合。 它实际上指定了一个确切的时间点。

示例

julia> rightnow = Dates.Time(Dates.now())
15:46:39.872

julia> My_Birthday = Dates.Date(1984,1,17)
1984-01-17

julia> armistice_date = Dates.DateTime(1990,11,11,11,11,11)
1990-11-11T11:11:11

julia> today_date = Dates.today()
2020-09-22

julia> Dates.now(Dates.UTC)
2020-09-22T10:18:32.008

julia> Dates.DateTime("20180629 120000", "yyyymmdd HHMMSS")
2018-06-29T12:00:00

julia> Dates.DateTime("19/07/2007 17:42", "dd/mm/yyyy HH:MM")
2007-07-19T17:42:00

重新分级日期和时间的查询

有了日期/时间或日期等对象后,我们可以使用以下函数来提取所需的信息 −

julia> Dates.year(My_Birthday)
1984
julia> Dates.month(My_Birthday)
1
julia> Dates.minute(now())
22
julia> Dates.hour(now())
19
julia> Dates.second(now())
19
julia> Dates.minute(rightnow)
46
julia> Dates.hour(rightnow)
15
julia> Dates.second(rightnow)
39
julia> Dates.dayofweek(My_Birthday)
2
julia> Dates.dayname(My_Birthday)
"Tuesday"
julia> Dates.yearmonthday(My_Birthday)
(1984, 1, 17)
julia> Dates.dayofweekofmonth(My_Birthday)
3

日期运算

还可以对日期/时间以及日期对象进行算术运算。 最常见的方法是查找两个此类对象之间的差异,如下例所示 −

示例

julia> today_date - My_Birthday
13409 days

julia> datetimenow - armistice_date
943436237800 milliseconds

我们可以将这些差异转换为某种单位,如下所示 −

julia> Dates.Period(today_date - My_Birthday)
13409 days

julia> Dates.canonicalize(Dates.CompoundPeriod(datetimenow - armistice_date))
1559 weeks, 6 days, 9 hours, 37 minutes, 17 seconds, 800 milliseconds

我们还可以对日期和日期/时间对象添加和减去时间段,如下所示 −

julia> My_Birthday + Dates.Year(20) + Dates.Month(6)
2004-07-17

在上面的示例中,我们在我的出生日期上添加了 20 年零 6 个月。

日期范围

Julia 提供了通过创建可迭代范围对象来创建日期范围的工具。 在下面给出的示例中,我们将创建一个生成每个月第一天的迭代器。

示例

julia> date_range = Dates.Date(2000,1,1):Dates.Month(1):Dates.Date(2020,1,1)
Date("2000-01-01"):Month(1):Date("2020-01-01")

从上面的范围对象中,我们可以找出其中哪些属于工作日。 为此,我们需要为 filter() 创建一个匿名函数,它将根据给定的日期名称测试日期名称 −

julia> weekdaysfromrange = filter(dy -> Dates.dayname(dy) != "Saturday" && Dates.dayname(dy) != "Sunday" , date_range)
171-element Array{Date,1}:
 2000-02-01
 2000-03-01
 2000-05-01
 2000-06-01
 2000-08-01
 2000-09-01
 2000-11-01
 2000-12-01
 2001-01-01
 2001-02-01
 2001-03-01
 2001-05-01
 2001-06-01
 ⋮
 2018-10-01
 2018-11-01
 2019-01-01
 2019-02-01
 2019-03-01
 2019-04-01
 2019-05-01
 2019-07-01
 2019-08-01
 2019-10-01
 2019-11-01
 2020-01-01

日期格式

下表给出了日期格式代码,我们可以借助它来指定日期格式 −

字符代码 日期/时间元素
Y 年份数字 yyyy => 1984, yy => 84
m 月份数字 m => 7 或 07
u 月份名称简称 Jun
U 月份名称 例如 January
e 星期几简称 Mon
E 星期几 Monday
d 月份第几日 1 或 01
H 小时 HH => 00
M 分钟 MM => 00
S 秒 S => 00
s 毫秒 .000

示例

julia> Dates.Date("Sun, 27 Sep 2020", "e, d u y")
2020-09-27

julia> Dates.DateTime("Sun, 27 Sep 2020 10:25:10", "e, d u y H:M:S")
2020-09-27T10:25:10

舍入日期和时间

众所周知,函数 round()、floor() 和 ceil() 通常用于对数字进行向上或向下舍入。 这些函数还可用于对日期进行舍入,以便可以及时向前或向后调整日期。

示例

julia> Dates.now()
2020-09-27T13:34:03.49

julia> Dates.format(round(Dates.DateTime(Dates.now()), Dates.Minute(15)), Dates.RFC1123Format)
"Sun, 27 Sep 2020 13:30:00"

ceil() 函数将向前调整日期/时间,如下所示 −

julia> My_Birthday = Dates.Date(1984,1,17)
1984-01-17

julia> ceil(My_Birthday, Dates.Month)
1984-02-01

julia> ceil(My_Birthday, Dates.Year)
1985-01-01

julia> ceil(My_Birthday, Dates.Week)
1984-01-23

重复日期

如果我们要查找某个日期范围内满足某些条件的所有日期,则称为循环日期。 让我们借助以下示例来理解 −

首先,我们需要像之前一样创建一个日期范围 −

julia> date_range = Dates.Date(2000,1,1):Dates.Month(1):Dates.Date(2020,1,1)
Date("2000-01-01"):Month(1):Date("2020-01-01")

现在我们可以使用filter()函数来查找一个月中的星期日 −

julia> filter(d -> Dates.dayname(d) == "Sunday", date_range)
35-element Array{Date,1}:
 2000-10-01
 2001-04-01
 2001-07-01
 2002-09-01
 2002-12-01
 2003-06-01
 2004-02-01
 2004-08-01
 2005-05-01
 2006-01-01
 2006-10-01
 2007-04-01
 2007-07-01
 ⋮
 2013-12-01
 2014-06-01
 2015-02-01
 2015-03-01
 2015-11-01
 2016-05-01
 2017-01-01
 2017-10-01
 2018-04-01
 2018-07-01
 2019-09-01
 2019-12-01

Unix 时间

Unix 时间是另一种计时方式,它计算自 Unix 诞生(1970 年初)以来经过的秒数。 我们永远不会观察到 Unix 时间的结束,因为 Julia 将计数存储在 64 位整数中。

time()函数将返回Unix时间值 −

julia> using Dates
julia> time()
1.60206441103e9

unix2datetime() 函数会将 Unix 时间值转换为日期/时间对象 −

julia> Dates.unix2datetime(time())
2020-09-10T09:54:52.894

时刻

日期时间在即时字段中以毫秒为单位存储。 我们可以使用 Dates.value 函数获取该值,如下所示 −

julia> moment=Dates.now()
2020-09-10T09:56:11.885

julia> Dates.value(moment)
63737767811885

julia> moment.instant
Dates.UTInstant{Millisecond}(Millisecond(63737767811885))

时间和监控

Julia 为我们提供了 @elapsed 宏,它将返回表达式计算所需的时间(秒数)。

示例

julia> function foo(n)
            for i in 1:n
               x = sin(rand())
            end
      end
foo (generic function with 1 method)

julia> @elapsed foo(100000000)
1.113577001

julia> @time foo(100000000)
1.134852 seconds