Skip to content

CompletedBuilder: Fix LocalDateTime cannot be cast to Instant#424

Open
sunkup wants to merge 4 commits into
mainfrom
423-dmfstaskbuilder-localdatetime-cannot-be-cast-to-instant
Open

CompletedBuilder: Fix LocalDateTime cannot be cast to Instant#424
sunkup wants to merge 4 commits into
mainfrom
423-dmfstaskbuilder-localdatetime-cannot-be-cast-to-instant

Conversation

@sunkup
Copy link
Copy Markdown
Member

@sunkup sunkup commented May 22, 2026

Fix ClassCastException in CompletedBuilder : DmfsTaskFieldBuilder when DmfsTaskBuilder.buildTask runs.

The exception users get is ClassCastException: LocalDateTime cannot be cast to Instant so must occur where code assumes Instant at runtime but gets LocalDateTime. DmfsTaskBuilder.buildTask loops over all fieldBuilders calling .build()` so the crash must be inside one of them.

StartTimeBuilder and DueBuilder use normalizedDate()?.toTimestamp(), but CompletedBuilder does not. It uses .date?.toEpochMilli() which works only on Instant (!), so any non-Instant temporal here causes exactly this exception.

Relevant changes made:

  • call completedAt?.normalizedDate()?.toTimestamp() in COMPLETED builder instead of completedAt?.date?.toEpochMilli().
  • Add a regression test which demonstrates the bug and ensures it does not come back

Also:

  • AndroidTimeUtils: Don't lose milliseconds in toTimestamp which was loosing milliseconds. Changed toInstant().epochSecond * 1000 to toInstant().toEpochMilli().

@sunkup sunkup linked an issue May 22, 2026 that may be closed by this pull request
@sunkup sunkup added the pr-bugfix Fixes something that isn't working (only used for PRs) label May 22, 2026
@sunkup sunkup self-assigned this May 22, 2026
@sunkup sunkup requested a review from Copilot May 22, 2026 09:01
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a runtime ClassCastException in the DMFS task mapping when building the COMPLETED field from iCalendar data by normalizing temporals before converting them to provider timestamps.

Changes:

  • Update CompletedBuilder to convert completedAt via normalizedDate() + toTimestamp() (instead of assuming Instant).
  • Add a regression test covering floating COMPLETED (timezone-less) date-times to ensure the builder does not crash and produces the expected timestamp.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
lib/src/main/kotlin/at/bitfire/synctools/mapping/tasks/builder/CompletedBuilder.kt Fixes COMPLETED timestamp generation by normalizing temporals and using the shared timestamp conversion helper.
lib/src/test/kotlin/at/bitfire/synctools/mapping/tasks/builder/CompletedBuilderTest.kt Adds a regression test for floating COMPLETED values to prevent reintroducing the crash.

@sunkup sunkup requested a review from cketti May 22, 2026 09:13
@sunkup sunkup marked this pull request as ready for review May 22, 2026 09:13
@sunkup sunkup changed the title 423 dmfstaskbuilder localdatetime cannot be cast to instant CompletedBuilder: Fix LocalDateTime cannot be cast to Instant May 22, 2026
@sunkup sunkup force-pushed the 423-dmfstaskbuilder-localdatetime-cannot-be-cast-to-instant branch 2 times, most recently from 0525080 to 0111b70 Compare May 22, 2026 12:31
@sunkup sunkup force-pushed the 423-dmfstaskbuilder-localdatetime-cannot-be-cast-to-instant branch from 0111b70 to a9ecfe7 Compare May 22, 2026 12:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr-bugfix Fixes something that isn't working (only used for PRs)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[DmfsTaskBuilder] LocalDateTime cannot be cast to Instant

2 participants