Liking cljdoc? Tell your friends :D

Times & dates

In this chapter we introduce times & dates and how we can manipulate them.

Introduction

If we asked a stranger for the time they’d likely respond with the just time of day, for example, "a quarter to eight". It would be uncommon for them to tell you the date and timezone also, unless you asked for it. This is the same time that we learn to read as children, on analog watches and wall-clocks.

So let’s start with asking tick for the time of day, with the time function. We demonstate this with our first example:

Example 1. Getting the time

To get the current time, call (t/time) with no arguments:

(t/time)
If you have enabled JavaScript, you’ll see a button labelled Eval on the right of the code snippet. Press this button to instruct your browser to evaluate the tick code and display the result. You can clear the result by pressing the button labelled Clr. Many of the code examples in this documentation can be evaluated like this.

But so we can continue with our time-telling story, let’s get a specific time of "a quarter to eight":

Example 2. Getting a specific time

To get a specific time of day, call (t/time) with a string argument:

(t/time "19:45")

If we wanted to know the name of the day today, we might ask "what’s the day today". In tick, we’d use the day function.

Example 3. Getting the name of the day

We can get the name of the day today like this:

(t/day (t/today))

Or, even just:

(t/day)

Or, the day tomorrow:

(t/day (t/tomorrow))

The time "a-quarter-to-eight tomorrow" is useful, but if we wanted to record events we’d soon want to ask the date too. In tick, dates are specific calendar dates in the Gregorian calendar and include a day, month and year. We can ask the date with the date function:

Example 4. Getting today’s date

To get today’s date, we use the date function without arguments:

(t/date)

Alternatively we can call today:

(t/today)
On the Java platform a tick date corresponds to a java.time.LocalDate instance, while in a JavaScript environment it corresponds to js-joda’s LocalDate.

Like with time, we can get particular dates by calling date with a string argument:

Example 5. Getting a specific date

To get June 21st (or 21st June! [1]) in 2018:

(t/date "2018-06-21")

Now we can ask for both time and date, we can combine them into a date-time.

We can use the function date-time with no arguments to get the current time at the current date:

Example 6. Getting the current date-time

To get the current date-time, call t/date-time with no arguments:

(t/date-time)

As with time and date, we can use a string argument with date-time, as shown in Getting a specific date-time.

Example 7. Getting a specific date-time

To get the time of the Armistice of Compiègne, use ISO 8601:

(t/date-time "1918-11-11T11:00")

A date-time is the time at a specific location on a specific calendar date. Since noon is established as the point at which the Sun crosses the meridian, and since the Earth is spherical and rotating, noon is the same time for everyone. Consequently, the world is split into time-zones, each at an offset to Coordinated Universal Time (UTC).

If we wish to compare times in different places, we need to capture the local offset, as shown in Getting a specific date-time with a local offset..

Example 8. Getting a specific date-time with a local offset.

The Armistice of Compiègne was agreed at 11:00 am Paris time. On November 11th, 1918, Paris was one hour ahead of UTC. To capture this offset we can use offset-date-time:

(t/offset-date-time "1918-11-11T11:00:00+01:00")

There is a problem with using time offsets—they can change for a given time zone, especially since many time zones practice Daylight Savings Time (DST). To capture the actual time zone, rather than the offset in effect on a given date, we can use zoned-date-time, as shown in Getting a specific date-time in a time zone..

Why not local-date?

Java and js-joda name classes representing dates and date-times with a prefix of 'Local'. Why doesn’t tick maintain this convention? The reason is that date-times (and dates especially) are always local, so the use of this prefix is superfluous. However, in Java, it is useful to distinguish between java.time.LocalDate and java.util.Date, or in JavaScript, between js-joda’s LocalDate and JavaScript’s built-in Date. In these contexts, the 'Local' prefix makes sense.

In, tick, instances of Java’s java.util.Date and JavaScript’s Date are termed insts, so the term date is unambiguous (i.e. always local).

Example 9. Getting a specific date-time in a time zone.

The Armistice of Compiègne was agreed at 11:00 am Paris time. In the summer, Paris time moves one hour forward for Daylight Savings Time (DST). Although Paris did use Daylight Savings Time in 1918, the clocks had already moved back (at midnight on 8th October). To capture the time zone, along with its various rules for calculating offsets, we can use zoned-date-time:

(t/zoned-date-time
 "1918-11-11T11:00:00Z[Europe/Paris]")

Rather than using offset-date-times and zoned-date-times, you should use instants when you want UTC-based date-times and don’t care about time-zones and 'local' time.

Since a zoned-date-time (and offset-date-time) captures the offset from UTC, we can convert these into instants, as show in Converting an offset-date-time to an instant.

On the Java platform, an instant is a java.time.Instant and replaces the flawed java.util.Date. In a JavaScript environment, js-joda provides an identical class.
Example 10. Converting an offset-date-time to an instant

To convert an offset-date-time to an instant, call instant:

For example:

(t/instant (t/offset-date-time "1918-11-11T11:00:00+01:00"))

If you want to get an instant representing the current time in UTC, call instant without arguments.

Example 11. Get the current instant in UTC

To get the current instant, do this:

(t/instant)

Alternatively, you can just call now:

(t/now)

If you do need a java.util.Date or JavaScript Date, for instance, for interoperating with an existing library, use the inst function.

Example 12. Converting an instant to an inst

To convert the current instant to an inst:

(t/inst (t/now))

In this case, the same could be achieved with the zero-argument form of inst:

(t/inst)

That’s it for our introduction. Now we’ll return to constructing times and dates.

Construction

Time values are constructed with new-time.

Example 13. Creating a time value

To create the time 11 o’clock am:

(t/new-time 11 0)

new-time also has other forms to increase precision, for example, with seconds…

(t/new-time 23 59 59)

…and with nanoseconds

(t/new-time 23 59 59 999999)
What’s the difference between time and new-time?

Until now we’ve been using time to create time values, for example, (t/time "11:00"), but now we have started to use the new-time function. What’s going on?

Values are created using constructor functions in tick. There are also conversion functions, which are named after the value they convert to. For example, the time function is a conversion function which converts are string to a time value.

In tick, the names of constructor functions are prefixed with new- to prevent naming clashes with conversion functions.

These conventions have been taken from a blog article from Stuart Sierra on how to name Clojure functions—as good a guide as any.

Similarly, dates are constructed with new-date, a function which has 3 forms. The first, and most common form, requires 3 arguments: the year, month and day (of the month).

Example 14. Creating a date value

JUXT was incorporated on March 22nd, 2013. We can create this date with new-date like this:

(t/new-date 2013 3 22)

Reification

While t/time and t/new-time return a time, you may want to provide a date for that time later on. We can reify with t/on and t/at.

reify

[ree-uh-fahy, rey-] [2]

verb (used with object), re·i·fied, re·i·fy·ing.

  1. to convert into or regard as a concrete thing: to reify a concept.

You can think of a time (or a date) as being a partially defined date-time.

Example 15. Reifying a date-time from dates and times

If we have a date of 1918-11-11, we can construct a date-time by giving the time of 11am with at:

(-> (t/date "1918-11-11") (t/at "11:00"))

Alternatively, if we have the time we can add the date:

(-> (t/time "11:00") (t/on "1918-11-11"))

We can also use reification to provide the location, with in. This allows us to take a local date-time and produce either a zoned-date-time or an offset-date-time.

Example 16. Reifying a zoned-date-time from dates and times

To construct the zoned-date-time of the Armistice of Compiègne with time, on and in:

(-> (t/time "11:00") (t/on "1918-11-11") (t/in "Europe/Paris"))

Alternatively, we can use t/offset-by in place of t/in, to produce an offset-date-time.

(-> (t/time "11:00") (t/on "1918-11-11") (t/offset-by 2))

Conversion

With instants, insts (java.util.Date, JavaScript’s Date), zoned-date-times and offset-date-times, it’s easy to get stuck with the wrong type. Therefore, tick provides functions to convert between them.

To convert between any of these types, simply call the eponymous function corresponding to the destination type with the source type as an argument.

Example 17. Converting between types

To convert between an instant and a zoned-date-time:

(t/zoned-date-time (t/now))

To convert between a zoned-date-time and an instant:

(t/instant (t/zoned-date-time))

To convert between an instant and an inst:

(t/inst (t/now))

It’s also possible to convert from strings to their destination types, which will involve parsing the string in to its most appropriate type prior to conversion.

In Java, types are converted according to the rules in Converting between Java 8 types.

Table 1. Converting between Java 8 types
Convert betweento instantto offset-date-timeto zoned-date-timeto inst

from instant

identity

OffsetDateTime/ofInstant

ZonedDateTime/ofInstant

Date/from

from offset-date-time

.toInstant

identity

.toZonedDateTime

.toInstant, Date/from

from zoned-date-time

.toInstant

.toOffsetDateTime

identity

.toInstant, Date/from

from inst

.toInstant

.toInstant, OffsetDateTime/ofInstant

.toInstant, ZonedDateTime/ofInstant

identity

from String

parse

OffsetDateTime/parse

ZonedDateTime/parse

parse, then Date/from

Extraction

Culturally, we understand time via calendars and it is often desirable to extract certain fields from time values.

The day-of-week function extracts the day (of the week) from a time value, such as date, as shown in Extracting fields from a date.

Example 18. Extracting fields from a date
(t/day-of-week (t/date "2018-07-09"))
(t/month (t/date "2018-07-09"))
(t/year (t/date "2018-07-09"))

Days of the week, and months of the year, are available as constants listed in Tick constants and their corresponding host types.

Table 2. Tick constants and their corresponding host types
TickJavaJavaScript

tick.alpha.api/MONDAY

java.time.DayOfWeek.MONDAY

DayOfWeek.MONDAY

tick.alpha.api/TUESDAY

java.time.DayOfWeek.TUESDAY

DayOfWeek.TUESDAY

tick.alpha.api/WEDNESDAY

java.time.DayOfWeek.WEDNESDAY

DayOfWeek.WEDNESDAY

tick.alpha.api/THURSDAY

java.time.DayOfWeek.THURSDAY

DayOfWeek.THURSDAY

tick.alpha.api/FRIDAY

java.time.DayOfWeek.FRIDAY

DayOfWeek.FRIDAY

tick.alpha.api/SATURDAY

java.time.DayOfWeek.SATURDAY

DayOfWeek.SATURDAY

tick.alpha.api/SUNDAY

java.time.DayOfWeek.SUNDAY

DayOfWeek.SUNDAY

tick.alpha.api/JANUARY

java.time.Month.JANUARY

Month.JANUARY

tick.alpha.api/FEBRUARY

java.time.Month.FEBRUARY

Month.FEBRUARY

tick.alpha.api/MARCH

java.time.Month.MARCH

Month.MARCH

tick.alpha.api/APRIL

java.time.Month.APRIL

Month.APRIL

tick.alpha.api/MAY

java.time.Month.MAY

Month.MAY

tick.alpha.api/JUNE

java.time.Month.JUNE

Month.JUNE

tick.alpha.api/JULY

java.time.Month.JULY

Month.JULY

tick.alpha.api/AUGUST

java.time.Month.AUGUST

Month.AUGUST

tick.alpha.api/SEPTEMBER

java.time.Month.SEPTEMBER

Month.SEPTEMBER

tick.alpha.api/OCTOBER

java.time.Month.OCTOBER

Month.OCTOBER

tick.alpha.api/NOVEMBER

java.time.Month.NOVEMBER

Month.NOVEMBER

tick.alpha.api/DECEMBER

java.time.Month.DECEMBER

Month.DECEMBER

We can use these constants to compare with = as shown in Comparing the day of the week from a date.

Example 19. Comparing the day of the week from a date

Is the date 2018-07-09 is a Monday?

(= (t/day-of-week (t/date "2018-07-09")) t/MONDAY)

But is the month May?

(= (t/month (t/date "2018-07-09")) t/MAY)

1. iso-8601,Dates are so often subject to regional conventions. Therefore in tick, we always parse and format dates according to ISO 8601.

Can you improve this documentation?Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close