I'm converting some code from using Java 8's LocalDatetime
to using the version from kotlinx-datetime
and I can't find any formatting methods. Specifically, I'm replacing a FormatStyle.MEDIUM
. Do they not exist and I need to write the formatting?
This is for an Android app. Is there are there Android specific libraries I can use? Or can I do this with pre-Java 8 methods to maintain support for older versions of Android?
Edit: I posted my current solution as an answer. My requirements have changed since I asked this question. It also needs to support JVM and iOS. JS and localization are a big bonus. I'd like to see a solution that supports localization without using platform-specific code.
My current implementation utilizes expect
/actual
to support Java, iOS, and JS.
Common:
expect fun Instant.toDateTimeString(formatStyle: FormatStyle, timeZone: TimeZone = TimeZone.currentSystemDefault()): String
enum class FormatStyle {
SHORT,
MEDIUM,
LONG,
}
Java/Android:
actual fun Instant.toDateTimeString(formatStyle: FormatStyle, timeZone: TimeZone): String {
val javaFormatStyle = when (formatStyle) {
FormatStyle.SHORT -> java.time.format.FormatStyle.SHORT
FormatStyle.MEDIUM -> java.time.format.FormatStyle.MEDIUM
FormatStyle.LONG -> java.time.format.FormatStyle.LONG
}
val zonedTime = toJavaInstant().atZone(timeZone.toJavaZoneId())
val formatter = DateTimeFormatter.ofLocalizedDateTime(javaFormatStyle)
return formatter.format(zonedTime)
}
iOS:
actual fun Instant.toDateTimeString(formatStyle: FormatStyle, timeZone: TimeZone): String {
val nsFormatStyle = when (formatStyle) {
FormatStyle.SHORT -> NSDateFormatterShortStyle
FormatStyle.MEDIUM -> NSDateFormatterMediumStyle
FormatStyle.LONG -> NSDateFormatterLongStyle
}
val formatter = NSDateFormatter().apply {
dateStyle = nsFormatStyle
timeStyle = nsFormatStyle
}
return formatter.stringFromDate(toNSDate())
}
JS:
external val navigator: Navigator
actual fun Instant.toDateTimeString(formatStyle: FormatStyle, timeZone: TimeZone): String {
val locales = navigator.languages
val date = toJSDate()
val jsDate = Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds())
val options = when (formatStyle) {
FormatStyle.SHORT ->
DateTimeFormatOptions(
timeZone = timeZone.id,
dateStyle = DateStyle.short,
timeStyle = TimeStyle.short,
)
FormatStyle.MEDIUM ->
DateTimeFormatOptions(
timeZone = timeZone.id,
dateStyle = DateStyle.medium,
timeStyle = TimeStyle.medium,
)
FormatStyle.LONG ->
DateTimeFormatOptions(
timeZone = timeZone.id,
dateStyle = DateStyle.long,
timeStyle = TimeStyle.long,
)
}
val formatter = DateTimeFormat(locales, options)
return formatter.format(jsDate)
}