Skip to content

fix(filter)!: keep a short time fraction and read the zone after the fraction - #144

Closed
pdevito3 wants to merge 1 commit into
mainfrom
fm/qk-breaking-time-fraction
Closed

pdevito3 wants to merge 1 commit into
mainfrom
fm/qk-breaking-time-fraction

Conversation

@pdevito3

@pdevito3 pdevito3 commented Oct 1, 2026

Copy link
Copy Markdown
Owner

For later consideration in a major version. Do not merge now. #134 restored the v1.14.2 fraction rules to keep v1.x compatible (restore commit b49ad2b). This PR re-applies the break parts of 5c84ef6. The captain decides on this PR separately.

Summary

  • DateTimeFormatParser reads the zone only after the fraction: date, time, fraction, zone.
  • A quoted TimeOnly value keeps every fraction digit, like an unquoted value. The rightIsQuotedLiteral argument of CreateRightExpr is removed, because no other code uses it there.

v1.14.2 behavior (and main)

  • The date and time parser accepts the zone before the fraction: 2024-01-15T08:00:00Z.5 parses.
  • A quoted time uses the milliseconds only when the fraction has 3 or more digits, and the microseconds only when it has 6 or more. "08:30:00.5" and "08:30:00.50" compare with 08:30:00.

New behavior

  • The zone comes after the fraction, like ISO 8601. An unquoted value with the zone before the fraction throws ParsingException.
  • A quoted time keeps its fraction: "08:30:00.5" is 08:30:00 and 500 milliseconds.

Main already accepts these and they do not change: a fraction before the zone, 7 fraction digits, an unquoted time fraction, and a time list.

Example

FilterParser.ParseFilter<TestingPerson>("""Time == "08:30:00.5" """);
FilterParser.ParseFilter<TestingPerson>("SpecificDateTime == 2024-01-15T08:00:00Z.5");
  • v1.14.2 and main: the first filter matches 08:30:00, not 08:30:00.500. The second filter parses.
  • This PR: the first filter matches 08:30:00.500. The second filter throws ParsingException.

Justification

.5 is half a second. A filter that drops it gives wrong rows without an error. A zone before the fraction is not an ISO 8601 format, and the README shows only ISO 8601 values.

Migration

  • Write the zone after the fraction: 2024-01-15T08:00:00.5Z.
  • A caller that wrote a short fraction and expected the whole second must remove the fraction.

README

The date and time format list now tells that a time fraction keeps every digit, and that the zone comes after the fraction.

Tests

These tests come back from main before #134:

  • Unit FilterParsingRegressionTests.fractional_seconds_are_kept: the cases Time == "08:30:00.5" and Time == "08:30:00.50" expect the fraction again. The v1.14.2 cases Z.5, +02:00.500, and "08:30:00.500" are removed.
  • Unit quoted_time_with_fewer_than_three_fraction_digits_drops_the_fraction is removed. It held the v1.14.2 behavior.
  • Integration FilterParsingRegressionTests.fractional_second_value_matches_by_its_fraction -> fractional_seconds_are_kept (Postgres, a quoted .5 matches the fraction row again).

New unit test: zone_before_the_fraction_throws (2 cases).

dotnet build: 0 warnings, 0 errors. dotnet test: 401 unit tests and 281 Postgres integration tests (Testcontainers) pass, 0 failures.

…fraction

A quoted time dropped a fraction with fewer than 3 digits, so Time == "08:30:00.5" compared with 08:30:00. The date and time parser also accepted the zone before the fraction, for example 2024-01-15T08:00:00Z.5. Keep every fraction digit of a quoted time, and read the zone only after the fraction, like ISO 8601.

BREAKING CHANGE: a quoted time with a fraction of 1 or 2 digits now keeps the fraction. An unquoted date and time value with the zone before the fraction now throws ParsingException.
@pdevito3

pdevito3 commented Oct 1, 2026

Copy link
Copy Markdown
Owner Author

This PR had two breaking changes. Two PRs replace it, one change in each PR:

I close this PR. The captain decides on each new PR separately.

@pdevito3 pdevito3 closed this Oct 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant