Skip to content

Commit 0a5d5e3

Browse files
authored
Handle Instant literals in TemporalAccessorLiteral (#5506)
1 parent 2f6ae3b commit 0a5d5e3

2 files changed

Lines changed: 28 additions & 3 deletions

File tree

core/model-api/src/main/java/org/eclipse/rdf4j/model/base/AbstractLiteral.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@
3232
import java.math.BigDecimal;
3333
import java.math.BigInteger;
3434
import java.time.DateTimeException;
35+
import java.time.Instant;
36+
import java.time.OffsetDateTime;
37+
import java.time.ZoneOffset;
3538
import java.time.format.DateTimeFormatter;
3639
import java.time.format.DateTimeFormatterBuilder;
3740
import java.time.format.DateTimeParseException;
@@ -704,15 +707,24 @@ private static int key(Predicate<ChronoField> include, ChronoField... fields) {
704707

705708
this.value = value;
706709

707-
datatype = DATATYPES.get(key(value));
710+
TemporalAccessor lexicalValue = value;
708711

709-
if (datatype == null) {
712+
CoreDatatype.XSD detectedDatatype = DATATYPES.get(key(lexicalValue));
713+
714+
if (detectedDatatype == null && value.isSupported(ChronoField.INSTANT_SECONDS)) {
715+
Instant instant = Instant.from(value);
716+
lexicalValue = OffsetDateTime.ofInstant(instant, ZoneOffset.UTC);
717+
detectedDatatype = DATATYPES.get(key(lexicalValue));
718+
}
719+
720+
if (detectedDatatype == null) {
710721
throw new IllegalArgumentException(String.format(
711722
"value <%s> cannot be represented by an XML Schema date/time datatype", value
712723
));
713724
}
714725

715-
this.label = FORMATTERS.get(datatype).format(value);
726+
datatype = detectedDatatype;
727+
this.label = FORMATTERS.get(datatype).format(lexicalValue);
716728
}
717729

718730
@Override

core/model/src/test/java/org/eclipse/rdf4j/model/util/LiteralsTest.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@
1111
package org.eclipse.rdf4j.model.util;
1212

1313
import static org.assertj.core.api.Assertions.assertThat;
14+
import static org.assertj.core.api.Assertions.assertThatCode;
1415
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
1516
import static org.junit.jupiter.api.Assertions.assertEquals;
1617
import static org.junit.jupiter.api.Assertions.assertFalse;
1718
import static org.junit.jupiter.api.Assertions.assertNotNull;
1819
import static org.junit.jupiter.api.Assertions.assertTrue;
1920
import static org.junit.jupiter.api.Assertions.fail;
2021

22+
import java.time.Instant;
2123
import java.util.Date;
2224
import java.util.GregorianCalendar;
2325
import java.util.IllformedLocaleException;
@@ -107,6 +109,17 @@ public void testNormaliseBCP47Tag() {
107109
.isThrownBy(() -> Literals.normalizeLanguageTag("ru-ua-latn"));
108110
}
109111

112+
@Test
113+
public void valuesLiteralSupportsInstant() {
114+
Instant instant = Instant.parse("2022-08-01T21:14:38.470534100Z");
115+
116+
Literal literal = Values.literal(instant);
117+
118+
assertThat(Instant.parse(literal.getLabel())).isEqualTo(instant);
119+
assertThat(literal.getDatatype()).isEqualTo(XSD.DATETIME);
120+
assertThat(literal.temporalAccessorValue()).isEqualTo(instant);
121+
}
122+
110123
/**
111124
* Test method for
112125
* {@link org.eclipse.rdf4j.model.util.Literals#getLabel(org.eclipse.rdf4j.model.Literal, java.lang.String)} .

0 commit comments

Comments
 (0)