1. Introduction
In this tutorial, we’ll learn how to convert a date time string to Instant in Kotlin.
First, let’s try to understand the concept of an Instant and compare it against the popular LocalDateTime class, which is also used to represent date objects in Kotlin. We’ll then move from there to address the focus of this tutorial using different techniques.
2. What Is an Instant?
An Instant represents an offset from the epoch 01-01-1970 and, as such, points to a particular instant or point in the timeline.
This means that if we create two Instant objects at the same moment from two different locations on earth, these objects would carry the same time value.
3. How Does Instant Differ From LocalDateTime?
We use both Instant and LocalDateTime to represent time in Kotlin. In fact, LocalDateTime is more popular than the Instant counterpart because it provides methods for manipulating date components like months, days, hours, etc.
In contrast, Instant doesn’t have these features. This is why many applications use LocalDateTime instead of Instant when representing dates and times.
Since many Kotlin applications and programs make use of these two to represent dates and time, let’s reflect briefly on what differs between them.
One major difference between an Instant and LocalDateTime class is how they are calculated. Instant* is calculated independently of a time zone, and it captures the current moment in *UTC while LocalDateTime is a description of the date combined with the local time as seen on a wall clock and contains no time zone information.
So if we create two instances of LocalDateTime from two different locations at the same moment, the values in each of these objects would be different. Contrarily, if we create two instances of Instant at the same moment, regardless of the locations we create them from, they would contain the same time value.
To summarize, we may want to use an Instant in cases where we want to run some job in our application at a precise time and moment for all users around the globe or when we wish to schedule a meeting for users situated in different parts of the globe.
LocalDateTime is more appropriate for describing users’ birthdays or reminding a user of an event (such as “New Year”) that could represent different times in different parts of the globe.
4. Different Ways to Convert a Date Time String to Instant in Kotlin
Now, let’s discuss different ways to convert a date-time string to an Instant.
It’s not uncommon for back-end services return date and time data in the form of strings. Using such strings, we have a number of ways we can get Instant objects out of them.
We’ll be discussing five methods in this tutorial.
4.1. By Parsing Date-Time String to LocalDateTime* Object and *ZoneId
In this method, we combine the date and time strings to get a date-time string that satisfies the ISO 8601 format. We then parse this date-time string into a LocalDateTime object, and using ZoneId, we can convert this object into an Instant:
var strDate = "2021-11-25"
var strTime = "15:20"
var strDateTime = strDate + "T" + strTime
val ldt = LocalDateTime.parse(strDateTime)
val instant: Instant = ldt.atZone(ZoneId.systemDefault()).toInstant()
assertEquals("2021-11-25T14:20:00Z", instant.toString())
4.2. Using Date and Time String Directly With LocalDateTime Object
We create an instance of LocalDateTime using the date and time strings. We then use the time zone identifier represented by ZoneId to obtain an Instant:
var strDate = "2021-11-25"
var strTime = "15:20"
val ldt = LocalDateTime.of(LocalDate.parse(strDate), LocalTime.parse(strTime))
val instant: Instant = ldt.atZone(ZoneId.systemDefault()).toInstant()
assertEquals("2021-11-25T14:20:00Z", instant.toString())
4.3. Using ZonedDateTime Object With Date and Time Strings
Here, we won’t be using the LocalDateTime class. Instead, we use the ZonedDateTime class, which contains the zone information inherently. So using the ZonedDateTime.of() method, we create an object of ZonedDateTime:
var strDate = "2021-11-25"
var strTime = "15:20"
val zdt1 = ZonedDateTime.of(LocalDate.parse(strDate), LocalTime.parse(strTime),ZoneId.systemDefault() )
val zdt2 = ZonedDateTime.of(LocalDateTime.of(LocalDate.parse(strDate), LocalTime.parse(strTime)), ZoneId.systemDefault())
val instant1: Instant = zdt1.toInstant()
val instant2: Instant = zdt2.toInstant()
assertEquals("2021-11-25T14:20:00Z", instant1.toString())
assertEquals("2021-11-25T14:20:00Z", instant2.toString())
4.4. Using DateTimeFormatter on a ZonedDateTime Object
Another way is to combine the date and time strings to get a date-time string compatible with the ISO 8601 format. We then use the generated date-time string and the DateTimeFormatter class to create an object of ZonedDateTime:
val strDate = "2021-11-25"
val strTime = "15:20"
val dtf = DateTimeFormatter.ISO_LOCAL_DATE_TIME.withZone(ZoneId.systemDefault())
val zdt = ZonedDateTime.parse(strDate + "T" + strTime, dtf)
val instant = zdt.toInstant()
assertEquals("2021-11-25T14:20:00Z", instant.toString())
4.5. Calling toInstant() Method Directly on LocalDateTime
Similar to the first two methods we saw, we use an object of the LocalDateTime class. But here, we call the toInstant() method directly on this object to get the required Instant:
val strDate = "2021-11-25"
val strTime = "15:20"
val ldt = LocalDateTime.of(LocalDate.parse(strDate), LocalTime.parse(strTime))
val instant = ldt.toInstant(ZoneId.systemDefault().rules.getOffset(ldt))
assertEquals("2021-11-25T14:20:00Z", instant.toString())
5. Conclusion
In this article, we learned what an Instant is in Kotlin and how it differs from the LocalDateTime class.
Furthermore, we’ve discussed various ways to convert date and time strings to an Instant in Kotlin using five techniques.
As always, code samples and relevant test cases can be found over on GitHub.