From bde043c8fd1a076f44c402dd56c62d401afbfb16 Mon Sep 17 00:00:00 2001 From: feiyu02 <risaku@163.com> Date: 星期四, 27 三月 2025 17:29:48 +0800 Subject: [PATCH] 1. 新增卫星遥测网格热力图计算逻辑 --- src/main/kotlin/com/flightfeather/uav/common/utils/TimeUtil.kt | 155 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 138 insertions(+), 17 deletions(-) diff --git a/src/main/kotlin/com/flightfeather/uav/common/utils/TimeUtil.kt b/src/main/kotlin/com/flightfeather/uav/common/utils/TimeUtil.kt index 246b159..aa189e6 100644 --- a/src/main/kotlin/com/flightfeather/uav/common/utils/TimeUtil.kt +++ b/src/main/kotlin/com/flightfeather/uav/common/utils/TimeUtil.kt @@ -1,31 +1,152 @@ package com.flightfeather.uav.common.utils +import java.time.Duration +import java.time.LocalDateTime +import java.time.ZoneId import java.util.* +import kotlin.math.max +import kotlin.math.min /** * @author riku * Date: 2019/9/16 */ -class TimeUtil { +object TimeUtil { - companion object { - /** - * 鏄惁鏄浜屽ぉ鎴栨洿鏂扮殑鏃堕棿 - */ - fun isNextDay(oldTime: Date, newTime: Date): Boolean { - val oldC = Calendar.getInstance().apply { - time = oldTime - } - val newC = Calendar.getInstance().apply { - time = newTime - } - return when { - newC[Calendar.YEAR] > oldC[Calendar.YEAR] -> true - newC[Calendar.YEAR] == oldC[Calendar.YEAR] -> newC[Calendar.DAY_OF_YEAR] > oldC[Calendar.DAY_OF_YEAR] - else -> false - } + /** + * 鏄惁鏄浜屽ぉ鎴栨洿鏂扮殑鏃堕棿 + */ + fun isNextDay(oldTime: Date, newTime: Date): Boolean { + val oldC = Calendar.getInstance().apply { + time = oldTime + } + val newC = Calendar.getInstance().apply { + time = newTime + } + + return when { + newC[Calendar.YEAR] > oldC[Calendar.YEAR] -> true + newC[Calendar.YEAR] == oldC[Calendar.YEAR] -> newC[Calendar.DAY_OF_YEAR] > oldC[Calendar.DAY_OF_YEAR] + else -> false } } + /** + * 鑾峰彇鏌愭鏃堕棿鍦ㄦ瘡鏃ヤ腑鐨勬椂娈� + * "鍑屾櫒 0 - 6", "鏃╀笂 6 - 9", "涓婂崍 9 - 12", "涓崍 12 - 14", "涓嬪崍 14 - 17", "鍌嶆櫄 17 - 20", "澶滈棿 20 - 0" + * 褰撹繖娈垫椂闂磋法瓒婁簡鏃舵鏃讹紝鎸夌収60%鐨勬椂闂存墍鍦ㄦ椂娈典负鏈�缁堟椂娈碉紝鍚﹀垯閲囩敤鍚庝竴涓椂娈� + * @return 鏃舵鍜屾椂娈电殑璧锋鏃堕棿 <鏃舵, 寮�濮嬫椂闂�, 缁撴潫鏃堕棿> + */ + fun getDayTimeTag(start: Date, end: Date): Triple<String, Date, Date>? { + var sLocal = LocalDateTime.ofInstant(start.toInstant(), ZoneId.systemDefault()) + var eLocal = LocalDateTime.ofInstant(end.toInstant(), ZoneId.systemDefault()) + val duration = Duration.between(sLocal, eLocal) + if (duration.toDays() > 1) return null + if (duration.isNegative) { + val temp = sLocal + sLocal = eLocal + eLocal = temp + } + + val sDay = sLocal.dayOfMonth + val eDay = eLocal.dayOfMonth + val ranges = listOf( + Triple(0, 6, "鍑屾櫒"), Triple(6, 9, "鏃╀笂"), + Triple(9, 12, "涓婂崍"), Triple(12, 14, "涓崍"), + Triple(14, 17, "涓嬪崍"), Triple(17, 20, "鍌嶆櫄"), Triple(20, 24, "澶滈棿") + ) + val periodList = mutableListOf<Pair<Triple<String, Date, Date>, Long>>() + + if (sDay < eDay) { + val dayStart = sLocal.plusDays(1).withHour(0).withMinute(0).withSecond(0) + val firstRange = sLocal to dayStart + val secondRange = dayStart to eLocal + ranges.forEachIndexed { i, r -> + // 鍒ゆ柇鏃堕棿鑼冨洿鏄惁鍜岃鏃舵鏈変氦闆� + checkPeriodTime(firstRange.first, firstRange.second, r.first to r.second)?.let { + val t = firstRange.first.withMinute(0).withSecond(0) + periodList.add( + Triple( + r.third, + Date.from(t.withHour(r.first).atZone(ZoneId.systemDefault()).toInstant()), + if (r.second == 24) { + Date.from( + t.withHour(0).plusDays(1).minusSeconds(1) + .atZone(ZoneId.systemDefault()).toInstant() + ) + } else { + Date.from(t.withHour(r.second).atZone(ZoneId.systemDefault()).toInstant()) + } + ) to it.toMinutes() + ) + } + checkPeriodTime(secondRange.first, secondRange.second, r.first to r.second)?.let { + val t = secondRange.first.withMinute(0).withSecond(0) + periodList.add( + Triple( + r.third, + Date.from(t.withHour(r.first).atZone(ZoneId.systemDefault()).toInstant()), + if (r.second == 24) { + Date.from( + t.withHour(0).plusDays(1).minusSeconds(1) + .atZone(ZoneId.systemDefault()).toInstant() + ) + } else { + Date.from(t.withHour(r.second).atZone(ZoneId.systemDefault()).toInstant()) + } + ) to it.toMinutes() + ) + } + } + } else { + val range = sLocal to eLocal + ranges.forEachIndexed { i, r -> + // 鍒ゆ柇鏃堕棿鑼冨洿鏄惁鍜岃鏃舵鏈変氦闆� + checkPeriodTime(range.first, range.second, r.first to r.second)?.let { + val t = range.first.withMinute(0).withSecond(0) + periodList.add( + Triple( + r.third, + Date.from(t.withHour(r.first).atZone(ZoneId.systemDefault()).toInstant()), + if (r.second == 24) { + Date.from( + t.withHour(0).plusDays(1).minusSeconds(1) + .atZone(ZoneId.systemDefault()).toInstant() + ) + } else { + Date.from(t.withHour(r.second).atZone(ZoneId.systemDefault()).toInstant()) + } + ) to it.toMinutes() + ) + } + } + } + if (periodList.isEmpty()) return null + + periodList.sortByDescending { it.second } + val maxOne = periodList.first() + return maxOne.first + } + + private fun checkPeriodTime(start: LocalDateTime, end: LocalDateTime, hourRange: Pair<Int, Int>): Duration? { + return if (start.hour in hourRange.first..hourRange.second) { + Duration.between( + start, + end.withHour(min(hourRange.second, end.hour)).withMinute(0).withSecond(0) + ) + } else if (start.hour < hourRange.first && end.hour > hourRange.second) { + Duration.between( + start.withHour(hourRange.first).withMinute(0).withSecond(0), + end.withHour(hourRange.second).withMinute(0).withSecond(0), + ) + } else if (end.hour in hourRange.first..hourRange.second) { + Duration.between( + start.withHour(max(hourRange.first, start.hour)).withMinute(0).withSecond(0), + end, + ) + } else { + null + } + } } \ No newline at end of file -- Gitblit v1.9.3