diff --git a/QueryKit.IntegrationTests/Tests/FilterParsingRegressionTests.cs b/QueryKit.IntegrationTests/Tests/FilterParsingRegressionTests.cs index 99bf6bd..346848a 100644 --- a/QueryKit.IntegrationTests/Tests/FilterParsingRegressionTests.cs +++ b/QueryKit.IntegrationTests/Tests/FilterParsingRegressionTests.cs @@ -143,7 +143,6 @@ public async Task date_time_offset_value_with_offset_matches_same_instant(string [Theory] [InlineData("SpecificDateTime == 2024-01-15T08:00:00.500Z", true)] - [InlineData("SpecificDateTime == 2024-01-15T08:00:00Z.5", true)] [InlineData("SpecificDate == 2024-01-15T10:00:00.5+02:00", true)] [InlineData("Time == 08:30:00.5", true)] [InlineData("Time == \"08:30:00.500\"", true)] diff --git a/QueryKit.UnitTests/FilterParsingRegressionTests.cs b/QueryKit.UnitTests/FilterParsingRegressionTests.cs index 8533635..d895455 100644 --- a/QueryKit.UnitTests/FilterParsingRegressionTests.cs +++ b/QueryKit.UnitTests/FilterParsingRegressionTests.cs @@ -137,8 +137,6 @@ public void enum_list_value_is_split_into_items() [InlineData("SpecificDateTime ^^ [2024-01-15T08:00:00.5Z]")] [InlineData("SpecificDate == 2024-01-15T10:00:00.5+02:00")] [InlineData("SpecificDate == 2024-01-15T08:00:00.5000000Z")] - [InlineData("SpecificDateTime == 2024-01-15T08:00:00Z.5")] - [InlineData("SpecificDate == 2024-01-15T10:00:00+02:00.500")] [InlineData("Time == 08:30:00.5")] [InlineData("Time == \"08:30:00.500\"")] [InlineData("Time ^^ [08:30:00.5]")] @@ -159,6 +157,16 @@ public void quoted_time_with_fewer_than_three_fraction_digits_drops_the_fraction result.Select(x => x.Title).Should().Equal("whole second"); } + [Theory] + [InlineData("SpecificDateTime == 2024-01-15T08:00:00Z.5")] + [InlineData("SpecificDate == 2024-01-15T10:00:00+02:00.500")] + public void zone_before_the_fraction_throws(string input) + { + var act = () => FilterParser.ParseFilter(input); + + act.Should().Throw(); + } + private static TestingPerson[] FractionalSecondPeople() => new[] { new TestingPerson diff --git a/QueryKit/FilterParser.cs b/QueryKit/FilterParser.cs index 07ead9d..978acdb 100644 --- a/QueryKit/FilterParser.cs +++ b/QueryKit/FilterParser.cs @@ -247,14 +247,12 @@ private static readonly Parser DoubleQuoteParser private static readonly Parser DateTimeTimeParser = Parse.Regex(@"T\d{2}:\d{2}:\d{2}").Text().Optional().Select(x => x.GetOrElse("")); private static readonly Parser DateTimeMicrosParser = Parse.Regex(@"\.\d{1,7}").Text().Optional().Select(x => x.GetOrElse("")); private static readonly Parser DateTimeZoneParser = Parse.Regex(@"Z|[+-]\d{2}(:\d{2})?").Text().Optional().Select(x => x.GetOrElse("")); - // v1.14.2 read the zone before the fraction, so 2022-07-01T00:00:02Z.5 is a valid value. A zone after the fraction is also valid. private static readonly Parser DateTimeFormatParser = from dateFormat in Parse.Regex(@"\d{4}-\d{2}-\d{2}").Text() from timeFormat in DateTimeTimeParser - from zoneBeforeMicros in DateTimeZoneParser from micros in DateTimeMicrosParser - from zoneAfterMicros in zoneBeforeMicros == "" ? DateTimeZoneParser : Parse.Return("") - select dateFormat + timeFormat + micros + zoneBeforeMicros + zoneAfterMicros; + from timeZone in DateTimeZoneParser + select dateFormat + timeFormat + micros + timeZone; // A number with a '.' decimal point, or with the decimal separator of the current culture. // The longer match wins, so '4.5' parses in every culture and '4,5' still parses in a culture that uses ','. diff --git a/README.md b/README.md index 96f5341..2478843 100644 --- a/README.md +++ b/README.md @@ -258,6 +258,7 @@ Property list grouping is particularly useful for: * `TimeOnly`: * `var filterInput = """Time == "12:30:00" """;` * `var filterInput = """Time == "12:30:00.678722" """;` + * In a date and time value, write the zone after the fraction: `2022-07-01T00:00:03.5Z`. An unquoted value with the zone before the fraction (`2022-07-01T00:00:03Z.5`) throws a `ParsingException`. * `bool` properties need to use `== true`, `== false`, or the same using the `!=` operator. they can not be standalone properies: