メモです
例
以下のような文字列を
"2019-10-31T09:00:00+09:00"
以下のようなZonedDateTimeに変換する拡張関数
ZonedDateTime("2019-10-31T09:00:00+09:00")
実装
fun String?.toZonedDateTime(formatter: DateTimeFormatter = DateTimeFormatter.ISO_DATE_TIME): ZonedDateTime? {
if (this==null) return null
val result = kotlin.runCatching {
ZonedDateTime.parse(this, formatter)
}
if (result.isFailure) return null
return result.getOrNull()!!
}
ZonedDateTime.parseが失敗することも考慮してkotlin.runCatching
で処理してます。
DateTimeFormatterでフォーマット変更が可能にしています。
使い方
val date = "2019-12-31T23:59:59+09:00".toZonedDateTime()
文字列のフォーマット指定
unit testでの使用例
@Test
fun toZonedDateTime_Format_Test1() {
val expected = ZonedDateTime.parse("2019-12-31T23:59:59+09:00")
var actual = "2019/12/31T23:59:59+09:00".toZonedDateTime(DateTimeFormatter.ofPattern("yyyy/MM/dd'T'HH:mm:ssXXX"))
Assertions.assertThat(actual).isEqualTo(expected)
actual = "2019/12/31 23:59:59+09:00".toZonedDateTime(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ssXXX"))
Assertions.assertThat(actual).isEqualTo(expected)
actual = "20191231 235959+09:00".toZonedDateTime(DateTimeFormatter.ofPattern("yyyyMMdd HHmmssXXX"))
Assertions.assertThat(actual).isEqualTo(expected)
actual = "20191231 235959 JST".toZonedDateTime(DateTimeFormatter.ofPattern("yyyyMMdd HHmmss zzz"))
Assertions.assertThat(actual).isEqualTo(expected)
actual = "20191231235959JST".toZonedDateTime(DateTimeFormatter.ofPattern("yyyyMMddHHmmsszzz"))
Assertions.assertThat(actual).isEqualTo(expected)
}
タイムゾーンのフォーマットの切り替えが必要な場合
タイムゾーンの切り替え
//「同じ瞬間の別タイムゾーンの時刻に変えたい場合
val date = "2019-12-31T23:59:59+09:00".toZonedDateTime()?.withZoneSameInstant(ZoneId.of("America/Chicago"))
結果
2019-12-31T08:59:59-06:00[America/Chicago]
//「同じ時刻の別タイムゾーン」 に変えたい場合 (ローカル日付/時間を保持したまま、別のタイムゾーンを使う場合)
val date = "2019-12-31T23:59:59+09:00".toZonedDateTime()?.withZoneSameLocal(ZoneId.of("America/Chicago"))
結果
2019-12-31T23:59:59-06:00[America/Chicago]
@Test
fun toZonedDateTime_Change_Timezone_Test1() {
val dateString = "2019-12-31T23:59:59+09:00"
var expected = ZonedDateTime.parse("2019-12-31T08:59:59-06:00")
var actual = dateString.toZonedDateTime()?.withZoneSameInstant(ZoneId.of("America/Chicago"))
Assertions.assertThat(actual).isEqualTo(expected)
expected = ZonedDateTime.parse("2019-12-31T23:59:59-06:00")
actual = dateString.toZonedDateTime()?.withZoneSameLocal(ZoneId.of("America/Chicago"))
Assertions.assertThat(actual).isEqualTo(expected)
}