Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

Julia date and time


May 14, 2021 Julia


Table of contents


Date and time

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.

The constructor

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 .

Interval/comparison

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

Access functions

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 function

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} .

Interval arithmetic

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.).

Adjust the function

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 .

The interval

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 .