Island Time 0.2.0 is out
Tags: kotlin, kotlinmultiplatform, android, ios
Published: 2020-03-12 03:20:51

I'm pleased to announce that Island Time 0.2.0 is now available. If you're not familiar with [Island Time](https://github.com/erikc5000/island-time), you might want to first check out [this](https://dev.to/erikc5000/introducing-island-time-a-kotlin-multiplatform-library-for-working-with-dates-and-times-46jn) introductory post. In summary, it lets you write date and time code that'll run on the JVM, Android, iOS, and all other Apple platforms while offering a nice Kotlin API that's heavily inspired by the java.time library.

In addition to support for Kotlin 1.3.70, a number of new features have been added -- and bugs squashed. You can find the full release notes [here](https://github.com/erikc5000/island-time/releases/tag/0.2.0), but I'll run through some of the notable features and talk a little about where things are going.

##Locale support

The biggest new feature is support for localized text and week definitions.

While most platforms these days are using data from the [Unicode CLDR](http://cldr.unicode.org/) under the hood, what version they're using and how much of it is exposed through their APIs varies considerably. Island Time attempts to provide a common interface to these platform APIs while also giving you the flexibility to use data from different sources or customize the behavior where needed via `DateTimeTextProvider` and `TimeZoneTextProvider` interfaces.

####Localized text

It's now possible to access the localized names of months, days of the week, time zones, and more.

```kotlin
// Get the system default locale. We'll assume this is "en_US".
val locale = defaultLocale()

// "Feb"
val shortMonthName = Month.FEBRUARY.localizedName(TextStyle.SHORT_STANDALONE, locale)

// "Eastern Daylight Time"
val tzName = TimeZone("America/New_York").displayName(TimeZoneTextStyle.DAYLIGHT, locale)
```

For applicable classes, you'll find a `localizedName()` method that returns `null` if text is unavailable for the provided style and locale. And then a `displayName()` method that will instead return a default value if localized text is unavailable, such as the month or day of week number.

Island Time's `Locale` is simply a typealias for `java.util.Locale` or `NSLocale`. The `defaultLocale()` method allows you to access the system default locale in common code. If you want to use a specific locale, you should create it in platform-specific code and inject it.

You can also parse localized text, though results may vary between different platforms and versions -- and writing locale-agnostic parsers is non-trivial, so please be mindful of that. While it can be useful in some situations (which is why this feature is available), it should be avoided where possible.

```kotlin
val customParser = dateTimeParser {
    localizedMonth(setOf(TextStyle.SHORT, TextStyle.LONG))
    +' '
    dayOfMonth()
    +", "
    year()
}

val date: Date = "Feb 29, 2020".toDate(customParser) // 2020-02-29
```

####Localized week definitions

In addition to localized text, there's also support for localized week definitions. Depending on the locale, the week might start on Sunday, Monday, or Saturday -- and some platforms, such as macOS and iOS, allow the user to customize this independently from the locale settings.

A `WeekSettings` class has been introduced to provide control over this behavior when using week-related methods. `WeekSettings.systemDefault()` will usually be the most desirable construction method since it respects the user's system settings.

```kotlin
// Start of ISO week (Monday start)
val isoStart = Date.now().startOfWeek

// Start of week using Sunday as start
val sundayStart = Date.now().startOfWeek(WeekSettings.SUNDAY_START)

// Respect the user's system settings
val systemStart = Date.now().startOfWeek(WeekSettings.systemDefault())

// Use the default associated with a particular locale
val localeStart = Date.now().startOfWeek(explicitLocale)
```

##Week range/interval operators

New operators have also been added to make it easier to get the range of the week from a date or date-time. As an example, you could obtain an interval between the starting and ending instants of a week by doing the following:

```kotlin
// Get the date range of the current week
val weekRange: DateRange = Date.now().weekRange(WeekSettings.systemDefault())

// Convert it into the interval between the starting and ending instants of that week
val weekInterval: InstantInterval = weekRange.toInstantIntervalAt(TimeZone.systemDefault())
```

##Serializers for Kotlin Serialization

The serialization-extensions artifact provides a set of custom serializers ready to use with [kotlinx.serialization](https://github.com/Kotlin/kotlinx.serialization). These will allow you to serialize all date-time primitives, durations, and ranges as ISO-compatible strings, well-suited for JSON.

```kotlin
@Serializable
data class MyDto(
    val name: String,
    @Serializable(with = DateRangeSerializer::class) val dateRange: DateRange
)
```

##Parcelers for `@Parcelize` in the Kotlin Android Extensions

Similarly, the parcelize-extensions artifact provides a set of custom parcelers ready to use with the [`Parcelable` implementation generator](https://kotlinlang.org/docs/tutorials/android-plugin.html#parcelable-implementations-generator) provided by the Kotlin Android Extensions.

```kotlin
@Parcelize
@TypeParceler<Date, DateParceler>()
data class MyParcelable(
    val name: String,
    val date: Date
) : Parcelable

@Parcelize
@TypeParceler<Date?, NullableDateParceler>()
data class MyParcelableWithNull(
    val name: String,
    val date: Date?
) : Parcelable
```

##Future directions

At KotlinConf, JetBrains announced that they're working on their own date-time library. At this time, it's unclear what the feature set will look like and when it'll be ready.

Island Time is quite usable today and will continue to live on for the foreseeable future, serving as an alternative that will perhaps better satisfy certain needs. A number of new features and enhancements are in the pipeline already and will be making their way out in the coming months, including support for custom date-time formats. Stay tuned and coronavirus-free.