【Kotlin/Android Studio】現在の日付を取得する方法!DateTimeFormatterの使い方

この記事からわかること

  • Android Studio/Kotlin現在日付情報取得する方法
  • DateTimeFormatter使い方
  • yyyy/mm/dd形式種類
  • 日付→文字列文字列→日付(Date型)への変換
  • 日本時間元号を取得するには?
  • Calendarクラスの使い方

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

公式リファレンス:LocalDate

環境

現在の日付を取得する方法

Kotlinでは現在の日付や時間を取得するクラスがいくつか定義されています。それぞれに役割は異なりますがnowメソッドから取得できる点は変わりません。

val date = Date()
import java.time.LocalDate
import java.time.chrono.JapaneseDate
import java.time.LocalDateTime
import java.time.ZoneId
import java.time.ZonedDateTime

val date = Date()
val local = LocalDate.now()
val localTime = LocalDateTime.now()
val japan = JapaneseDate.now()
val zone = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"))
println(date)      // Sat Feb 17 00:41:41 UTC 2024
println(local)     // 2024-02-17
println(localTime) // 2024-02-17T00:41:41.172648120
println(japan)     // Japanese Reiwa 6-02-17
println(zone)      // 2024-02-17T09:41:41.193866743+09:00[Asia/Tokyo]

LocalDateTimeで9時間のズレが生じる原因

LocalDateTimeクラスで時間まで取得した場合printした時刻(9時でした)とオブジェクトの時刻では0時とAM 9時日時情報には誤差が生まれています。これはUTC(協定世界時)で日時情報を保持しているためであり、UTCと日本標準時(JTC)とは9時間ズレているため誤差が生まれてしまうのです。

文字列として出力するフォーマットを指定

公式:DateTimeFormatter

先ほどはデフォルトの形式のまま出力されていましたが、DateTimeFormatterクラスを使用することで任意の形式の文字列に変更することができます。フォーマットパターンはofPatternの引数に文字列で渡します。

val now = LocalDateTime.now()
val df = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss")
val fdate = df.format(now)
print(fdate) // 2023/07/24 10:40:52

表示されている日付情報が/区切りに変更になったことを確認できました。間の区切り文字に指定はないので日本語の年月日を指定することも可能です。

val now = LocalDateTime.now()
val df = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH時mm分ss秒")
val fdate = df.format(now)
print(fdate) // 2023年07月24日 11時04分39秒

日本時間で取得する

val now = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"))
val df = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH時mm分ss秒")
val fdate = df.format(now)
print(fdate) // 2023年07月24日 20時07分32秒

フォーマットパターンの種類

yyyy/MM/ddなどのフォーマットはあらかじめ指定されたシンボルを使用します。以下に公式サイトに載っていたものを抜粋したので参考にしてください。

Symbol 意味 Examples
G 元号 西暦; Anno Domini; A
u 2004; 04
y 元号の年 2004; 04
D 年内通算日 189
M/L 年内月 7; 07; 7月; 7月; J
d 月内通算日 10
g 修正ユリウス日 2451334
Q/q 四半期 3; 03; 第3四半期; 3rd quarter
Y 週ベースの年 1996; 96
w 週ベースの年内週 27
W 月内週 4
E 曜日 火; 火曜日; 火
e/c ローカライズされた曜日 2; 02; 火; 火曜日; 火
F 月内曜日番号 3
a 午前/午後 午後
h 午前/午後の時 (1-12) 12
K 午前/午後の時 (0-11) 0
k 1日の時 (1-24) 24
H 1日の時 (0-23) 0
m 30
s 55
S 秒以下の小数部分 978
A 1日のミリ秒 1234
n 秒以下のナノ秒 987654321
N 1日のナノ秒 1234000000

参考文献:公式:DateTimeFormatter

文字列からDate型への変換

日付→文字列」ではなく「文字列→日付」へ変換したい場合はLocalDateparseメソッドを使用します。引数には変換対象の文字列とそのフォーマットにあったDateTimeFormatterを渡します。

val formatter = DateTimeFormatter.ofPattern("yyyy年M月d日")
val dateStr = "2023年10月23日"
val day = LocalDate.parse(dateStr, formatter)
print(day)        // 2023-10-23
print(day::class) // class java.time.LocalDate (Kotlin reflection is not available)

DateTimeFormatterparseメソッドでも変換はできるようですがデータ型がParsedになるようです。

val formatter = DateTimeFormatter.ofPattern("yyyy年M月d日")
val dateStr = "2023年10月23日"
val day = formatter.parse(dateStr)
print(day)        // {},ISO resolved to 2023-10-23
print(day::class) // class java.time.format.Parsed (Kotlin reflection is not available)

文字列から時間込みのDate型への変換

時間も含めてパースしたい場合はLocalDateTimeを使用します。

val formatter = DateTimeFormatter.ofPattern("yyyy年M月d日 HH時mm分ss秒")
val dateStr = "2023年10月23日 10時20分30秒"
val day = LocalDateTime.parse(dateStr, formatter)
print(day)        // 2023-10-23T10:20:30

元号を取得する

元号を取得したい場合はJapaneseDateで取得したオブジェクトのeraプロパティから取得することが可能です。そのままではローマ字なのでgetDisplayNameメソッドの引数に表示するスタイルとロケールを指定すれば日本語で表示させることも可能です。

val japan = JapaneseDate.now()
val era = japan.era
print(era) // Reiwa
print(era.getDisplayName(TextStyle.FULL, Locale.JAPAN)) // 令和

スタイルは以下の通りですがFULLSHORTは日本の場合同じなのでFULLだけ使用すれば良さそうです。

定数 出力例
FULL 令和
FULL_STANDALONE 令和
NARROW R
NARROW_STANDALONE R
SHORT 令和
SHORT_STANDALONE 令和

元号n年形式で取得する

元号のみではなく「元号n年」形式で取得したい場合のが多いと思います。これはDateTimeFormatterを使用してGy年と指定することで取得することができます。

val df = DateTimeFormatter.ofPattern("Gy年", Locale.JAPAN)
val jpEra = df.format(JapaneseDate.now())
print(jpEra)  // 令和5年

西暦になってしまう場合

和暦で表示させたい場合はJapaneseDateオブジェクトに変換させる必要があります。これをしないと西暦で表示されてしまうので以下のように文字列から和暦のみを抽出したい場合は変換を繰り返して実装することになります。

val date = "1999年12月1日"
val formatter = DateTimeFormatter.ofPattern("yyyy年M月d日", Locale.JAPAN)
val birthday = LocalDate.parse(date, formatter)
val japanDay = JapaneseDate.from(birthday)
val df = DateTimeFormatter.ofPattern("Gy年", Locale.JAPAN)
val jpEra = df.format(japanDay)
print(jpEra)  // 平成11年

日付を引き算/足し算して⚪︎日前/後を取得する

日付を引き算/足し算して⚪︎日前/後を取得するにはminusDaysメソッドまたはplusDaysメソッドを使用します。

val now = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"))
val oneDayBefore = now.minusDays(1)
val oneDayAfter = now.plusDays(1)
print(now)           // 2023-10-28T23:43:12.217434296+09:00[Asia/Tokyo]
print(oneDayBefore)  // 2023-10-27T23:43:12.217434296+09:00[Asia/Tokyo]
print(oneDayAfter)   // 2023-10-29T23:43:12.217434296+09:00[Asia/Tokyo]

Calendarクラスから日時を1つずつ取得する

Calendarクラスを使用することで日時情報を1つ1つ取得することが可能です。ですが月のみ1ヶ月少ない数値が返ってくるので+1することで実際の月に合わせます。これは1月=02月=1という感じになっているからのようです。

val c = Calendar.getInstance()
val year = c.get(Calendar.YEAR)
val month = c.get(Calendar.MONTH)
val day = c.get(Calendar.DAY_OF_MONTH)   
val hour = c.get(Calendar.HOUR_OF_DAY)
val minute = c.get(Calendar.MINUTE)
val second = c.get(Calendar.SECOND)

print(year)         // 2023
print(month + 1 )   // 8
print(day)          // 3
print(hour)         // 12
print(minute)       // 32
print(second)       // 17

SimpleDateFormatでも日付の変換が可能

UNIX形式のタイムスタンプを取得する

timeプロパティから自身の日付と1970年1月1日の00:00:00 UTCとの間隔(UNIX)をLong型のミリ秒数で取得できます。ミリ秒数なので秒単位で取得したい場合は1000でわる必要があります。

val date = Date()
val unixTimeMilliSeconds: Long = date.time // 1710855741810
val unixTimeSeconds: Long = unixTimeMilliSeconds / 1000 // 1710855741

UNIX形式のタイムスタンプをDate型に戻す

UNIX形式のタイムスタンプ値はDate型に簡単に戻すことが可能です。この際にちゃんとミリ秒単位でLong型のタイムスタンプでないと正しく変換できないので注意してください。

var date = Date(unixTimeMilliSeconds)

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index