■ はじめに
https://dk521123.hatenablog.com/entry/2023/03/08/000000
の続き。 今回は、Scala で、Joda-Time を使うことを扱う。
目次
【1】Joda-Time 1)使用上の注意 【2】インストール 【3】基本動作 0)現在時間 1)Datetime⇒文字列 2)文字列⇒Datetime 【4】期間クラス 1)Duration 2)Period 3)Interval 【5】サンプル 1)一日・末日 2)日付の比較
【1】Joda-Time
* 読み方は、ジョーダ・タイム(だと思う)
https://www.joda.org/joda-time/
より抜粋 ~~~~~~~~~ The standard date and time classes prior to Java SE 8 are poor. By tackling this problem head-on, Joda-Time became the de facto standard date and time library for Java prior to Java SE 8. ~~~~~~~~~
日本語訳
Java SE 8以前の標準日付・時刻クラスは貧弱である。 この問題に真正面から取り組むことで、 Joda-TimeはJava SE 8以前のJavaの事実上の標準日付・時刻ライブラリとなった。
1)使用上の注意
* 紹介しておいてなんなんだが、 標準的なDate and Time APIであるjava.time(JSR-310) を使った方がいいらしい
https://www.joda.org/joda-time/
より抜粋 ~~~~~~~~~ Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project. ~~~~~~~~~
日本語訳
Java SE 8以降では、 ユーザーは、java.time(JSR-310) -このプロジェクトを置き換えるJDKのコア部分- に移行するよう求められていることに注意されたい。
補足:java.time との絡みに関して
* 以下のような差があるらしい ~~~~ Joda-Timeとjava.timeでは書式文字列が 同じでもパース結果が異なる場合がある ~~~~
https://qiita.com/kijuky/items/136586048b4feceea04a
* Joda-Timeをjava.timeに移行に関しては以下。
https://ja.securecodewarrior.com/article/migrating-joda-time-to-java-time
【2】インストール
libraryDependencies ++= Seq( "joda-time" % "joda-time" % "2.12.7" )
https://mvnrepository.com/artifact/joda-time/joda-time
【3】基本動作
* 主なクラスは以下の通り。
org.joda.time.DateTime
https://www.joda.org/joda-time/apidocs/org/joda/time/DateTime.html
org.joda.time.format.DateTimeFormat
https://www.joda.org/joda-time/apidocs/org/joda/time/format/DateTimeFormat.html
0)現在時間
import org.joda.time.{DateTime, DateTimeZone} import org.joda.time.format.DateTimeFormat object Hello { def main(args: Array[String]): Unit = { // ★ここ val now = DateTime.now val datetimeFormat = DateTimeFormat.forPattern( "yyyyMMdd").withZone(DateTimeZone.UTC) println(datetimeFormat.print(now)) } }
1)Datetime⇒文字列
import org.joda.time.DateTime import org.joda.time.format.DateTimeFormat object Hello { def main(args: Array[String]): Unit = { val now = DateTime.now val datetimeFormat = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss") // 2024-07-22 16:25:06 println(datetimeFormat.print(now)) val datetimeFormat2 = DateTimeFormat.forPattern("yyyy-M-d h:mm:ss.SSS a").withLocale(Locale.UK) // 2024-7-22 4:25:06.931 pm println(datetimeFormat2.print(now)) } }
2)文字列⇒Datetime
import org.joda.time.format.DateTimeFormat import org.joda.time.{DateTime, DateTimeZone} object Hello { def main(args: Array[String]): Unit = { val targetDate = "2024-07-09" // Pattern-1: datetimeFormat.parseDateTime val datetimeFormat = DateTimeFormat.forPattern("yyyy-MM-dd") // 2024-07-09T00:00:00.000+09:00 println(datetimeFormat.parseDateTime(targetDate)) // 2024-07-08T15:00:00.000Z println(datetimeFormat.parseDateTime(targetDate).withZone(DateTimeZone.UTC)) // Pattern-2: DateTime.parse // 2024-07-08T15:00:00.000Z println(DateTime.parse(targetDate).withZone(DateTimeZone.UTC)) } }
【4】期間クラス
* Java の記事だが、以下が参考になる
https://shinsuke789.hatenablog.jp/entry/2013/08/06/195436
1)Duration
* 日時から日時分秒の差を扱うクラス
org.joda.time.Duration
https://www.joda.org/joda-time/apidocs/org/joda/time/Duration.html
2)Period
* 単純に年月日時分秒毎に日時の差を扱うクラス
org.joda.time.Period
https://www.joda.org/joda-time/apidocs/org/joda/time/Period.html
https://www.joda.org/joda-time/key_period.html
例1
import org.joda.time.{DateTime, Period} object Hello { def main(args: Array[String]): Unit = { val start = new DateTime("1977-10-10T00:00:00.000") val end = new DateTime("2024-07-10T00:00:00.000") val period = new Period(start, end) // 46 println(s"Year = ${period.getYears}") } }
例2
import org.joda.time.format.DateTimeFormat import org.joda.time.{DateTime, DateTimeZone, Period} object Hello { def main(args: Array[String]): Unit = { val dateTime = getDateTime("2005-07-09", "yyyy-MM-dd") // 2024-07-10 val now = DateTime.now() val age = getAge(dateTime, now) // 19 println(age) } private def getDateTime(inputValue: String, inputPattern: String): DateTime = { val format = DateTimeFormat.forPattern(inputPattern) format.parseDateTime(inputValue).withZone(DateTimeZone.UTC) } private def getAge(fromDateTime: DateTime, toDateTime: DateTime): Int = { // !!注目!! new Period(fromDateTime, toDateTime).getYears } }
3)Interval
* 2つの期間の差を扱うクラス
org.joda.time.Interval
https://www.joda.org/joda-time/apidocs/org/joda/time/Interval.html
overlap()
* 2つの期間の重なった範囲を確認することが可能
【5】サンプル
1)一日・末日
import org.joda.time.DateTime.now object Hello { def main(args: Array[String]): Unit = { val first = now.dayOfMonth().withMinimumValue() val end = now.dayOfMonth().withMaximumValue() // 2024-07-09 println(now.toString("yyyy-MM-dd")) // 2024-07-01 println(first.toString("yyyy-MM-dd")) // 2024-07-31 println(end.toString("yyyy-MM-dd")) } }
2)日付の比較
import org.joda.time.DateTime object Hello { def main(args: Array[String]): Unit = { // true println(isValid(new DateTime("2021-12-31T00:00:00.000"))) // false println(isValid(new DateTime("1899-12-31T00:00:00.000"))) // false println(isValid(new DateTime("2999-12-31T00:00:00.000"))) } private def isValid(target: DateTime): Boolean = { val minDate = new DateTime("1900-01-01T00:00:00.000") val maxDate = DateTime.now // ★ target.isAfter(minDate) && target.isBefore(maxDate) } }
補足:比較用メソッド
Method | Explanations |
---|---|
isAfter() | 対象日時が未来の場合 true |
isBefore() | 対象日時が過去の場合 true |
isEqual() | 対象日時が同じ場合 true |
参考文献
https://qiita.com/rubytomato@github/items/a9abb4f766e905c0c227
https://developers.cyberagent.co.jp/blog/archives/24735/
https://qiita.com/suin/items/db5963c2f5c8dddd417b
https://qiita.com/suin/items/2c111601b6501f4586f7
https://terasolunaorg.github.io/guideline/public_review/ArchitectureInDetail/Utilities/JodaTime.html
関連記事
Scala ~ 環境構築編 ~
https://dk521123.hatenablog.com/entry/2023/03/10/193805
Scala ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2023/03/12/184331
Scala ~ 基本編 / 繰り返し ~
https://dk521123.hatenablog.com/entry/2023/01/24/000000
Scala ~ 基本編 / コレクション ~
https://dk521123.hatenablog.com/entry/2023/03/13/000345
Scala ~ コレクションで使えるメソッド ~
https://dk521123.hatenablog.com/entry/2023/09/07/223422
Scala ~ mutable collection ~
https://dk521123.hatenablog.com/entry/2024/07/09/223730
Scala ~ 基本編 / 日付・日時 ~
https://dk521123.hatenablog.com/entry/2023/03/08/000000
Scala ~ 基本編 / 例外処理 ~
https://dk521123.hatenablog.com/entry/2023/10/05/000135
Scala ~ 基本編 / パターンマッチング ~
https://dk521123.hatenablog.com/entry/2023/06/06/233614