pcp: время — сквозной naive LocalDateTime как локальное настенное время (без UTC)

Отказ от остаточной UTC-семантики: naive LocalDateTime трактуется как
локальное время единой зоны всех сервисов.

Backend (границы внешних систем):
- VisibilityPayloadParser, SyncSpacecraftFromNsiUseCase: ZoneOffset.UTC →
  ZoneId.systemDefault() для проекции внешних Instant/ISO-с-Z в naive.
- тесты границ перевёрнуты на systemDefault (под Europe/Moscow ждут +3).
- чистка UTC-формулировок в DTO-комментариях, мёртвых ссылок на
  docs/standards/DATETIME_UTC.md.

Frontend (pcp-tgu-ops-ui):
- utils/utcTime.ts → utils/localTime.ts: parseLocal/formatLocal*/toLocalIso/
  toLocalInputValue с локальной семантикой (без дописывания Z и timeZone:UTC).
- замена getUTC*/Date.UTC/toISOString-сериализации на локальные аналоги.
- убраны пользовательские подписи «UTC» в редакторе/таймлайне.
- удалён utcTime.guard.test.ts (форсил обратный UTC-инвариант); тест-фикстуры
  сделаны зоно-независимыми. tsc + vitest зелёные под TZ=UTC и TZ=Europe/Moscow.

Включает также прочие незакоммиченные правки рабочего дерева.
This commit is contained in:
Дмитрий Соловьев
2026-06-04 09:50:39 +03:00
parent 5049395911
commit 294b17757d
123 changed files with 556 additions and 535 deletions
@@ -13,7 +13,6 @@ import jakarta.persistence.Table
import space.nstart.pcp.pcp_types_lib.dto.ballistics.AscNodeDTO
import space.nstart.pcp.pcp_types_lib.dto.ballistics.KeplersDTO
import java.time.LocalDateTime
import java.time.ZoneOffset
import kotlin.math.PI
@@ -27,7 +26,7 @@ class AscNodeEntity(
@Column(nullable = false)
val satelliteId : Long = 0,
@Column(name = "t", nullable = false)
val time : LocalDateTime = LocalDateTime.now(ZoneOffset.UTC),
val time : LocalDateTime = LocalDateTime.now(),
@Column(nullable = false)
val revolution : Long = 0,
val longitude : Double = 0.0,
@@ -10,7 +10,6 @@ import jakarta.persistence.Table
import space.nstart.pcp.pcp_types_lib.dto.ballistics.RevolutionSign
import space.nstart.pcp.pcp_types_lib.dto.ballistics.SquareViewParamDTO
import java.time.LocalDateTime
import java.time.ZoneOffset
import kotlin.math.PI
@Entity
@@ -27,13 +26,13 @@ class EarthCellViewsEntity(
@Column(name = "rev_begin", nullable = false)
val revolutionBegin : Long = 0,
@Column(nullable = false)
val timeBegin : LocalDateTime = LocalDateTime.now(ZoneOffset.UTC),
val timeBegin : LocalDateTime = LocalDateTime.now(),
@Column(nullable = false)
val revSignBegin : Int = 0,
@Column(name = "rev_end", nullable = false)
val revolutionEnd: Long = 0,
@Column(nullable = false)
val timeEnd : LocalDateTime = LocalDateTime.now(ZoneOffset.UTC),
val timeEnd : LocalDateTime = LocalDateTime.now(),
@Column(nullable = false)
val revSignEnd : Int = 0,
@Column(name = "roll_min")
@@ -9,7 +9,6 @@ import jakarta.persistence.GenerationType
import jakarta.persistence.Id
import jakarta.persistence.Table
import java.time.LocalDateTime
import java.time.ZoneOffset
@Entity
@Table(name = "earth_coverage")
@@ -23,9 +22,9 @@ class EarthCoverageEntity(
@Column(nullable = false)
val cellNumber : Long = 0,
@Column(nullable = false)
val tStart : LocalDateTime = LocalDateTime.now(ZoneOffset.UTC),
val tStart : LocalDateTime = LocalDateTime.now(),
@Column(nullable = false)
val tStop : LocalDateTime = LocalDateTime.now(ZoneOffset.UTC),
val tStop : LocalDateTime = LocalDateTime.now(),
) {
constructor(fl : FleghtLineSector, sector : Int, sat : Long) : this(
null,
@@ -6,7 +6,6 @@ import jakarta.persistence.*
import space.nstart.pcp.pcp_types_lib.dto.ballistics.FlightLineDTO
import space.nstart.pcp.pcp_types_lib.dto.ballistics.RevolutionSign
import java.time.LocalDateTime
import java.time.ZoneOffset
import kotlin.math.PI
@@ -20,7 +19,7 @@ class FlightLineEntity(
@Column(nullable = false)
val satelliteId : Long = 0,
@Column(name = "t", nullable = false)
val time : LocalDateTime = LocalDateTime.now(ZoneOffset.UTC),
val time : LocalDateTime = LocalDateTime.now(),
@Column(nullable = false)
val revolution : Long = 0,
@Column(nullable = false)
@@ -7,7 +7,6 @@ import ballistics.utils.toDateTime
import jakarta.persistence.*
import space.nstart.pcp.pcp_types_lib.dto.ballistics.OrbPointDTO
import java.time.LocalDateTime
import java.time.ZoneOffset
@Entity
@Table(name = "pdcm")
@@ -19,7 +18,7 @@ class PDCMEntity (
@Column(nullable = false)
val satelliteId : Long = 0,
@Column(name = "t", nullable = false)
val time : LocalDateTime = LocalDateTime.now(ZoneOffset.UTC),
val time : LocalDateTime = LocalDateTime.now(),
@Column(nullable = false)
val revolution : Long = 0,
val x: Double = 0.0,
@@ -13,7 +13,6 @@ import space.nstart.pcp.pcp_types_lib.dto.ballistics.MovementModel
import space.nstart.pcp.pcp_types_lib.dto.ballistics.OrbPointDTO
import space.nstart.pcp.pcp_types_lib.dto.ballistics.SatelliteICDTO
import java.time.LocalDateTime
import java.time.ZoneOffset
@Entity
@Table(name = "satellite_initial_conditions")
@@ -28,7 +27,7 @@ class SatelliteInitialConditionEntity(
@Column(name = "movement_model", nullable = false)
val movementModel: MovementModel = MovementModel.FOTO,
@Column(name = "orb_time", nullable = false)
val orbTime: LocalDateTime = LocalDateTime.now(ZoneOffset.UTC),
val orbTime: LocalDateTime = LocalDateTime.now(),
@Column(name = "orb_revolution", nullable = false)
val orbRevolution: Long = 0,
@Column(nullable = false)
@@ -48,7 +47,7 @@ class SatelliteInitialConditionEntity(
@Column(nullable = false)
val f81: Double = 147.8,
@Column(name = "received_at", nullable = false)
val receivedAt: LocalDateTime = LocalDateTime.now(ZoneOffset.UTC),
val receivedAt: LocalDateTime = LocalDateTime.now(),
@Column(name = "calculated_at")
var calculatedAt: LocalDateTime? = null,
@Column(name = "last_calculated", nullable = false)
@@ -69,7 +68,7 @@ class SatelliteInitialConditionEntity(
f81 = request.ic.f81
)
fun markLastCalculated(calculatedAt: LocalDateTime = LocalDateTime.now(ZoneOffset.UTC)) {
fun markLastCalculated(calculatedAt: LocalDateTime = LocalDateTime.now()) {
this.calculatedAt = calculatedAt
this.lastCalculated = true
}
@@ -63,7 +63,6 @@ import space.nstart.pcp.pcp_types_lib.dto.ballistics.TLEDTO
import space.nstart.pcp.pcp_types_lib.dto.ballistics.TargetPositionDTO
import tools.jackson.databind.ObjectMapper
import java.time.LocalDateTime
import java.time.ZoneOffset
import kotlin.collections.forEach
import kotlin.math.PI
import kotlin.math.abs
@@ -762,8 +761,8 @@ class SatelliteService {
fun getOrbPoints(id : Long, tn : LocalDateTime?, tk : LocalDateTime?) =
pdcmRepository.findBySatelliteIdAndTimeBetween(
id,
tn?: LocalDateTime.now(ZoneOffset.UTC),
tk?: LocalDateTime.now(ZoneOffset.UTC).plusDays(1))
tn?: LocalDateTime.now(),
tk?: LocalDateTime.now().plusDays(1))
.map { it.toDTO()
}
@@ -776,8 +775,8 @@ class SatelliteService {
fun getFL(id : Long, tn : LocalDateTime?, tk : LocalDateTime?, step : Double?) =
flightLineRepository.findBySatelliteIdAndTimeBetween(id,
tn?: LocalDateTime.now(ZoneOffset.UTC),
tk?: LocalDateTime.now(ZoneOffset.UTC).plusDays(1)
tn?: LocalDateTime.now(),
tk?: LocalDateTime.now().plusDays(1)
)
.map { it.toDTO() }
@@ -898,8 +897,8 @@ class SatelliteService {
return ascNodeRepository.findBySatelliteIdAndTimeBetween(
id,
tn ?: LocalDateTime.now(ZoneOffset.UTC),
tk ?: LocalDateTime.now(ZoneOffset.UTC).plusDays(1)
tn ?: LocalDateTime.now(),
tk ?: LocalDateTime.now().plusDays(1)
)
.map {
val keps = calculateKeplerParams(