こんにちは、虎の穴ラボの磯江です。
虎の穴ラボ Advent Calendar 2020 - Qiita2日目の記事になります。
1日目は奥谷さんがNuxtの記事を書いているので、読んでみてください。
toranoana-lab.hatenablog.com
3日目は大場さんのSEOについての記事です。
qiita.com
今回はKotlinマルチプラットフォームに対応したDateTimeAPIとして「kotlinx-datetime」ライブラリを紹介します。
2020年12月「kotlinx-datetime」は実験的なライブラリです。今後、APIの内容は変更される可能性があります。
Kotlin/JVMで日時や日付を扱う場合、java.timeパッケージのLocalDateTimeやLocalDateを利用するのが一般的です。
import java.time.LocalDate import java.time.LocalDateTime fun main() { val currentDateTime: LocalDateTime = LocalDateTime.now() val currentDate: LocalDate = LocalDate.now() println("Current DateTime: $currentDateTime") println("Current Date: $currentDate") }
しかし、Kotlin/NativeやKotlin/JSではjava.timeAPIは利用できないため、プロジェクト毎に日付を扱うライブラリが異なるのが現状です。
そこで新しいDateTimeAPI「kotlinx-datetime」がKotlin1.4.0のリリースに合わせて公開されました。
プロジェクトに導入する
GradleとMavenを利用して「kotlinx-datetime」をプロジェクトに導入することができます。 2020年12月時点ではjCenterで公開されていないため、独自リポジトリを設定する必要があります。
Gradleを利用する場合
repositories { maven(url = "https://kotlin.bintray.com/kotlinx/") } dependencies { implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.1.1") }
※Kotlin/JSプラットフォームではデフォルトでSYSTEM
タイムゾーンのみ使用できます。すべてのタイムゾーンを利用したい場合はjs-jodaを利用する必要があります。
kotlin { sourceSets { val jsMain by getting { dependencies { implementation(npm("@js-joda/timezone", "2.3.0")) } } } }
Mevenを利用する場合
<repositories> <repository> <snapshots> <enabled>false</enabled> </snapshots> <id>kotlinx</id> <name>kotlinx</name> <url>https://kotlin.bintray.com/kotlinx/</url> </repository> </repositories> <dependencies> <dependency> <groupId>org.jetbrains.kotlinx</groupId> <artifactId>kotlinx-datetime-jvm</artifactId> <version>0.1.1</version> </dependency> </dependencies>
現在日時を取得する
import kotlinx.datetime.Clock fun main() { val currentMoment = Clock.System.now() println(currentMoment) // 2020-12-02T06:25:22.008Z }
Clock.System.now()
を呼び出すことでUTC(世界標準時)を取得できます。
タイムゾーンを指定した日時を取得する
import kotlinx.datetime.* fun main() { val currentMoment: Instant = Clock.System.now() val datetimeInUtc: LocalDateTime = currentMoment.toLocalDateTime(TimeZone.UTC) val datetimeInSystemZone: LocalDateTime = currentMoment.toLocalDateTime(TimeZone.currentSystemDefault()) println("LocalDateTimeInUTC:$datetimeInUtc") // LocalDateTimeInUTC:2020-12-02T06:57:16.812 println("LocalDateTimeInSystemZone:$datetimeInSystemZone") // LocalDateTimeInSystemZone:2020-12-12T15:57:16.812 }
先程利用したClock.System.now()
で取得したInstant
クラスのtoLocalDateTime
メソッドを利用することで、タイムゾーンを指定した日時(LocalDateTime
)に変換することができます。
任意のタイムゾーンを指定したい場合にはTimeZone
クラスを利用して、タイムゾーン指定を行います。
import kotlinx.datetime.* fun main() { val currentMoment: Instant = Clock.System.now() val tzBerlin = TimeZone.of("Europe/Berlin") val datetimeInBerlin = currentMoment.toLocalDateTime(tzBerlin) println("LocalDateTimeInBerlin:$datetimeInBerlin") // LocalDateTimeInBerlin:2020-12-02T08:57:11.125 }
任意の日時を取得する
import kotlinx.datetime.* fun main() { val kotlinReleaseDateTime = LocalDateTime(2016, 2, 15, 16, 57, 0, 0) println("KotlinReleaseDateTime:$kotlinReleaseDateTime") // KotlinReleaseDateTime:2016-02-15T16:57 }
LocalDateTime
クラスには年月日時分秒ミリ秒を指定可能なコンストラクタが用意されています。
また、String
クラスが拡張されており、ISO-8601形式で記述した日時の文字列をLocalDateTime
に変換することもできます。
import kotlinx.datetime.* fun main() { val dateTimeFromString = "2010-06-01T22:19:44".toLocalDateTime() println("DateTimeFromString:$dateTimeFromString") // DateTimeFromString:2010-06-01T22:19:44 }
現在日付を取得する
現在日付を取得するにはLocalDate
クラスを利用します。
import kotlinx.datetime.* fun main() { val today: LocalDate = Clock.System.todayAt(TimeZone.currentSystemDefault()) println("Today is $today") // Today is 2020-12-02 }
任意の日付を取得する
LocalDateTime
と同様にLocalDate
クラスにも年月日を指定可能なコンストラクタが用意されています。
import kotlinx.datetime.* fun main() { val knownDate = LocalDate(2020, 2, 21) println("KnownDate:$knownDate") // KnownDate:2020-02-21 }
ISO-8601形式で記述した日付の文字列をLocalDateT
に変換するString
の拡張メソッドもあります。
import kotlinx.datetime.* fun main() { val localDateFromString = "2010-06-01".toLocalDate() println("LocalDateFromString:$localDateFromString") // LocalDateFromString:2010-06-01 }
日時計算をする
LocalDateTime
クラスには日時計算用にplus
メソッドが用意されています。
import kotlinx.datetime.* fun main() { val now = Clock.System.now() val systemTZ = TimeZone.currentSystemDefault() val tomorrow = now.plus(1, DateTimeUnit.DAY, systemTZ) val threeYearsAndAMonthLater = now.plus(DateTimePeriod(years = 3, months = 1), systemTZ) println("Now:$now, Tomorrow:$tomorrow, ThreeYearsAndMonthLater:$threeYearsAndAMonthLater") // Now:2020-12-02T09:19:05.999Z, Tomorrow:2020-12-02T09:19:05.999Z, ThreeYearsAndMonthLater:2024-01-02T09:19:05.999Z }
期間を表すDateTimePeriod
クラスを利用した日付計算も可能です。
日付計算をする
LocalDate
クラスにもplus
メソッドが用意されています。
import kotlinx.datetime.* fun main() { val today = Clock.System.todayAt(TimeZone.currentSystemDefault()) val yesterday = today.plus(-1, DateTimeUnit.DAY) val threeYearsAndAMonthBefore = today.plus(DatePeriod(years = -3, months = -1)) println("Now:$today, Yesterday:$yesterday, ThreeYearsAndAMonthBefore:$threeYearsAndAMonthBefore") // Now:2020-12-02, Yesterday:2020-12-01, ThreeYearsAndAMonthBefore:2017-11-02 }
まとめ
- kotlinx-datetimeライブラリの最新バージョンはv0.1.1
- API変更の可能性があるのでプロダクトでの利用はまだ早い
- いつかはこのライブラリを利用するのがスタンダードになる(かも)
- 今のうちにチェックしておくと、正式リリース後の導入がスムーズに?