Add CalendarViewModel with ISO week calculation and month grid generation
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
2c0a63e930
commit
298631c8b5
@ -0,0 +1,76 @@
|
|||||||
|
package plus.rua.project
|
||||||
|
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import kotlinx.datetime.DatePeriod
|
||||||
|
import kotlinx.datetime.LocalDate
|
||||||
|
import kotlinx.datetime.TimeZone
|
||||||
|
import kotlinx.datetime.daysUntil
|
||||||
|
import kotlinx.datetime.minus
|
||||||
|
import kotlinx.datetime.plus
|
||||||
|
import kotlinx.datetime.todayIn
|
||||||
|
import kotlin.time.Clock
|
||||||
|
|
||||||
|
data class CalendarDay(
|
||||||
|
val date: LocalDate,
|
||||||
|
val isCurrentMonth: Boolean,
|
||||||
|
val isToday: Boolean,
|
||||||
|
val isSelected: Boolean
|
||||||
|
)
|
||||||
|
|
||||||
|
class CalendarViewModel {
|
||||||
|
private val today: LocalDate = Clock.System.todayIn(TimeZone.currentSystemDefault())
|
||||||
|
|
||||||
|
var selectedDate by mutableStateOf(today)
|
||||||
|
private set
|
||||||
|
|
||||||
|
val currentYear: Int get() = selectedDate.year
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
val currentMonth: Int get() = selectedDate.monthNumber
|
||||||
|
|
||||||
|
fun selectDate(date: LocalDate) {
|
||||||
|
selectedDate = date
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getIsoWeekNumber(date: LocalDate): Int {
|
||||||
|
val jan4 = LocalDate(date.year, 1, 4)
|
||||||
|
val jan4DayOfWeek = jan4.dayOfWeek.ordinal
|
||||||
|
val week1Monday = jan4.minus(DatePeriod(days = jan4DayOfWeek))
|
||||||
|
val diff = week1Monday.daysUntil(date)
|
||||||
|
val weekNumber = diff / 7 + 1
|
||||||
|
return if (weekNumber < 1) {
|
||||||
|
getIsoWeekNumber(LocalDate(date.year - 1, 12, 28))
|
||||||
|
} else if (weekNumber > getIsoWeeksInYear(date.year)) {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
weekNumber
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getIsoWeeksInYear(year: Int): Int {
|
||||||
|
val dec28 = LocalDate(year, 12, 28)
|
||||||
|
val jan4 = LocalDate(year, 1, 4)
|
||||||
|
val jan4DayOfWeek = jan4.dayOfWeek.ordinal
|
||||||
|
val week1Monday = jan4.minus(DatePeriod(days = jan4DayOfWeek))
|
||||||
|
val diff = week1Monday.daysUntil(dec28)
|
||||||
|
return diff / 7 + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
fun getMonthDays(year: Int, month: Int): List<CalendarDay> {
|
||||||
|
val firstOfMonth = LocalDate(year, month, 1)
|
||||||
|
val dayOfWeekOffset = firstOfMonth.dayOfWeek.ordinal
|
||||||
|
val startDate = firstOfMonth.minus(DatePeriod(days = dayOfWeekOffset))
|
||||||
|
|
||||||
|
return (0 until 42).map { i ->
|
||||||
|
val date = startDate.plus(DatePeriod(days = i))
|
||||||
|
CalendarDay(
|
||||||
|
date = date,
|
||||||
|
isCurrentMonth = date.monthNumber == month && date.year == year,
|
||||||
|
isToday = date == today,
|
||||||
|
isSelected = date == selectedDate
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user