diff --git a/src/main/scala/fetch/lvgmc/OpenDataStationService.scala b/src/main/scala/fetch/lvgmc/OpenDataStationService.scala index b00f629..f36f6aa 100644 --- a/src/main/scala/fetch/lvgmc/OpenDataStationService.scala +++ b/src/main/scala/fetch/lvgmc/OpenDataStationService.scala @@ -11,7 +11,7 @@ import org.typelevel.log4cats.Logger import org.typelevel.log4cats.slf4j.Slf4jLogger import parse.csv.{WeatherData, WeatherStationData} -import java.time.LocalDateTime +import java.time.{LocalDateTime, ZoneId, ZoneOffset} import scala.util.Try object OpenDataStationService { @@ -27,6 +27,14 @@ object OpenDataStationService { final class OpenDataStationService private (logger: Logger[IO]) { private val pageSize = 5000 + // The open-data portal's DATETIME field is UTC (verified live against real + // clock time 2026-08-23); the private FTP feed's "Laiks" column is already + // Latvia local time with no conversion needed. Both write into the same + // weather.dateTime column, so this path converts to match — otherwise the + // two sources silently occupy two different, 2-3h-offset timelines in the + // same table instead of one. + private val rigaZone = ZoneId.of("Europe/Riga") + private val observationsUrl = sys.env.getOrElse( "LVGMC_OPENDATA_OBSERVATIONS_URL", "https://data.gov.lv/dati/api/3/action/datastore_search?resource_id=17460efb-ae99-4d1d-8144-1068f184b05f" @@ -113,7 +121,7 @@ final class OpenDataStationService private (logger: Logger[IO]) { city <- stationCities.get(stationId) abbreviation <- cursor.downField("ABBREVIATION").as[String].toOption datetimeStr <- cursor.downField("DATETIME").as[String].toOption - timestamp <- Try(LocalDateTime.parse(datetimeStr)).toOption + timestamp <- Try(LocalDateTime.parse(datetimeStr).atZone(ZoneOffset.UTC).withZoneSameInstant(rigaZone).toLocalDateTime).toOption value <- cursor.downField("VALUE").as[Double].toOption } yield ObservationCell(city, timestamp, abbreviation, value) }