例えば2026年2月
日 月 火 水 木 金 土
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
なら
[
1, 2, 3, 4, 5, 6, 7,
8, 9,10,11,12,13,14,
15,16,17,18,19,20,21,
22,23,24,25,26,27,28,
null,null,null,null,null,null,null,
null,null,null,null,null,null,null
]
という42個のリストを作ります。
データ生成関数
まずは日付だけ表示する版です。
private fun createCalendarCells(
year: Int,
month: Int
): List<Int?> {
val firstDay = LocalDate.of(year, month, 1)
val firstColumn =
firstDay.dayOfWeek.value % 7
val daysInMonth =
firstDay.lengthOfMonth()
val cells = mutableListOf<Int?>()
repeat(firstColumn) {
cells.add(null)
}
for (day in 1..daysInMonth) {
cells.add(day)
}
while (cells.size < 42) {
cells.add(null)
}
return cells
}
実際に生成されるデータ
例えば
createCalendarCells(2025, 9)
なら
[
null, 1, 2, 3, 4, 5, 6,
7, 8, 9,10,11,12,13,
14,15,16,17,18,19,20,
21,22,23,24,25,26,27,
28,29,30,null,null,null,null,
null,null,null,null,null,null,null
]
になります。
画面表示
42個を7列ずつ表示します。
val cells = createCalendarCells(
today.year,
today.monthValue
)
Column {
for (week in 0 until 6) {
Row {
for (day in 0 until 7) {
val value =
cells[week * 7 + day]
Button(
onClick = {},
modifier = Modifier.width(cellWidth)
) {
Text(
text = value?.toString() ?: ""
)
}
}
}
}
}
さらにおすすめ
日付だけではなく
data class CalendarCell(
val date: LocalDate?,
val isCurrentMonth: Boolean
)
を使います。
すると
CalendarCell(
date = LocalDate.of(2025, 9, 15),
isCurrentMonth = true
)
のように保持できます。
JSON保存
LocalDate は ISO-8601形式の文字列にできます。
val date = LocalDate.of(2026, 7, 13)
val str = date.toString()
結果
2026-07-13
JSON
{
"date": "2026-07-13"
}
この形式は
- 人間が読める
- ソートできる
- 復元が簡単
ので非常に便利です。
復元
val date = LocalDate.parse("2026-07-13")
だけです。
年月日の比較
例えば
val d1 = LocalDate.of(2026, 7, 13)
val d2 = LocalDate.of(2026, 7, 20)
なら
d1 == d2
d1.isBefore(d2)
d1.isAfter(d2)
が使えます。
年だけ比較
if (d1.year == d2.year) {
}
年月だけ比較
if (
d1.year == d2.year &&
d1.monthValue == d2.monthValue
) {
}
ただし後述する YearMonth の方がおすすめです。
月移動で便利な YearMonth
カレンダーでは
2026/07
だけを扱う場面が非常に多いです。
そんな時は
import java.time.YearMonth
val currentMonth = YearMonth.now()
を使います。
前月
currentMonth.minusMonths(1)
次月
currentMonth.plusMonths(1)
表示
currentMonth.format(
DateTimeFormatter.ofPattern("yyyy/MM")
)
その月の1日
val firstDay = currentMonth.atDay(1)
月末
val lastDay = currentMonth.atEndOfMonth()