Skip to content

Instantly share code, notes, and snippets.

@hikaMaeng
Created August 21, 2025 03:47
Show Gist options
  • Save hikaMaeng/42338e8d4eaca3bce9a04b3180848748 to your computer and use it in GitHub Desktop.
Save hikaMaeng/42338e8d4eaca3bce9a04b3180848748 to your computer and use it in GitHub Desktop.
package kore.time
class DstRule(
val fromYear: Int,
val toYear: Int,
val startMonth: Int,
val startDayRule: String,
val startTimeSeconds: Int,
val endMonth: Int,
val endDayRule: String,
val endTimeSeconds: Int,
val saveSeconds: Int
)
@file:Suppress("NOTHING_TO_INLINE")
package kore.time
import kotlin.math.*
class ZoneInfo(
val area: String,
val countryCode: CountryCode,
val lat: Double,
val lon: Double,
val utcOffset:Int,
val periods: List<ZonePeriod>
){
init{
if(area !in zones) zones[area] = this else throw Throwable("Zone already exists: $area")
}
companion object{
private inline fun Double.rad(): Double = this * PI / 180.0
fun findClose(lat:Double, lon:Double): ZoneInfo?{
val candidates = zones.values
if (candidates.isEmpty()) return null
val latRad = lat.rad()
val cosLat = cos(latRad)
var best: ZoneInfo? = null
var bestD2 = Double.POSITIVE_INFINITY
for (z in candidates) {
val dLat = (z.lat - lat).rad()
var dLon = (z.lon - lon).rad()
// 날짜변경선 래핑: [-π, π]로 접기
if (dLon > PI) dLon -= 2 * PI
if (dLon < -PI) dLon += 2 * PI
// equirectangular 근사: x=Δλ·cos φ, y=Δφ
val x = dLon * cosLat
val d2 = x * x + dLat * dLat
if (d2 < bestD2) {
bestD2 = d2
best = z
}
}
return best
}
}
}
package kore.time
class ZonePeriod(
val stdOffsetSeconds: Int, // 표준 오프셋 (초)
val dstSaveSeconds: Int, // 서머타임 시 추가되는 시간 (초). 없으면 0.
val format: String, // 시간대 약어 (예: "EST", "E%sT")
val untilEpochSeconds: Long // 이 기간이 유효한 마지막 시점 (UTC 에포크 초)
)
package kore.time
internal val zones = hashMapOf<String, ZoneInfo>()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment