LoginSignup
2
1

More than 1 year has passed since last update.

【Scala, Java】LocalDateから月の第何週かを取得する

Last updated at Posted at 2021-12-27

java.time.temporal.WeekFields#weekOfMonth を使うことで、指定日が月の第何週にあたるかを取得できる。
週の始まりを日曜日とするか月曜日とするかも指定できる。

このカレンダーを例とする。

𝙳𝙴𝙲𝙴𝙼𝙱𝙴𝚁 – 𝟸𝟶𝟸𝟷
𝚂𝚞|𝙼𝚘|𝚃𝚞|𝚆𝚎|𝚃𝚑|𝙵𝚛|𝚂𝚊
𝚡𝚡|𝚡𝚡|𝚡𝚡|𝟶𝟷|𝟶𝟸|𝟶𝟹|𝟶𝟺
𝟶𝟻|𝟶𝟼|𝟶𝟽|𝟶𝟾|𝟶𝟿|𝟷𝟶|𝟷𝟷
𝟷𝟸|𝟷𝟹|𝟷𝟺|𝟷𝟻|𝟷𝟼|𝟷𝟽|𝟷𝟾
𝟷𝟿|𝟸𝟶|𝟸𝟷|𝟸𝟸|𝟸𝟹|𝟸𝟺|𝟸𝟻
𝟸𝟼|𝟸𝟽|𝟸𝟾|𝟸𝟿|𝟹𝟶|𝟹𝟷|𝚡𝚡

カレンダーはこちらを使わせていただきました。
https://qwerty.dev/calendar-generator/

実装

週の始まりを日曜日とするなら

val date = LocalDate.of(2021, 12, 26) 
val weekField = WeekFields.SUNDAY_START.weekOfMonth()

println(date.get(weekField)) // -> 5

週の始まりを月曜日とするなら

val date = LocalDate.of(2021, 12, 26)
val weekFieldMondayStart = WeekFields.of(DayOfWeek.MONDAY, 1).weekOfMonth()

println(date.get(weekFieldMondayStart)) // -> 4

解説

ここで使っている WeekFields.of() は第1引数に「週の始まりとする曜日」、第2引数に「何日以上あれば最初の週とみなすか」を指定する。
WeekFields.of(DayOfWeek.MONDAY, 1) なら週の始まりは月曜日、1日以上あれば最初の週とする。
WeekFields.SUNDAY_STARTWeekFields に定義されている定数で、内部的には WeekFields.of(DayOfWeek.SUNDAY, 1)

「何日以上あれば最初の週とみなすか」ってどういうこと?

「何日以上あれば最初の週とみなすか」が指定できるのは、ISO-8601のような定義に対応するためらしい。

日時のフォーマットを定義しているISO-8601では、4日以上ある週じゃないと最初の週と見なされない。(ちなみにISO-8601では週の始まりは月曜日)

例を挙げる。
2021年12月1日は水曜日なので、日曜日までに5日ある。よって2021年12月1日は第1週である。
2022年1月1日は土曜日なので、日曜日までに2日しかない。この場合、2022年1月3日(月)からが第1週となる

実際にISO-8601の定義に従った WeekFields で確認してみる。

val date = LocalDate.of(2022, 1, 1)
val weekField = WeekFields.of(DayOfWeek.MONDAY, 4).weekOfMonth() // ISO-8601の定義

println(date.get(weekField)) // -> 0

このように、最初の週以前の日付は第0週として扱われる。
(なお、WeekFields にはISO-8601に合わせた定数である ISO が用意されているので、自分でコーディングする必要はない)

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1