Android(Kotlin)で ZonedDateTime を使う
September 18, 2020
はじめに
日時処理をまあまあ記述しなければいけない場合、java.util.Calendar
しか使えないのは(使いづらくて)辛いなーと思います。java.time.ZonedDateTime
で代替できそうなので試してみます。
実装内容
概要
- デフォルトでは使えない
java.time.ZonedDateTime
を使えるようにする - 現時刻を
java.util.Calendar
とjava.time.ZonedDateTime
で取得 - それぞれ同形式で表示
- それぞれの UNIX 時間をミリ秒で表示
詳細
app/build.gradle
こちらに従い、
アプリの最小 API レベルを気にせずに java.time
を使えるようにします。
@@ -22,6 +22,12 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
+
+ compileOptions {
+ coreLibraryDesugaringEnabled true
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
}
dependencies {
@@ -32,5 +38,6 @@ dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
+ coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10'
}
app/src/main/java/com/example/myapplication/MainActivity.kt
ZonedDateTime
と Calendar
、それぞれで簡単な動作確認してみました。
ZonedDateTime
のクラス名からわかる通り、内部的にタイムゾーンを保有しており、
Calendar
同様、簡単に UNIX 時間を取得できます。
ちなみに Calendar
の timeInMillis
メソッドは結構使うので、ZonedDateTime
にも拡張メソッドとして timeInMillis
を用意して試してみました。
package com.example.myapplication
import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import java.text.SimpleDateFormat
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
import java.util.*
class MainActivity : AppCompatActivity(R.layout.activity_main) {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val zonedDateTime = ZonedDateTime.now()
val calendar = Calendar.getInstance()
val pattern = "yyyy/MM/dd HH:mm:ss.SSS"
val locale = Locale.JAPAN
val dateTimeFormatter = DateTimeFormatter.ofPattern(pattern, locale)
val simpleDateFormat = SimpleDateFormat(pattern, locale)
findViewById<TextView>(R.id.textViewZonedDateTimeFormat).apply {
text = dateTimeFormatter.format(zonedDateTime)
}
findViewById<TextView>(R.id.textViewZonedDateTimeTimeInMillis).apply {
text = zonedDateTime.timeInMillis.toString()
}
findViewById<TextView>(R.id.textViewCalendarFormat).apply {
text = simpleDateFormat.format(calendar.time)
}
findViewById<TextView>(R.id.textViewCalendarTimeInMillis).apply {
text = calendar.timeInMillis.toString()
}
}
}
val ZonedDateTime.timeInMillis: Long
get() = toInstant().toEpochMilli()
app/src/main/res/layout/activity_main.xml
特筆すべき点はありません。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:id="@+id/textViewZonedDateTimeFormat"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/textViewZonedDateTimeTimeInMillis"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/textViewCalendarFormat"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/textViewCalendarTimeInMillis"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
おわりに
開発では、本記事で触れていないメソッドも使ったりしていますが、
「java.util.Calendar
は使わずに、java.time.ZonedDateTime
使う」
で良さそうですね。