Write a easy multiplatform date formatter utilizing 1) native libraries or 2) kotlinx.datetime
Formatting dates usually feels borderline tiresome to implement. Personally, each time I’ve to transform a date to a sure format, I believe to myself — now once more? Didn’t we do that earlier than? There needs to be a approach of penning this type of code as soon as and never having to trouble with it once more.
A easy instance of a date formatting requirement may very well be that we should show the textual content 18.06.2022 if (you guessed it) the present date is June 18th, 2022. Must be simple sufficient to do on a number of platforms, proper? Certain. However it’s a must to write the “similar” formatting logic twice for those who write code for Android and iOS, for instance, in two separate code bases.
Fortunately for us, we are able to make the most of Kotlin Multiplatform Mobile (KMM) which allows us to write down the identical code as soon as and use it throughout a number of platforms.
I gained’t go into element about KMM on this publish. Let’s go straight to the purpose and dive into the code as a substitute.
On this publish I’ll current two alternate options:
- A generic formatter written purely in Kotlin, the place we’ll add code to
iosMain, thereby introducing platform-specific logic;
- Utilizing a multiplatform library referred to as
kotlinx-datetime(verify the repo here), the place we’ll preserve all of our code in
For brevity, I’ll solely concentrate on supporting timestamps in ISO 8601 format, in addition to solely supporting one date format, particularly
Let’s outline this straightforward class which we put in
DateTime isn’t an ideal identify for such a category. We may identify it
Iso8601TimestampFormatter or equally, however I selected to call it otherwise for brevity.)
It’s fairly fundamental. We cross in an ISO 8601 timestamp in addition to a format (
dd.MM.yyyy), and it ought to return the formatted date.
So how does it look on Android?
We are going to make the most of the
java.time APIs, though it requires our Android minimal SDK to be 26 (you should use ThreeTen Backport or desugaring if you wish to use these APIs on decrease SDK variations).
The next needs to be positioned in
We’re parsing our timestamp utilizing the
ZonedDateTime API, and subsequently formatting it with our format through
Then how about iOS?
As a substitute of utilizing Java libraries, which aren’t accessible on iOS, we’ll as a substitute confer with the
Basis framework. It incorporates all of the issues we’d like for date formatting (and more, in fact).
Let’s put the next in
We create an occasion of
NSDateFormatter and set the time zone, locale, and format. Lastly, we invoke
stringFromDate() to get the formatted string.
You could ask — why not use the Swift APIs like
TimeZone , and so forth.? The TL;DR is that we’re unable to import any pure Swift modules from Kotlin code within the present state of KMM. Importing Goal-C APIs (
NS…), nonetheless, works simply high-quality. See this link for more information.
Let’s check it! ✅
As our assessments are platform-independent, it’s adequate to put them in
After we ask Android Studio to run the assessments, we’re requested to make use of a particular goal (relying on how our venture is configured):
Usually you’d select between
iosX64 . Operating both, we are able to see that the assessments cross:
If you happen to don’t need to run the assessments through Android Studio’s popup (or having to waste treasured time deciding on completely different choices in a popup, for that matter), you possibly can merely run the command
$ ./gradlew :shared:allTests which is able to execute all assessments within the venture throughout all potential targets.
Alright, cool, however I don’t actually need to write platform-dependent code if it may be prevented
Let’s see if we are able to keep away from that, then! The great individuals over at Kotlin/JetBrains created the
kotlinx-datetime library, which we’ll take a look at subsequent.
I like to recommend studying the documentation on the GitHub page for this library. As for our work, let’s get proper right down to it by including the dependency to our
commonMain supply set:
Now let’s use
LocalDateTime to search out the day, month, and 12 months from the timestamp, and eventually return the formatted date as a string:
zeroPrefixed()extension operate is one I created to bypass the truth that there’s no non-JVM
String.format()equal in Kotlin’s customary library at this moment, which might in any other case allow us to simply format integers as strings with prefixed zeros. You’ll find the code for
Write the assessments (why wouldn’t you?)
We checked out two approaches to writing date formatting logic that works on each Android and iOS.
Requiring platform-specific logic, the primary method allows us to make use of date time patterns/codecs straight. Nonetheless, we’re pressured to write down code that caters to every particular person platform.
Evidently, the method needing much less code is the latter. It depends on a third-party library that doesn’t at this moment help formatting varied date time patterns/codecs out of the field, which is why now we have to write down that half ourselves. On the intense facet, it’s a multiplatform library, and we don’t have to fret about any platform-specific APIs.
Hope you will have enjoyable coding in Kotlin for a number of platforms!