Dates
Dates
模块提供了两种用于处理日期的类型:Date
和 DateTime
,分别表示天和毫秒精度;这两者都是抽象类型 TimeType
的子类型。使用不同类型的动机很简单:某些操作在代码和思维推理方面要简单得多,当不必处理更高精度的复杂性时。例如,由于 4d61726b646f776e2e436f64652822222c2022446174652229_40726566
类型仅解析为单个日期的精度(即没有小时、分钟或秒),因此时间区、夏令时和闰秒的正常考虑是多余的,可以避免。
Date
和 DateTime
基本上是不可变的 Int64
包装器。任一类型的单个 instant
字段实际上是 UTInstant{P}
类型,表示基于 UT 秒的持续增加的机器时间线 [1]。4d61726b646f776e2e436f64652822222c20224461746554696d652229_40726566
类型并不考虑时区(在 Python 术语中称为 naive),类似于 Java 8 中的 LocalDateTime。可以通过 TimeZones.jl package 添加额外的时区功能,该功能编译 IANA time zone database。4d61726b646f776e2e436f64652822222c2022446174652229_40726566
和 4d61726b646f776e2e436f64652822222c20224461746554696d652229_40726566
都基于 ISO 8601 标准,该标准遵循前瞻性公历。需要注意的是,ISO 8601 标准对公元前/公元前日期有特别规定。一般来说,公元前/公元前时代的最后一天,公元前 1 年 12 月 31 日,之后是公元 1 年 1 月 1 日,因此不存在零年。然而,ISO 标准规定公元前 1 年是零年,因此 0000-12-31
是 0001-01-01
之前的一天,而年份 -0001
(是的,负一的年份)是公元前 2 年,年份 -0002
是公元前 3 年,依此类推。
Constructors
Date
和 DateTime
类型可以通过整数或 Period
类型构建,通过解析或通过调整器(稍后会详细介绍):
julia> DateTime(2013)
2013-01-01T00:00:00
julia> DateTime(2013,7)
2013-07-01T00:00:00
julia> DateTime(2013,7,1)
2013-07-01T00:00:00
julia> DateTime(2013,7,1,12)
2013-07-01T12:00:00
julia> DateTime(2013,7,1,12,30)
2013-07-01T12:30:00
julia> DateTime(2013,7,1,12,30,59)
2013-07-01T12:30:59
julia> DateTime(2013,7,1,12,30,59,1)
2013-07-01T12:30:59.001
julia> Date(2013)
2013-01-01
julia> Date(2013,7)
2013-07-01
julia> Date(2013,7,1)
2013-07-01
julia> Date(Dates.Year(2013),Dates.Month(7),Dates.Day(1))
2013-07-01
julia> Date(Dates.Month(7),Dates.Year(2013))
2013-07-01
Date
或 DateTime
的解析是通过使用格式字符串来完成的。格式字符串的工作原理是定义 分隔 或 固定宽度 的“插槽”,这些插槽包含一个句点以进行解析,并将要解析的文本和格式字符串传递给 4d61726b646f776e2e436f64652822222c2022446174652229_40726566
或 4d61726b646f776e2e436f64652822222c20224461746554696d652229_40726566
构造函数,形式为 Date("2015-01-01",dateformat"y-m-d")
或 DateTime("20150101",dateformat"yyyymmdd")
。
分隔槽通过指定解析器在两个后续时间段之间应该期待的分隔符来标记;因此,"y-m-d"
让解析器知道在像 "2014-07-16"
这样的日期字符串中的第一个和第二个槽之间,它应该找到 -
字符。y
、m
和 d
字符让解析器知道在每个槽中应该解析哪些时间段。
如上面构造函数 Date(2013)
的情况,带分隔符的 DateFormat
允许日期和时间的某些部分缺失,只要前面的部分给出。其他部分将使用通常的默认值。例如,Date("1981-03", dateformat"y-m-d")
返回 1981-03-01
,而 Date("31/12", dateformat"d/m/y")
返回 0001-12-31
。(请注意,默认年份是公元1年/公历1年。)然而,空字符串始终会抛出 ArgumentError
。
固定宽度的插槽通过重复句点字符来指定,重复的次数与宽度相对应,字符之间没有分隔符。因此,dateformat"yyyymmdd"
将对应于像 "20140716"
这样的日期字符串。解析器通过缺少分隔符来区分固定宽度的插槽,注意到从一个句点字符到下一个句点字符的过渡 "yyyymm"
。
对文本形式的月份解析也通过 u
和 U
字符支持,分别用于缩写和全名的月份名称。默认情况下,仅支持英语月份名称,因此 u
对应于 "Jan"、"Feb"、"Mar" 等。而 U
对应于 "January"、"February"、"March" 等。与其他名称=>值映射函数类似,dayname
和 monthname
,可以通过将 locale=>Dict{String,Int}
映射传递给 MONTHTOVALUEABBR
和 MONTHTOVALUE
字典来加载自定义区域设置,分别用于缩写和全名的月份名称。
上述示例使用了 dateformat""
字符串宏。该宏在宏展开时创建一个 DateFormat
对象,并在多次运行代码片段时使用相同的 DateFormat
对象。
julia> for i = 1:10^5
Date("2015-01-01", dateformat"y-m-d")
end
或者您可以显式创建 DateFormat 对象:
julia> df = DateFormat("y-m-d");
julia> dt = Date("2015-01-01",df)
2015-01-01
julia> dt2 = Date("2015-01-02",df)
2015-01-02
或者,使用广播:
julia> years = ["2015", "2016"];
julia> Date.(years, DateFormat("yyyy"))
2-element Vector{Date}:
2015-01-01
2016-01-01
为了方便,您可以直接传递格式字符串(例如,Date("2015-01-01","y-m-d")
),尽管这种形式在重复解析相同格式时会产生性能开销,因为它每次都会内部创建一个新的 DateFormat
对象。
除了通过构造函数,Date
或 DateTime
还可以通过字符串构造,使用 parse
和 tryparse
函数,但可以选择性地传入一个类型为 DateFormat
的第三个参数来指定格式;例如,parse(Date, "06.23.2013", dateformat"m.d.y")
,或 tryparse(DateTime, "1999-12-31T23:59:59")
,后者使用默认格式。这两个函数之间的显著区别在于,使用 4d61726b646f776e2e436f64652822222c202274727970617273652229_40726566
时,如果字符串为空或格式无效,则不会抛出错误;相反,返回 nothing
。
在 Julia 1.9 之前,空字符串可以传递给构造函数和 parse
而不会出错,返回相应的 DateTime(1)
、Date(1)
或 Time(0)
。同样,tryparse
不会返回 nothing
。
一整套解析和格式化测试及示例可在 stdlib/Dates/test/io.jl
中找到。
Durations/Comparisons
Finding the length of time between two Date
or DateTime
is straightforward given their underlying representation as UTInstant{Day}
and UTInstant{Millisecond}
, respectively. The difference between Date
is returned in the number of Day
, and DateTime
in the number of Millisecond
. Similarly, comparing TimeType
is a simple matter of comparing the underlying machine instants (which in turn compares the internal Int64
values).
julia> dt = Date(2012,2,29)
2012-02-29
julia> dt2 = Date(2000,2,1)
2000-02-01
julia> dump(dt)
Date
instant: Dates.UTInstant{Day}
periods: Day
value: Int64 734562
julia> dump(dt2)
Date
instant: Dates.UTInstant{Day}
periods: Day
value: Int64 730151
julia> dt > dt2
true
julia> dt != dt2
true
julia> dt + dt2
ERROR: MethodError: no method matching +(::Date, ::Date)
[...]
julia> dt * dt2
ERROR: MethodError: no method matching *(::Date, ::Date)
[...]
julia> dt / dt2
ERROR: MethodError: no method matching /(::Date, ::Date)
julia> dt - dt2
4411 days
julia> dt2 - dt
-4411 days
julia> dt = DateTime(2012,2,29)
2012-02-29T00:00:00
julia> dt2 = DateTime(2000,2,1)
2000-02-01T00:00:00
julia> dt - dt2
381110400000 milliseconds
Accessor Functions
因为 Date
和 DateTime
类型被存储为单个 Int64
值,因此可以通过访问器函数检索日期部分或字段。小写访问器将字段作为整数返回:
julia> t = Date(2014, 1, 31)
2014-01-31
julia> Dates.year(t)
2014
julia> Dates.month(t)
1
julia> Dates.week(t)
5
julia> Dates.day(t)
31
While propercase return the same value in the corresponding Period
type:
julia> Dates.Year(t)
2014 years
julia> Dates.Day(t)
31 days
复合方法的提供是因为同时访问多个字段比单独访问更高效:
julia> Dates.yearmonth(t)
(2014, 1)
julia> Dates.monthday(t)
(1, 31)
julia> Dates.yearmonthday(t)
(2014, 1, 31)
您还可以访问底层的 UTInstant
或整数值:
julia> dump(t)
Date
instant: Dates.UTInstant{Day}
periods: Day
value: Int64 735264
julia> t.instant
Dates.UTInstant{Day}(Day(735264))
julia> Dates.value(t)
735264
Query Functions
查询函数提供有关 TimeType
的日历信息。它们包括有关星期几的信息:
julia> t = Date(2014, 1, 31)
2014-01-31
julia> Dates.dayofweek(t)
5
julia> Dates.dayname(t)
"Friday"
julia> Dates.dayofweekofmonth(t) # 5th Friday of January
5
一年中的月份:
julia> Dates.monthname(t)
"January"
julia> Dates.daysinmonth(t)
31
关于 TimeType
的年份和季度的信息:
julia> Dates.isleapyear(t)
false
julia> Dates.dayofyear(t)
31
julia> Dates.quarterofyear(t)
1
julia> Dates.dayofquarter(t)
31
dayname
和 monthname
方法还可以接受一个可选的 locale
关键字,用于返回其他语言/地区的星期几或月份名称。这些函数还有返回缩写名称的版本,即 dayabbr
和 monthabbr
。首先,映射被加载到 LOCALES
变量中:
julia> french_months = ["janvier", "février", "mars", "avril", "mai", "juin",
"juillet", "août", "septembre", "octobre", "novembre", "décembre"];
julia> french_months_abbrev = ["janv","févr","mars","avril","mai","juin",
"juil","août","sept","oct","nov","déc"];
julia> french_days = ["lundi","mardi","mercredi","jeudi","vendredi","samedi","dimanche"];
julia> Dates.LOCALES["french"] = Dates.DateLocale(french_months, french_months_abbrev, french_days, [""]);
上述提到的函数可以用来执行查询:
julia> Dates.dayname(t;locale="french")
"vendredi"
julia> Dates.monthname(t;locale="french")
"janvier"
julia> Dates.monthabbr(t;locale="french")
"janv"
由于未加载日期的缩写版本,尝试使用函数 dayabbr
将会抛出错误。
julia> Dates.dayabbr(t;locale="french")
ERROR: BoundsError: attempt to access 1-element Vector{String} at index [5]
Stacktrace:
[...]
TimeType-Period Arithmetic
在使用任何语言/日期框架时,熟悉日期周期算术的处理方式是一个好习惯,因为有一些 tricky issues 需要处理(尽管对于日精度类型来说要少得多)。
Dates
模块的方法试图遵循一个简单的原则,即在进行 Period
算术运算时尽量减少更改。这种方法通常也被称为 历法 算术,或者如果有人在对话中问你同样的计算,你可能会猜到的内容。为什么对此如此关注?让我们来看一个经典的例子:在2014年1月31日加1个月,答案是什么?Javascript 会说 March 3(假设31天)。PHP 说 March 2(假设30天)。事实上,没有正确的答案。在 Dates
模块中,它给出的结果是2月28日。它是如何得出这个结果的?考虑一下赌场中的经典7-7-7赌博游戏。
现在想象一下,老虎机的格式不是7-7-7,而是年-月-日,或者在我们的例子中是2014-01-31。当你要求将这个日期加1个月时,月份的槽位会增加,所以现在我们有2014-02-31。然后检查日期数字是否大于新月份的最后有效日期;如果是(如上例所示),日期数字会调整到最后有效日期(28)。这种方法有什么影响呢?继续将我们的日期加一个月,2014-02-28 + Month(1) == 2014-03-28
。什么?你期待三月的最后一天吗?不,抱歉,记住7-7-7的槽位。尽可能少的槽位会改变,所以我们首先将月份槽位加1,变成2014-03-28,完成,因为这是一个有效的日期。另一方面,如果我们将原始日期2014-01-31加2个月,那么我们最终得到2014-03-31,正如预期的那样。这种方法的另一个影响是,当强制特定顺序时,关联性会丧失(即以不同顺序添加的结果不同)。例如:
julia> (Date(2014,1,29)+Dates.Day(1)) + Dates.Month(1)
2014-02-28
julia> (Date(2014,1,29)+Dates.Month(1)) + Dates.Day(1)
2014-03-01
发生了什么?在第一行中,我们将1天添加到1月29日,这样得到2014-01-30;然后我们添加1个月,所以得到2014-02-30,随后调整为2014-02-28。在第二个例子中,我们首先添加1个月,得到2014-02-29,随后调整为2014-02-28,然后再添加1天,结果是2014-03-01。一个在这种情况下有帮助的设计原则是,在存在多个周期的情况下,操作将按周期的类型排序,而不是它们的值或位置顺序;这意味着Year
将始终首先添加,然后是Month
,然后是Week
,等等。因此,以下确实结果是结合性并且正常工作:
julia> Date(2014,1,29) + Dates.Day(1) + Dates.Month(1)
2014-03-01
julia> Date(2014,1,29) + Dates.Month(1) + Dates.Day(1)
2014-03-01
棘手吗?也许吧。一个无辜的 Dates
用户该怎么办?底线是要意识到,在处理月份时,明确强制某种结合性可能会导致一些意想不到的结果,但除此之外,一切应该按预期工作。值得庆幸的是,这几乎就是在处理 UT 时间的日期周期算术时奇怪情况的全部(避免处理夏令时、闰秒等的“乐趣”)。
作为额外奖励,所有周期算术对象都可以直接与范围一起使用:
julia> dr = Date(2014,1,29):Day(1):Date(2014,2,3)
Date("2014-01-29"):Day(1):Date("2014-02-03")
julia> collect(dr)
6-element Vector{Date}:
2014-01-29
2014-01-30
2014-01-31
2014-02-01
2014-02-02
2014-02-03
julia> dr = Date(2014,1,29):Dates.Month(1):Date(2014,07,29)
Date("2014-01-29"):Month(1):Date("2014-07-29")
julia> collect(dr)
7-element Vector{Date}:
2014-01-29
2014-02-28
2014-03-29
2014-04-29
2014-05-29
2014-06-29
2014-07-29
Adjuster Functions
尽管日期周期算术非常方便,但通常对日期的计算需要采用日历或时间的性质,而不是固定的周期数。假期就是一个完美的例子;大多数假期遵循诸如“阵亡将士纪念日 = 五月的最后一个星期一”或“感恩节 = 十一月的第四个星期四”等规则。这些时间表达式处理与日历相关的规则,例如每月的第一天或最后一天,下一个星期二,或第一和第三个星期三等。
Dates
模块通过几个方便的方法提供了 调整器 API,这些方法有助于简单明了地表达时间规则。第一组调整器方法处理周、月、季度和年的首尾。它们每个都接受一个单一的 TimeType
作为输入,并返回或 调整到 相对于输入的所需周期的首尾。
julia> Dates.firstdayofweek(Date(2014,7,16)) # Adjusts the input to the Monday of the input's week
2014-07-14
julia> Dates.lastdayofmonth(Date(2014,7,16)) # Adjusts to the last day of the input's month
2014-07-31
julia> Dates.lastdayofquarter(Date(2014,7,16)) # Adjusts to the last day of the input's quarter
2014-09-30
下两个高阶方法,tonext
和 toprev
,通过将 DateFunction
作为第一个参数,以及一个起始的 TimeType
,来推广处理时间表达式。DateFunction
只是一个函数,通常是匿名的,它接受一个单一的 4d61726b646f776e2e436f64652822222c202254696d65547970652229_40726566
作为输入,并返回一个 Bool
,true
表示满足调整标准。例如:
julia> istuesday = x->Dates.dayofweek(x) == Dates.Tuesday; # Returns true if the day of the week of x is Tuesday
julia> Dates.tonext(istuesday, Date(2014,7,13)) # 2014-07-13 is a Sunday
2014-07-15
julia> Dates.tonext(Date(2014,7,13), Dates.Tuesday) # Convenience method provided for day of the week adjustments
2014-07-15
这在使用 do-block 语法处理更复杂的时间表达式时非常有用:
julia> Dates.tonext(Date(2014,7,13)) do x
# Return true on the 4th Thursday of November (Thanksgiving)
Dates.dayofweek(x) == Dates.Thursday &&
Dates.dayofweekofmonth(x) == 4 &&
Dates.month(x) == Dates.November
end
2014-11-27
Base.filter
方法可以用来获取指定范围内的所有有效日期/时刻:
# Pittsburgh street cleaning; Every 2nd Tuesday from April to November
# Date range from January 1st, 2014 to January 1st, 2015
julia> dr = Dates.Date(2014):Day(1):Dates.Date(2015);
julia> filter(dr) do x
Dates.dayofweek(x) == Dates.Tue &&
Dates.April <= Dates.month(x) <= Dates.Nov &&
Dates.dayofweekofmonth(x) == 2
end
8-element Vector{Date}:
2014-04-08
2014-05-13
2014-06-10
2014-07-08
2014-08-12
2014-09-09
2014-10-14
2014-11-11
附加示例和测试可在 stdlib/Dates/test/adjusters.jl
中获取。
Period Types
周期是人类对离散的、有时不规则的时间段的看法。考虑1个月;根据年份和月份的上下文,它可以在天数上表示为28、29、30或31。或者在闰年的情况下,一年可以表示为365或366天。 Period
类型是简单的 Int64
包装器,通过包装任何可转换为 Int64
的类型构造,例如 Year(1)
或 Month(3.0)
。同类型的 4d61726b646f776e2e436f64652822222c2022506572696f642229_40726566
之间的算术运算表现得像整数,并且有限的 Period-Real
算术运算是可用的。您可以使用 Dates.value
提取底层整数。
julia> y1 = Dates.Year(1)
1 year
julia> y2 = Dates.Year(2)
2 years
julia> y3 = Dates.Year(10)
10 years
julia> y1 + y2
3 years
julia> div(y3,y2)
5
julia> y3 - y2
8 years
julia> y3 % y2
0 years
julia> div(y3,3) # mirrors integer division
3 years
julia> Dates.value(Dates.Millisecond(10))
10
表示非整数倍基本类型的周期或持续时间可以通过 Dates.CompoundPeriod
类型来实现。复合周期可以通过简单的 Period
类型手动构建。此外,canonicalize
函数可以用来将一个周期分解为 4d61726b646f776e2e436f64652822222c202244617465732e436f6d706f756e64506572696f642229_40726566
。这在将持续时间(例如,两个 DateTime
的差异)转换为更方便的表示时特别有用。
julia> cp = Dates.CompoundPeriod(Day(1),Minute(1))
1 day, 1 minute
julia> t1 = DateTime(2018,8,8,16,58,00)
2018-08-08T16:58:00
julia> t2 = DateTime(2021,6,23,10,00,00)
2021-06-23T10:00:00
julia> canonicalize(t2-t1) # creates a CompoundPeriod
149 weeks, 6 days, 17 hours, 2 minutes
Rounding
Date
和 DateTime
的值可以根据指定的分辨率(例如,1 个月或 15 分钟)进行四舍五入,使用 floor
、ceil
或 round
:
julia> floor(Date(1985, 8, 16), Dates.Month)
1985-08-01
julia> ceil(DateTime(2013, 2, 13, 0, 31, 20), Dates.Minute(15))
2013-02-13T00:45:00
julia> round(DateTime(2016, 8, 6, 20, 15), Dates.Day)
2016-08-07T00:00:00
与默认情况下向偶数倾斜的数字 round
方法不同,TimeType
4d61726b646f776e2e436f64652822222c2022726f756e642229_40726566
方法使用 RoundNearestTiesUp
舍入模式。(很难猜测向最近的“偶数” 4d61726b646f776e2e436f64652822222c202254696d65547970652229_40726566
的舍入会涉及什么。)有关可用 RoundingMode
的更多详细信息,请参见 API reference。
四舍五入通常应该按预期进行,但有一些情况下,预期的行为并不明显。
Rounding Epoch
在许多情况下,指定的舍入分辨率(例如,Dates.Second(30)
)可以均匀地划分到下一个较大的时间段(在这种情况下是Dates.Minute(1)
)。但是,在这种不成立的情况下,舍入行为可能会导致混淆。将DateTime
舍入到最接近的10小时的预期结果是什么?
julia> round(DateTime(2016, 7, 17, 11, 55), Dates.Hour(10))
2016-07-17T12:00:00
这可能看起来令人困惑,因为小时(12)不能被10整除。选择2016-07-17T12:00:00
的原因是它是0000-01-01T00:00:00
之后的17,676,660小时,而17,676,660可以被10整除。
作为 Julia Date
和 DateTime
的值是根据 ISO 8601 标准表示的,选择了 0000-01-01T00:00:00
作为基础(或“舍入纪元”),从这个时间点开始计算用于舍入计算的天数(和毫秒)。 (请注意,这与 Julia 内部表示的 4d61726b646f776e2e436f64652822222c2022446174652229_40726566
使用的 Rata Die notation 略有不同;但由于 ISO 8601 标准对最终用户最为明显,因此选择了 0000-01-01T00:00:00
作为舍入纪元,而不是内部使用的 0000-12-31T00:00:00
以减少混淆。)
唯一例外是,当四舍五入到周时,使用 0000-01-01T00:00:00
作为四舍五入的基准。四舍五入到最近的周将始终返回一个星期一(根据 ISO 8601 规定的周的第一天)。因此,我们在四舍五入到若干周时,使用 0000-01-03T00:00:00
(根据 ISO 8601 定义的公元 0000 年第一周的第一天)作为基准。
这里有一个相关的案例,其中预期的行为并不一定明显:当我们四舍五入到最近的 P(2)
时会发生什么,其中 P
是一个 Period
类型?在某些情况下(具体来说,当 P <: Dates.TimePeriod
时),答案是明确的:
julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Hour(2))
2016-07-17T08:00:00
julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Minute(2))
2016-07-17T08:56:00
这似乎显而易见,因为每个周期的两个仍然可以均匀地划分到下一个更大的周期中。但是在两个月的情况下(它仍然可以均匀地划分到一年中),答案可能会令人惊讶:
julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Month(2))
2016-07-01T00:00:00
为什么要四舍五入到七月的第一天,即使它是第7个月(一个奇数)?关键在于月份是从1开始计数的(第一个月被分配为1),与小时、分钟、秒和毫秒不同(它们的第一个值被分配为0)。
这意味着将 DateTime
四舍五入到秒、分钟、小时或年(因为 ISO 8601 规范包括零年)的偶数倍将导致该字段中的值为偶数的 4d61726b646f776e2e436f64652822222c20224461746554696d652229_40726566
,而将 4d61726b646f776e2e436f64652822222c20224461746554696d652229_40726566
四舍五入到月份的偶数倍将导致月份字段具有奇数值。由于月份和年份可能包含不规则的天数,因此四舍五入到偶数天是否会导致天数字段中的值为偶数是不确定的。
请参阅 API reference 以获取有关从 Dates
模块导出的方法的更多信息。
API reference
Dates and Time Types
Dates.Period
— Type周期
年
季度
月
周
天
小时
分钟
秒
毫秒
微秒
纳秒
周期
类型表示离散的、以人为单位的时间表示。
Dates.CompoundPeriod
— TypeCompoundPeriod
CompoundPeriod
对于表示不是固定倍数的小时间段非常有用。例如,“一年和一天”不是固定的天数,但可以使用 CompoundPeriod
表示。实际上,通过不同时间段类型的相加会自动生成 CompoundPeriod
,例如 Year(1) + Day(1)
产生一个 CompoundPeriod
结果。
Dates.Instant
— Type瞬时
Instant
类型表示基于整数的机器时间表示,作为从纪元开始的连续时间线。
Dates.UTInstant
— TypeUTInstant{T}
UTInstant
表示基于 UT 时间的机器时间线(1 天 = 地球的一次自转)。T
是一个 Period
参数,表示瞬时的分辨率或精度。
Dates.TimeType
— TypeTimeType
TimeType
类型封装了 Instant
机器实例,以提供机器瞬间的人类表示。Time
、DateTime
和 Date
是 TimeType
的子类型。
Dates.DateTime
— TypeDateTime
DateTime
表示根据前瞻性格里高利历法的某个时间点。时间的最精细分辨率为毫秒(即,微秒或纳秒无法由此类型表示)。该类型支持定点算术,因此容易发生下溢(和上溢)。一个显著的后果是在添加 Microsecond
或 Nanosecond
时的舍入:
julia> dt = DateTime(2023, 8, 19, 17, 45, 32, 900)
2023-08-19T17:45:32.900
julia> dt + Millisecond(1)
2023-08-19T17:45:32.901
julia> dt + Microsecond(1000) # 1000us == 1ms
2023-08-19T17:45:32.901
julia> dt + Microsecond(999) # 999us 舍入到 1000us
2023-08-19T17:45:32.901
julia> dt + Microsecond(1499) # 1499 舍入到 1000us
2023-08-19T17:45:32.901
Dates.Date
— Type日期
Date
包装了一个 UTInstant{Day}
并根据前瞻公历进行解释。
Dates.Time
— Type时间
Time
包装了一个 Nanosecond
,表示一天24小时中的特定时刻。
Dates.TimeZone
— TypeTimeZone
地理区域通常基于经度来确定某个位置的时间。一些时区会观察夏令时(例如 EST -> EDT)。有关实现和更多支持,请参见 TimeZones.jl
包。
Dates.UTC
— Type协调世界时
UTC
,或协调世界时,是所有其他时区测量的TimeZone
。它与0°经度的时间相关联。它不进行夏令时调整。
Dates Functions
Dates.DateTime
— MethodDateTime(y, [m, d, h, mi, s, ms]) -> DateTime
通过各部分构造一个 DateTime
类型。参数必须可以转换为 Int64
。
Dates.DateTime
— MethodDateTime(periods::Period...) -> DateTime
通过 Period
类型的部分构造 DateTime
类型。参数可以按任何顺序提供。未提供的 DateTime 部分将默认为 Dates.default(period)
的值。
Dates.DateTime
— MethodDateTime(f::Function, y[, m, d, h, mi, s]; step=Day(1), limit=10000) -> DateTime
通过调整器 API 创建一个 DateTime
。起始点将根据提供的 y, m, d...
参数构建,并将进行调整,直到 f::Function
返回 true
。调整的步长可以通过 step
关键字手动提供。limit
提供了调整 API 在抛出错误之前所追求的最大迭代次数限制(如果 f::Function
永远不满足)。
示例
julia> DateTime(dt -> second(dt) == 40, 2010, 10, 20, 10; step = Second(1))
2010-10-20T10:00:40
julia> DateTime(dt -> hour(dt) == 20, 2010, 10, 20, 10; step = Hour(1), limit = 5)
ERROR: ArgumentError: 调整限制已达到:5 次迭代
Stacktrace:
[...]
Dates.DateTime
— MethodDateTime(dt::Date) -> DateTime
将 Date
转换为 DateTime
。新 DateTime
的小时、分钟、秒和毫秒部分假定为零。
Dates.DateTime
— MethodDateTime(dt::AbstractString, format::AbstractString; locale="english") -> DateTime
通过解析遵循 format
字符串中给定模式的 dt
日期时间字符串来构造 DateTime
(有关语法,请参见 DateFormat
)。
此方法每次调用时都会创建一个 DateFormat
对象。建议您先创建一个 DateFormat
对象,并将其作为第二个参数使用,以避免在重复使用相同格式时造成性能损失。
示例
julia> DateTime("2020-01-01", "yyyy-mm-dd")
2020-01-01T00:00:00
julia> a = ("2020-01-01", "2020-01-02");
julia> [DateTime(d, dateformat"yyyy-mm-dd") for d ∈ a] # preferred
2-element Vector{DateTime}:
2020-01-01T00:00:00
2020-01-02T00:00:00
Dates.format
— Methodformat(dt::TimeType, format::AbstractString; locale="english") -> AbstractString
通过使用 TimeType
对象并应用提供的 format
来构造一个字符串。可以使用以下字符代码来构造 format
字符串:
代码 | 示例 | 注释 |
---|---|---|
y | 6 | 固定宽度的数字年份 |
Y | 1996 | 最小宽度的数字年份 |
m | 1, 12 | 最小宽度的数字月份 |
u | Jan | 根据 locale 缩写为3个字符的月份名称 |
U | January | 根据 locale 关键字的完整月份名称 |
d | 1, 31 | 最小宽度的月份中的天数 |
H | 0, 23 | 最小宽度的小时(24小时制) |
M | 0, 59 | 最小宽度的分钟 |
S | 0, 59 | 最小宽度的秒 |
s | 000, 500 | 最小宽度为3的毫秒 |
e | Mon, Tue | 缩写的星期几 |
E | Monday | 完整的星期几名称 |
连续代码字符的数量表示代码的宽度。格式 yyyy-mm
指定代码 y
应具有四个宽度,而 m
应具有两个宽度。产生数字的代码有一个相关的模式:固定宽度或最小宽度。固定宽度模式在值短于指定宽度时用零左填充,并在值过长时截断值。最小宽度模式的工作方式与固定宽度相同,只是它不截断超过宽度的值。
在创建 format
时,可以使用任何非代码字符作为分隔符。例如,要生成字符串 "1996-01-15T00:00:00",可以使用 format
: "yyyy-mm-ddTHH:MM:SS"。请注意,如果需要将代码字符用作字面量,可以使用转义字符反斜杠。字符串 "1996y01m" 可以通过格式 "yyyy\ymm\m" 生成。
Dates.DateFormat
— TypeDateFormat(format::AbstractString, locale="english") -> DateFormat
构造一个日期格式化对象,可以用于解析日期字符串或将日期对象格式化为字符串。以下字符代码可用于构造 format
字符串:
代码 | 匹配 | 注释 |
---|---|---|
Y | 1996, 96 | 返回1996年的年份,0096 |
y | 1996, 96 | 在 parse 上与 Y 相同,但在 format 时丢弃多余的数字 |
m | 1, 01 | 匹配1或2位数的月份 |
u | Jan | 根据 locale 关键字匹配缩写的月份 |
U | January | 根据 locale 关键字匹配完整的月份名称 |
d | 1, 01 | 匹配1或2位数的日期 |
H | 00 | 匹配小时(24小时制) |
I | 00 | 用于输出12小时制的小时 |
M | 00 | 匹配分钟 |
S | 00 | 匹配秒 |
s | .500 | 匹配毫秒 |
e | Mon, Tues | 匹配缩写的星期几 |
E | Monday | 匹配完整的星期几名称 |
p | AM | 匹配AM/PM(不区分大小写) |
yyyymmdd | 19960101 | 匹配固定宽度的年、月和日 |
未列出的字符通常被视为日期和时间段之间的分隔符。例如,dt
字符串 "1996-01-15T00:00:00.0" 将具有类似 "y-m-dTH:M:S.s" 的 format
字符串。如果需要将代码字符用作分隔符,可以使用反斜杠进行转义。日期 "1995y01m" 将具有格式 "y\ym\m"。
请注意,12:00AM 对应 00:00(午夜),而 12:00PM 对应 12:00(中午)。在解析带有 p
指定符的时间时,任何小时(无论是 H
还是 I
)都被解释为12小时制,因此 I
代码主要用于输出。
创建 DateFormat 对象是昂贵的。尽可能地,创建一次并多次使用,或者尝试 dateformat""
字符串宏。使用此宏在宏扩展时创建 DateFormat 对象,并在后续重用。还有几个 预定义格式化器,稍后列出。
Dates.@dateformat_str
— Macrodateformat"Y-m-d H:M:S"
创建一个 DateFormat
对象。类似于 DateFormat("Y-m-d H:M:S")
,但在宏扩展期间只创建一次 DateFormat 对象。
有关格式说明符的详细信息,请参见 DateFormat
。
Dates.DateTime
— MethodDateTime(dt::AbstractString, df::DateFormat=ISODateTimeFormat) -> DateTime
通过解析 dt
日期时间字符串来构造 DateTime
,遵循 DateFormat
对象中给定的模式,或者如果省略则使用 dateformat"yyyy-mm-dd\THH:MM:SS.s"。
类似于 DateTime(::AbstractString, ::AbstractString)
,但在重复解析格式相似的日期时间字符串时,使用预先创建的 DateFormat
对象更高效。
Dates.Date
— MethodDate(y, [m, d]) -> Date
通过部分构造一个 Date
类型。参数必须可以转换为 Int64
。
Dates.Date
— MethodDate(period::Period...) -> Date
通过 Period
类型的部分构造 Date
类型。参数可以按任意顺序提供。未提供的 Date
部分将默认为 Dates.default(period)
的值。
Dates.Date
— MethodDate(f::Function, y[, m, d]; step=Day(1), limit=10000) -> Date
通过调整器 API 创建一个 Date
。起始点将根据提供的 y, m, d
参数构建,并将进行调整,直到 f::Function
返回 true
。调整的步长可以通过 step
关键字手动提供。limit
提供了调整 API 在抛出错误之前将追求的最大迭代次数限制(假设 f::Function
永远不会满足)。
示例
julia> Date(date -> week(date) == 20, 2010, 01, 01)
2010-05-17
julia> Date(date -> year(date) == 2010, 2000, 01, 01)
2010-01-01
julia> Date(date -> month(date) == 10, 2000, 01, 01; limit = 5)
ERROR: ArgumentError: Adjustment limit reached: 5 iterations
Stacktrace:
[...]
Dates.Date
— MethodDate(dt::DateTime) -> Date
将 DateTime
转换为 Date
。DateTime
的小时、分钟、秒和毫秒部分被截断,因此在构造时仅使用年份、月份和日期部分。
Dates.Date
— MethodDate(d::AbstractString, format::AbstractString; locale="english") -> Date
通过解析 d
日期字符串并遵循 format
字符串中给定的模式来构造 Date
(有关语法,请参见 DateFormat
)。
此方法每次调用时都会创建一个 DateFormat
对象。建议您先创建一个 DateFormat
对象,并将其作为第二个参数使用,以避免在重复使用相同格式时造成性能损失。
示例
julia> Date("2020-01-01", "yyyy-mm-dd")
2020-01-01
julia> a = ("2020-01-01", "2020-01-02");
julia> [Date(d, dateformat"yyyy-mm-dd") for d ∈ a] # preferred
2-element Vector{Date}:
2020-01-01
2020-01-02
Dates.Date
— MethodDate(d::AbstractString, df::DateFormat=ISODateFormat) -> Date
通过解析遵循DateFormat
对象中给定模式的d
日期字符串来构造一个Date
,如果省略,则使用dateformat"yyyy-mm-dd"。
类似于Date(::AbstractString, ::AbstractString)
,但在重复解析格式相似的日期字符串时,使用预先创建的DateFormat
对象更高效。
Dates.Time
— Method时间(h, [mi, s, ms, us, ns]) -> 时间
通过部分构造一个 时间
类型。参数必须可转换为 Int64
。
Dates.Time
— MethodTime(period::TimePeriod...) -> Time
通过 Period
类型的部分构造 Time
类型。参数可以按任何顺序提供。未提供的 Time
部分将默认为 Dates.default(period)
的值。
Dates.Time
— Method通过调整器 API 创建一个 `Time`。起始点将根据提供的 `h, mi, s, ms, us` 参数构建,并将进行调整,直到 `f::Function` 返回 `true`。调整的步长可以通过 `step` 关键字手动提供。`limit` 提供了调整 API 在抛出错误之前所追求的最大迭代次数(如果 `f::Function` 从未满足)。请注意,默认步长将调整以允许给定参数的更高精度;即如果提供了小时、分钟和秒参数,默认步长将是 `Millisecond(1)` 而不是 `Second(1)`。
# 示例
jldoctest julia> Time(t -> minute(t) == 30, 20) 20:30:00
julia> Time(t -> minute(t) == 0, 20) 20:00:00
julia> Time(t -> hour(t) == 10, 3; limit = 5) ERROR: ArgumentError: 调整限制已达到:5 次迭代 Stacktrace: [...] ```
Dates.Time
— MethodTime(dt::DateTime) -> Time
将 DateTime
转换为 Time
。DateTime
的小时、分钟、秒和毫秒部分用于创建新的 Time
。微秒和纳秒默认值为零。
Dates.Time
— MethodTime(t::AbstractString, format::AbstractString; locale="english") -> Time
通过解析 t
时间字符串并遵循 format
字符串中给定的模式来构造 Time
(有关语法,请参见 DateFormat
)。
此方法每次调用时都会创建一个 DateFormat
对象。建议您先创建一个 DateFormat
对象,并将其作为第二个参数使用,以避免在重复使用相同格式时造成性能损失。
示例
julia> Time("12:34pm", "HH:MMp")
12:34:00
julia> a = ("12:34pm", "2:34am");
julia> [Time(d, dateformat"HH:MMp") for d ∈ a] # preferred
2-element Vector{Time}:
12:34:00
02:34:00
Dates.Time
— MethodTime(t::AbstractString, df::DateFormat=ISOTimeFormat) -> Time
通过解析t
日期时间字符串来构造一个Time
,遵循DateFormat
对象中给定的模式,或者如果省略则使用dateformat"HH:MM:SS.s"。
类似于Time(::AbstractString, ::AbstractString)
,但在重复解析格式相似的时间字符串时,使用预先创建的DateFormat
对象更高效。
Dates.now
— Methodnow() -> DateTime
返回一个 DateTime
,对应用户的系统时间,包括系统时区区域。
Dates.now
— Methodnow(::Type{UTC}) -> DateTime
返回一个与用户系统时间相对应的 DateTime
,以 UTC/GMT 表示。有关其他时区的信息,请参见 TimeZones.jl 包。
示例
julia> now(UTC)
2023-01-04T10:52:24.864
Base.eps
— Methodeps(::Type{DateTime}) -> 毫秒
eps(::Type{Date}) -> 天
eps(::Type{Time}) -> 纳秒
eps(::TimeType) -> 周期
返回 TimeType
支持的最小单位值。
示例
julia> eps(DateTime)
1 毫秒
julia> eps(Date)
1 天
julia> eps(Time)
1 纳秒
Accessor Functions
Dates.year
— Functionyear(dt::TimeType) -> Int64
Date
或 DateTime
的年份,作为一个 Int64
。
Dates.month
— Functionmonth(dt::TimeType) -> Int64
Date
或 DateTime
的月份,作为一个 Int64
。
Dates.week
— Functionweek(dt::TimeType) -> Int64
返回 Date
或 DateTime
的 ISO 周日期 作为 Int64
。请注意,一年的第一周是包含该年第一周四的那一周,这可能导致在1月4日之前的日期属于前一年的最后一周。例如,week(Date(2005, 1, 1))
是2004年的第53周。
示例
julia> week(Date(1989, 6, 22))
25
julia> week(Date(2005, 1, 1))
53
julia> week(Date(2004, 12, 31))
53
Dates.day
— Functionday(dt::TimeType) -> Int64
一个 Date
或 DateTime
的月份中的天数,作为一个 Int64
。
Dates.hour
— Functionhour(dt::DateTime) -> Int64
DateTime
的小时以 Int64
的形式表示。
hour(t::Time) -> Int64
Time
的小时作为一个 Int64
。
Dates.minute
— Functionminute(dt::DateTime) -> Int64
DateTime
的分钟作为一个 Int64
。
minute(t::Time) -> Int64
Time
的分钟作为一个 Int64
。
Dates.second
— Functionsecond(dt::DateTime) -> Int64
DateTime
的秒数作为 Int64
。
second(t::Time) -> Int64
Time
的秒数,作为一个 Int64
。
Dates.millisecond
— Functionmillisecond(dt::DateTime) -> Int64
DateTime
的毫秒作为一个 Int64
。
millisecond(t::Time) -> Int64
Time
的毫秒作为一个 Int64
。
Dates.microsecond
— Functionmicrosecond(t::Time) -> Int64
Time
的微秒作为一个 Int64
。
Dates.nanosecond
— Functionnanosecond(t::Time) -> Int64
Time
的纳秒作为一个 Int64
。
Dates.Year
— MethodYear(v)
构造一个具有给定 v
值的 Year
对象。输入必须能够无损转换为 Int64
。
Dates.Month
— MethodMonth(v)
构造一个具有给定 v
值的 Month
对象。输入必须能够无损转换为 Int64
。
Dates.Week
— MethodWeek(v)
构造一个具有给定 v
值的 Week
对象。输入必须能够无损转换为 Int64
。
Dates.Day
— MethodDay(v)
构造一个具有给定 v
值的 Day
对象。输入必须能够无损转换为 Int64
。
Dates.Hour
— MethodHour(dt::DateTime) -> Hour
DateTime 的小时部分作为 Hour
。
Dates.Minute
— MethodMinute(dt::DateTime) -> Minute
DateTime 的分钟部分作为 Minute
。
Dates.Second
— MethodSecond(dt::DateTime) -> Second
DateTime 的秒部分作为 Second
。
Dates.Millisecond
— MethodMillisecond(dt::DateTime) -> Millisecond
DateTime 的毫秒部分作为 Millisecond
。
Dates.Microsecond
— MethodMicrosecond(dt::Time) -> Microsecond
时间的微秒部分作为 Microsecond
。
Dates.Nanosecond
— MethodNanosecond(dt::Time) -> Nanosecond
时间的纳秒部分作为 Nanosecond
。
Dates.yearmonth
— Functionyearmonth(dt::TimeType) -> (Int64, Int64)
同时返回 Date
或 DateTime
的年份和月份部分。
Dates.monthday
— Functionmonthday(dt::TimeType) -> (Int64, Int64)
同时返回 Date
或 DateTime
的月份和日期部分。
Dates.yearmonthday
— Functionyearmonthday(dt::TimeType) -> (Int64, Int64, Int64)
同时返回 Date
或 DateTime
的年、月和日部分。
Query Functions
Dates.dayname
— Functiondayname(dt::TimeType; locale="中文") -> String
dayname(day::Integer; locale="中文") -> String
返回与给定 Date
或 DateTime
的星期几对应的完整星期名称,使用指定的 locale
。也接受 Integer
。
示例
julia> dayname(Date("2000-01-01"))
"星期六"
julia> dayname(4)
"星期四"
Dates.dayabbr
— Functiondayabbr(dt::TimeType; locale="中文") -> String
dayabbr(day::Integer; locale="中文") -> String
返回与给定 Date
或 DateTime
的星期几对应的缩写名称,使用指定的 locale
。也接受 Integer
。
示例
julia> dayabbr(Date("2000-01-01"))
"Sat"
julia> dayabbr(3)
"Wed"
Dates.dayofweek
— Functiondayofweek(dt::TimeType) -> Int64
返回一周中的天数,作为一个 Int64
,其中 1 = 星期一,2 = 星期二,等等。
示例
julia> dayofweek(Date("2000-01-01"))
6
Dates.dayofmonth
— Functiondayofmonth(dt::TimeType) -> Int64
一个 Date
或 DateTime
的月份中的天数,作为一个 Int64
。
Dates.dayofweekofmonth
— Functiondayofweekofmonth(dt::TimeType) -> Int
对于 dt
的星期几,返回它在 dt
所在月份中的编号。因此,如果 dt
的星期几是星期一,那么 1 = 本月的第一个星期一,2 = 本月的第二个星期一,依此类推。
范围为 1:5。
示例
julia> dayofweekofmonth(Date("2000-02-01"))
1
julia> dayofweekofmonth(Date("2000-02-08"))
2
julia> dayofweekofmonth(Date("2000-02-15"))
3
Dates.daysofweekinmonth
— Functiondaysofweekinmonth(dt::TimeType) -> Int
对于 dt
的星期几,返回 dt
所在月份中该星期几的总数。返回值为 4 或 5。在时间表达式中很有用,可以通过在调整函数中包含 dayofweekofmonth(dt) == daysofweekinmonth(dt)
来指定一个月份中最后一天的星期几。
示例
julia> daysofweekinmonth(Date("2005-01-01"))
5
julia> daysofweekinmonth(Date("2005-01-04"))
4
Dates.monthname
— Functionmonthname(dt::TimeType; locale="中文") -> String
monthname(month::Integer, locale="中文") -> String
返回给定 locale
中 Date
或 DateTime
或 Integer
的月份全名。
示例
julia> monthname(Date("2005-01-04"))
"一月"
julia> monthname(2)
"二月"
Dates.monthabbr
— Functionmonthabbr(dt::TimeType; locale="中文") -> String
monthabbr(month::Integer, locale="中文") -> String
返回给定 locale
的 Date
或 DateTime
或 Integer
的缩写月份名称。
示例
julia> monthabbr(Date("2005-01-04"))
"一月"
julia> monthabbr(2)
"二月"
Dates.daysinmonth
— Functiondaysinmonth(dt::TimeType) -> Int
返回 dt
所在月份的天数。值将为 28、29、30 或 31。
示例
julia> daysinmonth(Date("2000-01"))
31
julia> daysinmonth(Date("2001-02"))
28
julia> daysinmonth(Date("2000-02"))
29
Dates.isleapyear
— Functionisleapyear(dt::TimeType) -> Bool
如果 dt
的年份是闰年,则返回 true
。
示例
julia> isleapyear(Date("2004"))
true
julia> isleapyear(Date("2005"))
false
Dates.dayofyear
— Functiondayofyear(dt::TimeType) -> Int
返回 dt
的一年中的天数,1 月 1 日为第 1 天。
Dates.daysinyear
— Functiondaysinyear(dt::TimeType) -> Int
如果 dt
的年份是闰年,则返回 366,否则返回 365。
示例
julia> daysinyear(1999)
365
julia> daysinyear(2000)
366
Dates.quarterofyear
— Functionquarterofyear(dt::TimeType) -> Int
返回 dt
所在的季度。值的范围是 1:4。
Dates.dayofquarter
— Functiondayofquarter(dt::TimeType) -> Int
返回 dt
当前季度的天数。值的范围是 1:92。
Adjuster Functions
Base.trunc
— Methodtrunc(dt::TimeType, ::Type{Period}) -> TimeType
根据提供的 Period
类型截断 dt
的值。
示例
julia> trunc(DateTime("1996-01-01T12:30:00"), Day)
1996-01-01T00:00:00
Dates.firstdayofweek
— Functionfirstdayofweek(dt::TimeType) -> TimeType
将 dt
调整为其所在周的星期一。
示例
julia> firstdayofweek(DateTime("1996-01-05T12:30:00"))
1996-01-01T00:00:00
Dates.lastdayofweek
— Functionlastdayofweek(dt::TimeType) -> TimeType
将 dt
调整为其所在周的星期日。
示例
julia> lastdayofweek(DateTime("1996-01-05T12:30:00"))
1996-01-07T00:00:00
Dates.firstdayofmonth
— Functionfirstdayofmonth(dt::TimeType) -> TimeType
将 dt
调整为其月份的第一天。
示例
julia> firstdayofmonth(DateTime("1996-05-20"))
1996-05-01T00:00:00
Dates.lastdayofmonth
— Functionlastdayofmonth(dt::TimeType) -> TimeType
将 dt
调整为其月份的最后一天。
示例
julia> lastdayofmonth(DateTime("1996-05-20"))
1996-05-31T00:00:00
Dates.firstdayofyear
— Functionfirstdayofyear(dt::TimeType) -> TimeType
将 dt
调整为其年份的第一天。
示例
julia> firstdayofyear(DateTime("1996-05-20"))
1996-01-01T00:00:00
Dates.lastdayofyear
— Functionlastdayofyear(dt::TimeType) -> TimeType
将 dt
调整为其年份的最后一天。
示例
julia> lastdayofyear(DateTime("1996-05-20"))
1996-12-31T00:00:00
Dates.firstdayofquarter
— Functionfirstdayofquarter(dt::TimeType) -> TimeType
将 dt
调整为其季度的第一天。
示例
julia> firstdayofquarter(DateTime("1996-05-20"))
1996-04-01T00:00:00
julia> firstdayofquarter(DateTime("1996-08-20"))
1996-07-01T00:00:00
Dates.lastdayofquarter
— Functionlastdayofquarter(dt::TimeType) -> TimeType
将 dt
调整为其季度的最后一天。
示例
julia> lastdayofquarter(DateTime("1996-05-20"))
1996-06-30T00:00:00
julia> lastdayofquarter(DateTime("1996-08-20"))
1996-09-30T00:00:00
Dates.tonext
— Methodtonext(dt::TimeType, dow::Int; same::Bool=false) -> TimeType
将 dt
调整为与 dow
对应的下一个星期几,其中 1 = 星期一,2 = 星期二,等等
。设置 same=true
允许将当前的 dt
视为下一个 dow
,从而不进行调整。
Dates.toprev
— Methodtoprev(dt::TimeType, dow::Int; same::Bool=false) -> TimeType
将 dt
调整为与 dow
对应的前一个星期几,其中 1 = 星期一,2 = 星期二,等等
。设置 same=true
允许将当前的 dt
视为前一个 dow
,从而不进行任何调整。
Dates.tofirst
— Functiontofirst(dt::TimeType, dow::Int; of=Month) -> TimeType
将 dt
调整为其月份的第一个 dow
。或者,of=Year
将调整为年份的第一个 dow
。
Dates.tolast
— Functiontolast(dt::TimeType, dow::Int; of=Month) -> TimeType
将 dt
调整为其月份的最后一个 dow
。或者,of=Year
将调整为该年的最后一个 dow
。
Dates.tonext
— Methodtonext(func::Function, dt::TimeType; step=Day(1), limit=10000, same=false) -> TimeType
通过最多迭代 limit
次,按 step
增量调整 dt
,直到 func
返回 true
。func
必须接受一个 TimeType
参数并返回一个 Bool
。same
允许在满足 func
时考虑 dt
。
Dates.toprev
— Methodtoprev(func::Function, dt::TimeType; step=Day(-1), limit=10000, same=false) -> TimeType
通过最多迭代 limit
次,按 step
增量调整 dt
,直到 func
返回 true
。func
必须接受一个 TimeType
参数并返回一个 Bool
。same
允许在满足 func
时考虑 dt
。
Periods
Dates.Period
— Method年(v)
季度(v)
月(v)
周(v)
天(v)
小时(v)
分钟(v)
秒(v)
毫秒(v)
微秒(v)
纳秒(v)
构造一个具有给定 v
值的 Period
类型。输入必须能够无损转换为 Int64
。
Dates.CompoundPeriod
— MethodCompoundPeriod(periods) -> CompoundPeriod
从 Period
的 Vector
构造一个 CompoundPeriod
。所有相同类型的 Period
将被加在一起。
示例
julia> Dates.CompoundPeriod(Dates.Hour(12), Dates.Hour(13))
25 hours
julia> Dates.CompoundPeriod(Dates.Hour(-1), Dates.Minute(1))
-1 hour, 1 minute
julia> Dates.CompoundPeriod(Dates.Month(1), Dates.Week(-2))
1 month, -2 weeks
julia> Dates.CompoundPeriod(Dates.Minute(50000))
50000 minutes
Dates.canonicalize
— Functioncanonicalize(::CompoundPeriod) -> CompoundPeriod
通过应用以下规则将 CompoundPeriod
简化为其规范形式:
- 任何足够大的
Period
将被分解为多个Period
(例如,Hour(30)
变为Day(1) + Hour(6)
) - 具有相反符号的
Period
将在可能的情况下合并(例如,Hour(1) - Day(1)
变为-Hour(23)
)
示例
julia> canonicalize(Dates.CompoundPeriod(Dates.Hour(12), Dates.Hour(13)))
1 day, 1 hour
julia> canonicalize(Dates.CompoundPeriod(Dates.Hour(-1), Dates.Minute(1)))
-59 minutes
julia> canonicalize(Dates.CompoundPeriod(Dates.Month(1), Dates.Week(-2)))
1 month, -2 weeks
julia> canonicalize(Dates.CompoundPeriod(Dates.Minute(50000)))
4 weeks, 6 days, 17 hours, 20 minutes
Dates.value
— FunctionDates.value(x::Period) -> Int64
对于给定的周期,返回与该周期相关联的值。例如,value(Millisecond(10))
返回 10 作为整数。
Dates.default
— Functiondefault(p::Period) -> Period
为输入的 Period 返回一个合理的“默认”值,对于 Year、Month 和 Day 返回 T(1)
,对于 Hour、Minute、Second 和 Millisecond 返回 T(0)
。
Dates.periods
— FunctionDates.periods(::CompoundPeriod) -> Vector{Period}
返回组成给定 CompoundPeriod
的 Vector
的 Period
。
此函数需要 Julia 1.7 或更高版本。
Rounding Functions
Date
和 DateTime
值可以使用 floor
、ceil
或 round
方法四舍五入到指定的精度(例如,1 个月或 15 分钟)。
Base.floor
— Methodfloor(dt::TimeType, p::Period) -> TimeType
返回小于或等于 dt
的最近 Date
或 DateTime
,分辨率为 p
。
为了方便,p
可以是类型而不是值:floor(dt, Dates.Hour)
是 floor(dt, Dates.Hour(1))
的快捷方式。
julia> floor(Date(1985, 8, 16), Month)
1985-08-01
julia> floor(DateTime(2013, 2, 13, 0, 31, 20), Minute(15))
2013-02-13T00:30:00
julia> floor(DateTime(2016, 8, 6, 12, 0, 0), Day)
2016-08-06T00:00:00
Base.ceil
— Methodceil(dt::TimeType, p::Period) -> TimeType
返回大于或等于 dt
的最近 Date
或 DateTime
,分辨率为 p
。
为了方便,p
可以是类型而不是值:ceil(dt, Dates.Hour)
是 ceil(dt, Dates.Hour(1))
的快捷方式。
julia> ceil(Date(1985, 8, 16), Month)
1985-09-01
julia> ceil(DateTime(2013, 2, 13, 0, 31, 20), Minute(15))
2013-02-13T00:45:00
julia> ceil(DateTime(2016, 8, 6, 12, 0, 0), Day)
2016-08-07T00:00:00
Base.round
— Methodround(dt::TimeType, p::Period, [r::RoundingMode]) -> TimeType
返回与 dt
最近的 Date
或 DateTime
,分辨率为 p
。默认情况下(RoundNearestTiesUp
),平局(例如,将 9:30 四舍五入到最近的小时)将向上舍入。
为了方便,p
可以是类型而不是值:round(dt, Dates.Hour)
是 round(dt, Dates.Hour(1))
的快捷方式。
julia> round(Date(1985, 8, 16), Month)
1985-08-01
julia> round(DateTime(2013, 2, 13, 0, 31, 20), Minute(15))
2013-02-13T00:30:00
julia> round(DateTime(2016, 8, 6, 12, 0, 0), Day)
2016-08-07T00:00:00
有效的舍入模式为 round(::TimeType, ::Period, ::RoundingMode)
的有 RoundNearestTiesUp
(默认)、RoundDown
(floor
)和 RoundUp
(ceil
)。
大多数 Period
值也可以四舍五入到指定的精度:
Base.floor
— Methodfloor(x::Period, precision::T) where T <: Union{TimePeriod, Week, Day} -> T
将 x
向下舍入到最接近的 precision
的倍数。如果 x
和 precision
是不同的 Period
子类型,则返回值将具有与 precision
相同的类型。
为了方便,precision
可以是类型而不是值:floor(x, Dates.Hour)
是 floor(x, Dates.Hour(1))
的快捷方式。
julia> floor(Day(16), Week)
2 weeks
julia> floor(Minute(44), Minute(15))
30 minutes
julia> floor(Hour(36), Day)
1 day
不支持舍入到 Month
或 Year
的 precision
,因为这些 Period
的长度不一致。
Base.ceil
— Methodceil(x::Period, precision::T) where T <: Union{TimePeriod, Week, Day} -> T
将 x
向上舍入到最接近的 precision
的倍数。如果 x
和 precision
是不同的 Period
子类型,则返回值将具有与 precision
相同的类型。
为了方便,precision
可以是类型而不是值:ceil(x, Dates.Hour)
是 ceil(x, Dates.Hour(1))
的快捷方式。
julia> ceil(Day(16), Week)
3 weeks
julia> ceil(Minute(44), Minute(15))
45 minutes
julia> ceil(Hour(36), Day)
2 days
不支持将舍入精度设置为 Month
或 Year
,因为这些 Period
的长度不一致。
Base.round
— Methodround(x::Period, precision::T, [r::RoundingMode]) where T <: Union{TimePeriod, Week, Day} -> T
将 x
四舍五入到最接近的 precision
的倍数。如果 x
和 precision
是不同的 Period
子类型,则返回值将具有与 precision
相同的类型。默认情况下(RoundNearestTiesUp
),平局(例如,将 90 分钟四舍五入到最接近的小时)将向上舍入。
为了方便,precision
可以是类型而不是值:round(x, Dates.Hour)
是 round(x, Dates.Hour(1))
的快捷方式。
julia> round(Day(16), Week)
2 weeks
julia> round(Minute(44), Minute(15))
45 minutes
julia> round(Hour(36), Day)
2 days
有效的舍入模式 round(::Period, ::T, ::RoundingMode)
为 RoundNearestTiesUp
(默认),RoundDown
(floor
),和 RoundUp
(ceil
)。
不支持将舍入精度设置为 Month
或 Year
,因为这些 Period
的长度不一致。
以下函数未被导出:
Dates.floorceil
— Functionfloorceil(dt::TimeType, p::Period) -> (TimeType, TimeType)
同时返回 Date
或 DateTime
在分辨率 p
下的 floor
和 ceil
。比单独调用 floor
和 ceil
更高效。
floorceil(x::Period, precision::T) where T <: Union{TimePeriod, Week, Day} -> (T, T)
同时返回在分辨率 p
下的 Period
的 floor
和 ceil
。比单独调用 floor
和 ceil
更高效。
Dates.epochdays2date
— Functionepochdays2date(days) -> 日期
获取自舍入纪元(0000-01-01T00:00:00
)以来的天数,并返回相应的日期
。
Dates.epochms2datetime
— Functionepochms2datetime(milliseconds) -> DateTime
获取自基准纪元(0000-01-01T00:00:00
)以来的毫秒数,并返回相应的 DateTime
。
Dates.date2epochdays
— Functiondate2epochdays(dt::Date) -> Int64
获取给定的 Date
,并返回自舍入纪元(0000-01-01T00:00:00
)以来的天数,作为一个 Int64
。
Dates.datetime2epochms
— Functiondatetime2epochms(dt::DateTime) -> Int64
获取给定的 DateTime
,并返回自基准纪元(0000-01-01T00:00:00
)以来的毫秒数,作为 Int64
。
Conversion Functions
Dates.today
— Functiontoday() -> Date
返回 now()
的日期部分。
Dates.unix2datetime
— Functionunix2datetime(x) -> DateTime
获取自 Unix 纪元 1970-01-01T00:00:00
以来的秒数,并转换为相应的 DateTime
。
Dates.datetime2unix
— Functiondatetime2unix(dt::DateTime) -> Float64
获取给定的 DateTime
,并返回自 Unix 纪元 1970-01-01T00:00:00
以来的秒数,作为一个 Float64
。
Dates.julian2datetime
— Functionjulian2datetime(julian_days) -> DateTime
获取自纪元 -4713-11-24T12:00:00
以来的儒略历天数,并返回相应的 DateTime
。
Dates.datetime2julian
— Functiondatetime2julian(dt::DateTime) -> Float64
获取给定的 DateTime
,并返回自儒略纪元 -4713-11-24T12:00:00
以来的儒略历天数,作为 Float64
返回。
Dates.rata2datetime
— Functionrata2datetime(days) -> DateTime
获取自纪元 0000-12-31T00:00:00
以来的 Rata Die 天数,并返回相应的 DateTime
。
Dates.datetime2rata
— Functiondatetime2rata(dt::TimeType) -> Int64
返回自纪元以来从给定的 Date
或 DateTime
开始的 Rata Die 天数。
Constants
一周的天数:
Variable | Abbr. | Value (Int) |
---|---|---|
Monday | Mon | 1 |
Tuesday | Tue | 2 |
Wednesday | Wed | 3 |
Thursday | Thu | 4 |
Friday | Fri | 5 |
Saturday | Sat | 6 |
Sunday | Sun | 7 |
一月: 二月: 三月: 四月: 五月: 六月: 七月: 八月: 九月: 十月: 十一月: 十二月:
Variable | Abbr. | Value (Int) |
---|---|---|
January | Jan | 1 |
February | Feb | 2 |
March | Mar | 3 |
April | Apr | 4 |
May | May | 5 |
June | Jun | 6 |
July | Jul | 7 |
August | Aug | 8 |
September | Sep | 9 |
October | Oct | 10 |
November | Nov | 11 |
December | Dec | 12 |
Common Date Formatters
Dates.ISODateTimeFormat
— ConstantDates.ISODateTimeFormat
描述了日期和时间的 ISO8601 格式。这是 DateTime
的 Dates.format
的默认值。
示例
julia> Dates.format(DateTime(2018, 8, 8, 12, 0, 43, 1), ISODateTimeFormat)
"2018-08-08T12:00:43.001"
Dates.ISODateFormat
— ConstantDates.ISODateFormat
描述日期的 ISO8601 格式。这是 Date
的 Dates.format
的默认值。
示例
julia> Dates.format(Date(2018, 8, 8), ISODateFormat)
"2018-08-08"
Dates.ISOTimeFormat
— ConstantDates.ISOTimeFormat
描述了时间的 ISO8601 格式。这是 Time
的 Dates.format
的默认值。
示例
julia> Dates.format(Time(12, 0, 43, 1), ISOTimeFormat)
"12:00:43.001"
Dates.RFC1123Format
— ConstantDates.RFC1123Format
描述日期和时间的RFC1123格式。
示例
julia> Dates.format(DateTime(2018, 8, 8, 12, 0, 43, 1), RFC1123Format)
"Wed, 08 Aug 2018 12:00:43"
- 1The notion of the UT second is actually quite fundamental. There are basically two different notions of time generally accepted, one based on the physical rotation of the earth (one full rotation = 1 day), the other based on the SI second (a fixed, constant value). These are radically different! Think about it, a "UT second", as defined relative to the rotation of the earth, may have a different absolute length depending on the day! Anyway, the fact that
Date
andDateTime
are based on UT seconds is a simplifying, yet honest assumption so that things like leap seconds and all their complexity can be avoided. This basis of time is formally called UT or UT1. Basing types on the UT second basically means that every minute has 60 seconds and every day has 24 hours and leads to more natural calculations when working with calendar dates.