Initial commit - v1.1.9
This commit is contained in:
89
app/src/main/java/com/example/shiftalarm/ShiftCalculator.kt
Normal file
89
app/src/main/java/com/example/shiftalarm/ShiftCalculator.kt
Normal file
@@ -0,0 +1,89 @@
|
||||
package com.example.shiftalarm
|
||||
|
||||
import java.time.LocalDate
|
||||
import java.time.ZoneId
|
||||
import java.time.temporal.ChronoUnit
|
||||
|
||||
object ShiftCalculator {
|
||||
val SEOUL_ZONE: ZoneId = ZoneId.of("Asia/Seoul")
|
||||
val BASE_DATE: LocalDate = LocalDate.of(2026, 2, 1)
|
||||
|
||||
// Provided list has 20 items.
|
||||
// "석간 석간 석간 휴 휴" (5)
|
||||
// "주간 주간 주간 주간 주간 휴 휴" (7)
|
||||
// "야간 야간 야간 야간 야간 휴" (6)
|
||||
// "석간 석간" (2)
|
||||
// Total 20.
|
||||
val cycle = listOf(
|
||||
"석간", "석간", "석간", "휴무", "휴무",
|
||||
"주간", "주간", "주간", "주간", "주간", "휴무", "휴무",
|
||||
"야간", "야간", "야간", "야간", "야간", "휴무",
|
||||
"석간", "석간"
|
||||
)
|
||||
|
||||
val CYCLE_LENGTH = cycle.size
|
||||
|
||||
val TEAM_OFFSETS = mapOf(
|
||||
"A" to 0,
|
||||
"B" to 15,
|
||||
"C" to 10,
|
||||
"D" to 5
|
||||
)
|
||||
|
||||
fun getShift(date: LocalDate, team: String, factory: String = "Jeonju"): String {
|
||||
return when (factory) {
|
||||
"Nonsan" -> calculateNonsanShift(date, team)
|
||||
else -> calculateJeonjuShift(date, team)
|
||||
}
|
||||
}
|
||||
|
||||
private fun calculateJeonjuShift(date: LocalDate, team: String): String {
|
||||
val teamOffset = TEAM_OFFSETS[team] ?: 0
|
||||
val days = ChronoUnit.DAYS.between(BASE_DATE, date).toInt()
|
||||
val index = Math.floorMod(days + teamOffset, CYCLE_LENGTH)
|
||||
return cycle[index]
|
||||
}
|
||||
|
||||
private fun calculateNonsanShift(date: LocalDate, team: String): String {
|
||||
// Nonsan Factory Logic
|
||||
// Mon-Fri: Work, Sat-Sun: Rest (Off) -> "휴무"
|
||||
// Base Date: 2026-02-09 (Monday)
|
||||
// Groups: A, B, C
|
||||
// User Requirement (Step 145):
|
||||
// Feb 9 week: Day (주간)
|
||||
// Feb 16 week: Night (야간)
|
||||
// Feb 23 week: Evening (석간)
|
||||
// Cycle: Day -> Night -> Evening
|
||||
|
||||
val dayOfWeek = date.dayOfWeek.value // 1=Mon, ..., 7=Sun
|
||||
if (dayOfWeek >= 6) return "휴무" // Sat, Sun is OFF
|
||||
|
||||
// Base Date: 2026-02-09 (Monday)
|
||||
val baseDateNonsan = LocalDate.of(2026, 2, 9)
|
||||
|
||||
// Calculate days between Monday of the target date and base date
|
||||
// To be safe for "Any date before", we align target date to its Monday
|
||||
val targetMonday = date.minusDays((dayOfWeek - 1).toLong()) // Align to Monday
|
||||
val daysDiff = ChronoUnit.DAYS.between(baseDateNonsan, targetMonday).toInt()
|
||||
val weeksPassed = daysDiff / 7
|
||||
|
||||
// Rotation Pattern: 주간 -> 야간 -> 석간
|
||||
// Index: 0=주간, 1=야간, 2=석간
|
||||
val rotation = listOf("주간", "야간", "석간")
|
||||
|
||||
// Start indices for 2026-02-09 (Week 0)
|
||||
// A: 주간 (0) -> Matches User Specification
|
||||
// B, C: Distributed to other shifts.
|
||||
// Assuming A=0(Day), B=1(Night), C=2(Evening)
|
||||
|
||||
val startOffset = when (team) {
|
||||
"A" -> 0 // 주간
|
||||
"B" -> 1 // 야간
|
||||
"C" -> 2 // 석간
|
||||
else -> 0
|
||||
}
|
||||
|
||||
val currentIndex = Math.floorMod(startOffset + weeksPassed, 3)
|
||||
return rotation[currentIndex]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user