This is an automated email from the ASF dual-hosted git repository. desruisseaux pushed a commit to branch geoapi-4.0 in repository https://gitbox.apache.org/repos/asf/sis.git
commit f5847a4f884bcf42ffd70c7805234b60651e7127 Author: glegal <guilhem.le...@geomatys.com> AuthorDate: Thu Apr 3 14:34:03 2025 +0200 Handle LocalDate format in CQL parser --- .../src/main/antlr/org/apache/sis/cql/internal/CQL.g4 | 4 +++- .../org.apache.sis.cql/main/org/apache/sis/cql/CQL.java | 2 +- .../test/org/apache/sis/cql/ExpressionReadingTest.java | 15 ++++++++++++++- .../test/org/apache/sis/cql/ExpressionWritingTest.java | 11 ++++++++++- 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/incubator/src/main/antlr/org/apache/sis/cql/internal/CQL.g4 b/incubator/src/main/antlr/org/apache/sis/cql/internal/CQL.g4 index 91197f8538..3757b06c99 100644 --- a/incubator/src/main/antlr/org/apache/sis/cql/internal/CQL.g4 +++ b/incubator/src/main/antlr/org/apache/sis/cql/internal/CQL.g4 @@ -137,7 +137,8 @@ WITHIN : W I T H I N ; // TEMPORAL TYPES AND FILTERS -DATE : DIGIT DIGIT DIGIT DIGIT '-' DIGIT DIGIT '-' DIGIT DIGIT 'T' DIGIT DIGIT ':' DIGIT DIGIT ':' DIGIT DIGIT ('.' DIGIT+)? 'Z'; +DATETIME : DIGIT DIGIT DIGIT DIGIT '-' DIGIT DIGIT '-' DIGIT DIGIT 'T' DIGIT DIGIT ':' DIGIT DIGIT ':' DIGIT DIGIT ('.' DIGIT+)? 'Z'; +DATE : DIGIT DIGIT DIGIT DIGIT '-' DIGIT DIGIT '-' DIGIT DIGIT; DURATION_P : P (INT 'Y')? (INT 'M')? (INT 'D')? (INT 'H')? (INT 'M')? (INT 'S')?; DURATION_T : P T (INT 'H')? (INT 'M')? (INT 'S')?; @@ -230,6 +231,7 @@ expressionTerm : TEXT | expressionUnary | PROPERTY_NAME + | DATETIME | DATE | DURATION_P | DURATION_T diff --git a/incubator/src/org.apache.sis.cql/main/org/apache/sis/cql/CQL.java b/incubator/src/org.apache.sis.cql/main/org/apache/sis/cql/CQL.java index 472228bb9a..6577e570b0 100644 --- a/incubator/src/org.apache.sis.cql/main/org/apache/sis/cql/CQL.java +++ b/incubator/src/org.apache.sis.cql/main/org/apache/sis/cql/CQL.java @@ -283,7 +283,7 @@ public final class CQL { case NAME: return ff.property(tree.getText()); case INT: return ff.literal(Integer.valueOf(tree.getText())); case FLOAT: return ff.literal(Double.valueOf(tree.getText())); - case DATE: { + case DATE, DATETIME: { TemporalAccessor ta = LenientDateFormat.parseBest(tree.getText()); return ff.literal(ta); // TODO: return ff.literal(TemporalObjects.getTimeInMillis(tree.getText())); diff --git a/incubator/src/org.apache.sis.cql/test/org/apache/sis/cql/ExpressionReadingTest.java b/incubator/src/org.apache.sis.cql/test/org/apache/sis/cql/ExpressionReadingTest.java index bb3dd4cbb1..a510b64bd2 100644 --- a/incubator/src/org.apache.sis.cql/test/org/apache/sis/cql/ExpressionReadingTest.java +++ b/incubator/src/org.apache.sis.cql/test/org/apache/sis/cql/ExpressionReadingTest.java @@ -20,6 +20,7 @@ import java.time.Instant; import java.time.Duration; import java.time.Period; import java.text.ParseException; +import java.time.LocalDate; import java.time.temporal.ChronoUnit; import java.time.temporal.TemporalAccessor; import org.locationtech.jts.geom.Coordinate; @@ -155,7 +156,7 @@ public final class ExpressionReadingTest extends CQLTestCase { } @Test - public void testDate() throws CQLException, ParseException{ + public void testDatetime() throws CQLException, ParseException{ //dates are expected to be formated in ISO 8601 : yyyy-MM-dd'T'HH:mm:ss'Z' final String cql = "2012-03-21T05:42:36Z"; final Object obj = CQL.parseExpression(cql); @@ -167,6 +168,18 @@ public final class ExpressionReadingTest extends CQLTestCase { assertEquals(Instant.parse("2012-03-21T05:42:36Z"), Instant.from(acc)); } + @Test + public void testDate() throws CQLException, ParseException{ + final String cql = "2012-03-21"; + final Object obj = CQL.parseExpression(cql); + assertTrue(obj instanceof Literal); + final Literal expression = (Literal) obj; + Object value = expression.getValue(); + assertTrue(value instanceof TemporalAccessor); + TemporalAccessor acc = (TemporalAccessor) value; + assertEquals(LocalDate.parse("2012-03-21"), LocalDate.from(acc)); + } + @Test public void testDuration() throws CQLException, ParseException{ final String cql = "P7Y6M5D"; diff --git a/incubator/src/org.apache.sis.cql/test/org/apache/sis/cql/ExpressionWritingTest.java b/incubator/src/org.apache.sis.cql/test/org/apache/sis/cql/ExpressionWritingTest.java index c72b1341d3..a180d6856d 100644 --- a/incubator/src/org.apache.sis.cql/test/org/apache/sis/cql/ExpressionWritingTest.java +++ b/incubator/src/org.apache.sis.cql/test/org/apache/sis/cql/ExpressionWritingTest.java @@ -18,6 +18,7 @@ package org.apache.sis.cql; import java.time.Instant; import java.text.ParseException; +import java.time.LocalDate; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.LineString; @@ -94,13 +95,21 @@ public final class ExpressionWritingTest extends CQLTestCase { @Test @Disabled("Unsupported temporal field: Year") - public void testDate() throws CQLException, ParseException{ + public void testDateTime() throws CQLException, ParseException{ final Expression<Feature,?> exp = FF.literal(Instant.parse("2012-03-21T05:42:36Z")); final String cql = CQL.write(exp); assertNotNull(cql); assertEquals("2012-03-21T05:42:36Z", cql); } + @Test + public void testDate() throws CQLException, ParseException{ + final Expression<Feature,?> exp = FF.literal(LocalDate.parse("2012-03-21")); + final String cql = CQL.write(exp); + assertNotNull(cql); + assertEquals("2012-03-21", cql); + } + @Test public void testNegativeDecimal() throws CQLException {