ITADN

Patch.Temporal for ZonedDateTimeType casts to LocalDate (ClassCastException)

#1098Openhaskiindahouse 创建于 2026-05-10
H
haskiindahousecommented
`Patch.Temporal.patch` has a `ZonedDateTimeType` case that's a copy-paste of the `LocalDateType` case — it casts the value to `LocalDate` and rebuilds via `LocalDate.ofEpochDay`. Applying such a patch to a `ZonedDateTime` throws `ClassCastException`. `Differ.zonedDateTime` produces `Patch.ZonedDateTime` (a separate case class), not `Patch.Temporal`, so this branch isn't hit by the standard diff path. It's reachable through direct construction of `Patch.Temporal(_, StandardType.ZonedDateTimeType)` and through deserialisation of patch data. Reproducer (scala-cli): ```scala //> using scala 3.8.3 //> using dep dev.zio::zio-schema::1.8.5 import zio.schema.* import java.time.* @main def repro(): Unit = val patch = Patch.Temporal(List(1L), StandardType.ZonedDateTimeType) try println(patch.patch(ZonedDateTime.now())) catch case e: ClassCastException => println(s"ClassCastException: ${e.getMessage}") // for contrast: the LocalDateType branch is fine val ok = Patch.Temporal(List(1L), StandardType.LocalDateType) println(ok.patch(LocalDate.now())) ``` Output: ``` ClassCastException: class java.time.ZonedDateTime cannot be cast to class java.time.LocalDate Right(...) <- LocalDate branch works ``` Source: https://github.com/zio/zio-schema/blob/f32240d525c45a702aaa40e9fb50f25011dc003a/zio-schema/shared/src/main/scala/zio/schema/Patch.scala#L107-L108 ```scala case (_: StandardType.ZonedDateTimeType.type, distance :: Nil) => Right(LocalDate.ofEpochDay(a.asInstanceOf[LocalDate].toEpochDay - distance).asInstanceOf[A]) ``` The neighbouring `LocalDateType` case (around line 178) is the obvious source of the copy. **Versions.** zio-schema 1.8.5, Scala 3.8.3. **Suggested fix.** Either delete the `Patch.Temporal` `ZonedDateTimeType` branch (the proper `Patch.ZonedDateTime` case class handles it correctly), or implement it using `Duration` arithmetic on `ZonedDateTime`. Happy to PR.
0 条评论