Lesson 12 - Date and Time in Kotlin - Modifying and intervals
In the previous lesson, Date and Time in Kotlin - Creating and formatting, we learned to create
instances and format their value. In today's tutorial of our Kotlin course,
we're going to modify the value and introduce time intervals.
First of all, we'll learn how to convert between the
LocalDateTime data types.
Converting from LocalDateTime
We convert from
LocalDateTime easily by using the
Converting to LocalDateTime
LocalDateTime instances using one of the
of*() methods where we specify the date and time separately:
val beginning = LocalDate.of(1939, 9, 1) val dateTime = LocalDateTime.of(beginning, LocalTime.of(10, 0))
If we want to set the time at the very beginning of the day, we can use the
atStartOfDay() method. Another method, which allows us to take a
date and attach a time to it, is
atTime(). Here’s an alternative
approach for the example above:
val beginning = LocalDate.of(1939, 9, 1) val dateTime = beginning.atStartOfDay() val dateTime2 = beginning.atTime(0, 0)
Modifying the value
We can add a particular number of days, hours and so on to an existing
instance. We use the methods with the
minus...() prefix to do just that. I'm sure we
don't have to explain which does what. The important thing to remember is that
they return a new instance with the modified value. The
instance is completely immutable (unchangeable) and any changes
are made by replacing the original instance with a new one (as we do with
Here’s an example where we add three more days to the current date:
val dateTime = LocalDateTime.now() dateTime = dateTime.plusDays(3) println(dateTime.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)))
Dec 9, 2016
Here's a list of the available methods:
Periods and Durations
Aside from the methods we've already mentioned, there are also four general
plus() methods which receive an interval
that is to be added or subtracted. They come in handy when we don't know whether
we're going to add days or years at a specific point in the application, so they
spare us from having to implement complex branching. There are also
Period classes available, which provide
us objects representing time intervals.
When we get to interfaces, you can check that both classes
TemporalAmount interface. However, don't worry about
it too much for now.
Here's a modified version of the example code from before:
val dateTime = LocalDateTime.now() dateTime = dateTime.plus(Period.ofDays(3)) println(dateTime.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)))
Because Kotlin allows us to overload operators (see further in the course), we can rewrite the code above like this:
var dateTime = LocalDateTime.now() dateTime += Period.ofDays(3) println(dateTime.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)))
The output will remain the same as with the previous example. The
of...*() methods have the same "suffixes" as the
minus() methods listed above.
The difference between
Duration is that
Duration represents a time interval which isn't related to the
calendar anyhow (e.g. how long it takes to manufacture a car), a day always
lasts 24 hours there. Whereas,
Period also takes daylight saving
time into consideration, so a day may sometimes be 23 or 25 hours long. We use
Period to work with
work exclusively with time.
To make units (such as days, hours, minutes and similar) easier to work with,
ChronoUnit class. It uses the
class internally, so all it provides is a different syntax for the tasks we
demonstrated above. For completeness' sake, we'll go over an example of its
var dateTime = LocalDateTime.now() dateTime = dateTime.plus(3, ChronoUnit.DAYS) println(dateTime.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)))
ChronoUnit implements the
interface, in case you meet it later on. We'll introduce interfaces later in the
As you can see, the implementation of date and time in Kotlin is quite complex. We won't go into unnecessary details. Instead, we'll focus on practical use, as we always do here at ICT.social.
The last method worth mentioning is the static
Period class. It allows us to compute the difference
(interval) between 2 dates. More accurately, it computes the difference between
two objects implementing the
Temporal interface, which is the
common data type for the
val started = LocalDate.of(1939, 9, 1) val ended = LocalDate.of(1945, 9, 2) val period = Period.between(started, ended) println("The World War II lasted for " + period.get(ChronoUnit.YEARS) + " years and " + period.get(ChronoUnit.DAYS) + " days")
The World War II lasted for 6 years and 1 days
The same method is available in the
Duration class, however,
that one works with
LocalDateTime rather than LocalDate. We
wouldn’t be able to extract the number of years from an interval since years
don't have a fixed amount of days and
Duration isn't related to
Setting the value
We set the value using the
with...*() methods, they all have the
same suffixes as the methods mentioned earlier. As always, remember that they
only return a new instance and don't modify the current one.
val started = LocalDate.of(1939, 9, 1) started = started.withYear(1945) // Sets the year to 1945
The fact that all of the methods return new instances, so as to keep classes immutable, also allows us to use the fluent interface, aka "method chaining". It really isn’t all that complicated, all it means is that we’re able to call multiple methods on a single line.
Let's set the value to programmer Christmas, i.e. Halloween (since, 31 OCT = 25 DEC).
var started = LocalDate.of(1939, 9, 1) started = started.withMonth(9).withDayOfMonth(31)
We'll continue in the next lesson, Date and Time in Kotlin- Parsing and comparing, where we'll finish up with date and time in Kotlin. We'll learn how to parse date and time and how to access inner values.