Write a simple multiplatform date formatter using 1) native libraries or 2) kotlinx.datetime
Formatting dates often feels borderline tiresome to implement. Personally, every time I have to convert a date to a certain format, I think to myself — now again? Didn’t we do this before? There should be a way of writing this sort of code once and not having to bother with it again.
A simple example of a date formatting requirement could be that we must display the text 18.06.2022 if (you guessed it) the current date is June 18th, 2022. Should be easy enough to do on multiple platforms, right? Sure. But you have to write the “same” formatting logic twice if you write code for Android and iOS, for example, in two separate code bases.
Luckily for us, we can utilize Kotlin Multiplatform Mobile (KMM) which enables us to write the same code once and use it across multiple platforms.
I won’t go into detail about KMM in this post. Let’s go straight to the point and dive into the code instead.
In this post I will present two alternatives:
- A generic formatter written purely in Kotlin, where we will add code to commonMain , androidMain , and iosMain , thereby introducing platform-specific logic;
- Using a multiplatform library called kotlinx-datetime (check the repo here), where we will keep all of our code in commonMain .
For brevity, I will only focus on supporting timestamps in ISO 8601 format, as well as only supporting one date format, namely dd.MM.yyyy .
Our own generic formatter
Let’s define this simple class which we put in commonMain:
(Yes, DateTime isn’t a perfect name for such a class. We could name it Iso8601TimestampFormatter or similarly, but I chose to name it differently for brevity.)
It’s quite basic. We pass in an ISO 8601 timestamp as well as a format (dd.MM.yyyy), and it should return the formatted date.
So how does it look on Android?
The following should be placed in androidMain :
We are parsing our timestamp using the ZonedDateTime API, and subsequently formatting it with our format via DateTimeFormatter .
Then how about iOS?
Instead of using Java libraries, which aren’t accessible on iOS, we will instead refer to the Foundation framework. It contains all the things we need for date formatting (and more, of course).
Let’s put the following in iosMain :
We create an instance of NSDateFormatter and set the time zone, locale, and format. Finally, we invoke stringFromDate() to get the formatted string.
You may ask — why not use the Swift APIs like DateFormatter , TimeZone , etc.? The TL;DR is that we are unable to import any pure Swift modules from Kotlin code in the current state of KMM. Importing Objective-C APIs (NS…), however, works just fine. See this link for more info.
Let’s test it! ✅
As our tests are platform-independent, it is sufficient to place them in commonTest only:
When we ask Android Studio to run the tests, we are asked to use a specific target (depending on how our project is configured):