Julia - Date & Time


Advertisements

Julia has a standard package named Dates which provides us the following two functions to work with Dates and Times −

  • Using Dates

  • Import Dates

The difference between these two functions is that if we use import Dates function then we will have to explicitly prefix Dates with every function, for example, Dates.dayofweek(dt). On the other hand, if we use using Dates function then we do not have to add the prefix Dates explicitly with every function because it will bring all exported Dates function into main.

Relationship between Types

Julia use various types to store Dates, Times, and DateTimes. The diagram below shows the relationship between these types −

Date & Time

Date & Time1

Date, Time, and DateTimes

To work with Dates and Times, Julia has the following three datatypes −

Dates.Time − Accurate to nanosecond, this object represents a precise moment of the day.

Dates.Date − As the name implies, it represents just a date.

Dates.DateTime − Accurate to a millisecond, this object represents combination of a date and a time of day. It actually specifies an exact moment in time.

Example

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

Queries regrading Date and Time

After having the objects such as date/time or date, we can use the following functions to extract the required information −

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

Date Arithmetic

It is also possible to do arithmetic on date/time as well as date objects. The most common one is to find the difference between two such objects as shown in the below example −

Example

julia> today_date - My_Birthday
13409 days

julia> datetimenow - armistice_date
943436237800 milliseconds

We can convert these differences in some unit as follows −

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

We can also add and subtract periods of time to date and date/time objects as follows −

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

In the above example, we have added 20 years and 6 months to my birth date.

Range of Dates

Julia provides the facility to create range of dates by making iterable range objects. In the example given below, we will be creating an iterator that yields the first day of every month.

Example

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

From the above range object, we can find out which of these fall on weekdays. For this we need to create an anonymous function to filter() which will test the day name against the given day names −

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

Formatting of Dates

Following table gives the date formatting codes with the help of which we can specify date formats −

Character Date/Time element
Y Year digit Ex. yyyy => 1984, yy => 84
m Month digit Ex. m => 7 or 07
u Month name Ex. Jun
U Month name Ex. January
e Day of week Ex. Mon
E Day of week Ex. Monday
d Day Ex. 1 or 01
H Hour digit Ex. HH => 00
M Minute digit Ex. MM => 00
S Second digit Ex. S => 00
s Millisecond digit Ex. .000

Example

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

Rounding Dates and Times

As we know that the functions round(), floor(), and ceil() are usually used to round numbers up or down. These functions can also be used to round dates so that the dates can be adjusted forward or backward in time.

Example

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"

The ceil() function will adjust the dates/time forward as given below −

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

Recurring Dates

If we want to find all the dates in a range of dates that satisfy some criteria, it is called recurring dates. Let us understand with the help of following example −

First, we need to create a Range of date as we did previously −

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

Now we can use filter() function to find Sundays in a month −

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 time

Unix time is another type of timekeeping in which the count of the number of seconds that have elapsed since the birth of Unix (beginning of the year 1970). We will never observe the end of Unix time because Julia store the count in a 64-bit integer.

The time() function will return the Unix time value −

julia> using Dates
julia> time()
1.60206441103e9

The unix2datetime() function will convert a Unix time value to date/time object −

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

Moments in time

DateTimes, in the field instant, are stored in milliseconds. We can obtain this value by using Dates.value function as follows −

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

julia> Dates.value(moment)
63737767811885

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

Time and Monitoring

Julia provides us @elapsed macro which will return the time (number of seconds) an expression took to evaluate.

Example

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
Advertisements