May 14, 2021 Julia
Dates
module provides two types of data about time: Date and
DateTime
with precision of days and milliseconds, respectively, are subtypes of the abstract data type
TimeType
Date
T
he reason for using two data types is simple: some operations are simple in themselves, and it is completely unnecessary to use high-precision data types, both in code and logically.
For example,
Date
only accurate to days (that is, no hours, minutes, or seconds), so use without considering time zones, daylight saving time, and leap seconds.
Date
and
DateTime
are simple packages for
Int64
and the only member
instant
UTInstant{P}
which represents world-time-based machine time.
Datetime
type
does not take into account
the time zone (according to Python), or the local time inside Java
8
. A
dditional time-date operations
can be obtained through the Timezones.jl
extension package, where the data comes
from Olsen Time Zone Database
.
Date
and
DateTime
ISO 8601 standards. I
t is worth noting that ISO 8601 deals with D.D. dates in a special way. S
imply put, the last day of D.D. was 1-12-31 D, and the next day was 1-1-1 A.D., so there was no 0 A.D. existence.
The ISO standard states that 1 year D is 0 years,
0000-12-21
is the day before
0001-01-01
-0001
is 2 D.
-0003
There are generally two commonly used time notations, one based on the Earth's state of transition (the Earth turns a full circle for 1 day), and the other based on SI seconds (fixed constant). T
he two means of representing are not the same. I
magine, because the earth turns around, the world - based seconds may be unequally long. B
ut in general, world -based
Date
and
DateTime
simplified scenario, such as leap seconds. T
he official name of this time-representing scheme is
world time
.
This means that every minute has 60 seconds, every day there are 60 hours, which makes the calculation of time more natural and simple.
Date
and
DateType
constructed by integers or
Period
through direct incoming, or as differences with a specific time:
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
and
DateTime
are achieved through formatted strings.
A formatted string
is a
separated
or fixed-width
"character segment" that represents a period of time and is then
Date
DateTime
constructor.
Using the separated character segment method, you need to display an indicated separator, so
"y-m-d"
is one between the first and second
-
"2014-07-16"
y
m
d
tell the parser the meaning of each character segment.
A fixed - width character segment is a string that uses a fixed - width to represent time.
So
"yyyymmdd"
is
"20140716"
.
At the same time the character represents the month can also be resolved,
u
U
respectively, the abbreviation and full name of the month. T
he month name in English is supported by default,
u
to
Jan
Feb
Mar
U
corresponds to
January
February
March
However,
dayname
the localized output can also be implemented by adding a map of the
Dates.MONTHTOVALUEABBR
and
Dates.MONTHTOVALUE
dictionaries to the
locale=>Dict{UTF8String, Int}
monthname
More examples of parsing and formatting can be referred to tests/dates/io.jl .
It's intuitive to calculate the interval between two
Date
or
DateTime
considering that they're just simple packages for
UTInstant{Day}
UTInstant{Millisecond}
. T
he difference is that the time interval
Date
is calculated,
Day
and
DateTime
interval is calculated
Millisecond
.
Similarly, comparing two
TimeType
is essentially comparing two
Int64
julia> dt = Date(2012,2,29)
2012-02-29
julia> dt2 = Date(2000,2,1)
2000-02-01
julia> dump(dt)
Date
instant: UTInstant{Day}
periods: Day
value: Int64 734562
julia> dump(dt2)
Date
instant: UTInstant{Day}
periods: Day
value: Int64 730151
julia> dt > dt2
true
julia> dt != dt2
true
julia> dt + dt2
Operation not defined for TimeTypes
julia> dt * dt2
Operation not defined for TimeTypes
julia> dt / dt2
Operation not defined for TimeTypes
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
381110402000 milliseconds
Because
Date
and
DateTime
are encapsulated
Int64
a specific part can be obtained by accessing functions.
The get function of the lowercase letter returns an integer:
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
The get function for capital letters returns a value of
Period
:
julia> Dates.Year(t)
2014 years
julia> Dates.Day(t)
31 days
If you need to get more than one field at a time, you can use the conformity function:
julia> Dates.yearmonth(t)
(2014,1)
julia> Dates.monthday(t)
(1,31)
julia> Dates.yearmonthday(t)
(2014,1,31)
You can also get the
UTInstant
values directly:
julia> dump(t)
Date
instant: UTInstant{Day}
periods: Day
value: Int64 735264
julia> t.instant
UTInstant{Day}(735264 days)
julia> Dates.value(t)
735264
Query functions can be used to
TimeType
such as the day of the week:
julia> t = Date(2014,1,31)
2014-01-31
julia> Dates.dayofweek(t)
5
julia> Dates.dayname(t)
"Friday"
julia> Dates.dayofweekofmonth(t)
5 # 5th Friday of January
Month information:
julia> Dates.monthname(t)
"January"
julia> Dates.daysinmonth(t)
31
Year and season information:
julia> Dates.isleapyear(t)
false
julia> Dates.dayofyear(t)
31
julia> Dates.quarterofyear(t)
1
julia> Dates.dayofquarter(t)
31
dayname
monthname
be displayed by passing in
locale
julia> const french_daysofweek =
[1=>"Lundi",2=>"Mardi",3=>"Mercredi",4=>"Jeudi",5=>"Vendredi",6=>"Samedi",7=>"Dimanche"];
# Load the mapping into the Dates module under locale name "french"
julia> Dates.VALUETODAYOFWEEK["french"] = french_daysofweek;
julia> Dates.dayname(t;locale="french")
"Vendredi"
monthname
Dates.VALUETOMONTH
to be loaded with
locale=>Dict{Int, UTF8String}
.
Before using any programming language/time and date framework, it's a good idea to understand how the next interval is handled, because there are places where special skills are required .
Dates
module works like this, making as
period
as possible each time when doing period arithmetic. T
his method is
called calendar
arithmetic, or the usual way of daily communication. W
hat the hell are these? T
o give a classic example: January 31, 2014 plus January. W
hat's the answer? J
avaScript will come out
on March 3rd (assuming
31 days). P
HP will get March
3月2号 <http://stackoverflow.com/questions/5760262/php-adding-months-to-a-date-while-not-exceeding-the-last-day-of-the-month>
(assuming 30 days). I
n fact, there is no correct answer to this question.
Dates
module will give the answer on February 28th. H
ow did it come about?
Imagine a 7-7-7 gambling game at the casino.
Imagine that the slot of the gambling machine is not 7-7-7, but year-month-day, or, in our case, 2014-01-31. W
hen you want to add a month to this date, the slot corresponding to the month will increase by 1, so it is now 2014-02-31, and then check that the day of the year-month-day exceeds the largest legal number of the month (28). W
hat are the consequences of this approach? W
e continue to add a month,
2014-02-28 + Month(1) == 2014-03-28
. W
hat the? D
o you expect the result to be the last day of March? S
orry, no, think 7-7-7. B
ecause to change as few slots as possible, so we add 1 on the month, 2014-03-28, and then there is no more, because this is a legitimate date. H
owever, if we add 2 months to the original date (2014-01-31), we will get the expected 2014-03-31. A
nother problem with this approach is the loss of interchangeability, if the order of forced additions (that is, different results are obtained by using unused order additions).
For example::
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
What's going on? I
n the first example, we add a day to January 29 to get 2014-01-30; T
hen add January, get 2014-02-30, and then be adjusted to 2014-02-28. I
n the second example, we add
one
month, get 2014-02-29, then adjust to 2014-02-28,
then add one day, get 2014-03-01. O
ne of the design principles for dealing with this problem is
that, if there are multiple intervals, the order of operations is arranged by the type of interval, not by the size of their values or the order in which they appear; T
hat said, the first plus is
Year
then
Month
then
Week
and so on.
So the following
example is
exchangeable:
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
It's a hassle? W
ell, maybe. W
hat about
Dates
user of Dates? T
he most basic thing is to be clear, when operating months, if forced to indicate the order of operations, may produce unexpected results, nothing else.
Fortunately, this is basically all special cases (UT time has eliminated the hassle of daylight saving time, leap seconds, etc.).
The arithmetic of time intervals is convenient, but at the same time, some time operations are based on the calendar or the time itself, rather than a fixed interval. F or example, the calculation of holidays, such as "Remembrance Day - Last Monday in May", or "Thanksgiving Day - Fourth Thursday in November". The calculation of these times involves calendar-based rules, such as the first or last day of a month, the next Thursday, or the first and third Wednesdays, and so on.
Dates
module provides several
adjustment functions,
which can describe time rules in a simple and concise way. T
he first group is about the first and last elements of the week, month, quarter, year.
The function parameter is
TimeType
and then returns or adjusts to
the correct date
according to the rule.
# 调整时间到相应的周一
julia> Dates.firstdayofweek(Date(2014,7,16))
2014-07-14
# 调整时间到这个月的最后一天
julia> Dates.lastdayofmonth(Date(2014,7,16))
2014-07-31
# 调整时间到这个季度的最后一天
julia> Dates.lastdayofquarter(Date(2014,7,16))
2014-09-30
The next set of
tofirst
tolast
tonext
and
toprev
the first argument
DateFunction
the second
TimeType
start date. A
DateFunction
is a function, usually an anonymous function, that
TimeType
as input,
Bool
true
whether a particular condition is met.
For example::
julia> istuesday = x->Dates.dayofweek(x) == Dates.Tuesday # 如果是周二, 返回 true
(anonymous function)
julia> Dates.tonext(istuesday, Date(2014,7,13)) # 2014-07-13 is a 是周日
2014-07-15
# 同时也额外提供了一些函数, 使得对星期几之类的操作更加方便
julia> Dates.tonext(Date(2014,7,13), Dates.Tuesday)
2014-07-15
In the case of complex time expressions, it is convenient to use
do-block
julia> Dates.tonext(Date(2014,7,13)) do x
# 如果是十一月的第四个星期四, 返回 true (感恩节)
Dates.dayofweek(x) == Dates.Thursday &&
Dates.dayofweekofmonth(x) == 4 &&
Dates.month(x) == Dates.November
end
2014-11-27
Similarly,
tofirst
tolast
are
DateFunction
but the default adjustment range bit is for the month, or you can use the keyword parameters to indicate that the adjustment range is for the current year:
julia> Dates.tofirst(istuesday, Date(2014,7,13)) # 默认位当月
2014-07-01
julia> Dates.tofirst(istuesday, Date(2014,7,13); of=Dates.Year)
2014-01-07
julia> Dates.tolast(istuesday, Date(2014,7,13))
2014-07-29
julia> Dates.tolast(istuesday, Date(2014,7,13); of=Dates.Year)
2014-12-30
The last function is
recur
.
recur
function is the adjustment process to quantify, entering as the start and end dates (or
StepRange
plus
DateFunction
determine whether a date should be returned.
In this case,
DateFunction
referred to as the "include" function because it indicates (by returning true) whether a date should appear in the returned date array.
# 匹兹堡大街清理日期; 从四月份到十一月份每月的第二个星期二
# 时间范围从2014年1月1号到2015年1月1号
julia> dr = Dates.Date(2014):Dates.Date(2015);
julia> recur(dr) do x
Dates.dayofweek(x) == Dates.Tue &&
Dates.April <= Dates.month(x) <= Dates.Nov &&
Dates.dayofweekofmonth(x) == 2
end
8-element Array{Date,1}:
2014-04-08
2014-05-13
2014-06-10
2014-07-08
2014-08-12
2014-09-09
2014-10-14
2014-11-11
More examples and tests can be referred to test/dates/adjusters.jl .
Time intervals are considered from a human point of view for a period of time, sometimes irregularly. T
hink about the next month; I
f in terms of days, in different cases, it may represent 28, 29, 30, or 31. O
r a year can represent 365 or 366 days.
Period
is a simple encapsulation of type
Int64
constructed from any data that can be converted to
Int64
such
Year(1)
Month(3.0)
The same type of interval behaves like an integer:
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 years
julia> y3 - y2
8 years
julia> y3 * y2
20 years
julia> y3 % y2
0 years
julia> y1 + 20
21 years
julia> div(y3,3) # 类似于整数除法
3 years
For more detailed information, refer to the API index of the
Dates
module
.