You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by re...@apache.org on 2022/02/22 16:43:25 UTC

[cxf] branch 3.5.x-fixes updated: CXF-8659: Can't filter when attribute type is LocalDate or LocalDateTime (#911)

This is an automated email from the ASF dual-hosted git repository.

reta pushed a commit to branch 3.5.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git


The following commit(s) were added to refs/heads/3.5.x-fixes by this push:
     new 9f413c0  CXF-8659: Can't filter when attribute type is LocalDate or LocalDateTime (#911)
9f413c0 is described below

commit 9f413c0ef37c798b9cf69a899e63d5cae0788573
Author: Andriy Redko <dr...@gmail.com>
AuthorDate: Tue Feb 22 10:09:42 2022 -0500

    CXF-8659: Can't filter when attribute type is LocalDate or LocalDateTime (#911)
    
    (cherry picked from commit e0df5b52626680967c05a65ac3a8305270e99891)
---
 .../ext/search/AbstractSearchConditionParser.java  |  77 +++++-
 .../apache/cxf/jaxrs/ext/search/SearchUtils.java   |  14 +-
 .../cxf/jaxrs/ext/search/fiql/FiqlParserTest.java  | 262 +++++++++++++++++++++
 3 files changed, 350 insertions(+), 3 deletions(-)

diff --git a/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/AbstractSearchConditionParser.java b/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/AbstractSearchConditionParser.java
index d69a24d..08c4aba 100644
--- a/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/AbstractSearchConditionParser.java
+++ b/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/AbstractSearchConditionParser.java
@@ -25,11 +25,22 @@ import java.sql.Time;
 import java.sql.Timestamp;
 import java.text.DateFormat;
 import java.text.ParseException;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.OffsetDateTime;
+import java.time.OffsetTime;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
+import java.time.temporal.Temporal;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.BiFunction;
 
 import javax.xml.datatype.DatatypeConfigurationException;
 import javax.xml.datatype.DatatypeFactory;
@@ -111,6 +122,7 @@ public abstract class AbstractSearchConditionParser<T> implements SearchConditio
         return setter;
     }
 
+    @SuppressWarnings("unchecked")
     protected Object parseType(String originalPropName,
                              Object ownerBean,
                              Object lastCastedValue,
@@ -126,6 +138,8 @@ public abstract class AbstractSearchConditionParser<T> implements SearchConditio
             Object castedValue = value;
             if (Date.class.isAssignableFrom(valueType)) {
                 castedValue = convertToDate(valueType, value);
+            } else if (Temporal.class.isAssignableFrom(valueType)) {
+                castedValue = convertToTemporal((Class<? extends Temporal>)valueType, value);
             } else {
                 boolean isPrimitive = InjectionUtils.isPrimitive(valueType);
                 boolean isPrimitiveOrEnum = isPrimitive || valueType.isEnum();
@@ -309,6 +323,47 @@ public abstract class AbstractSearchConditionParser<T> implements SearchConditio
             }
         }
     }
+    
+    private Temporal convertToTemporal(Class<? extends Temporal> valueType, String value) throws SearchParseException {
+
+        Message m = JAXRSUtils.getCurrentMessage();
+        Temporal obj = InjectionUtils.createFromParameterHandler(value, valueType, valueType,
+                                                               new Annotation[]{}, m);
+        if (obj != null) {
+            return obj;
+        }
+
+        try {
+            if (LocalTime.class.isAssignableFrom(valueType)) {
+                return LocalTime.parse(value);
+            } else if (LocalDate.class.isAssignableFrom(valueType)) {
+                return LocalDate.from(convertToDefaultDate(value).toInstant().atZone(ZoneId.systemDefault()));
+            } else if (LocalDateTime.class.isAssignableFrom(valueType)) {
+                return convertTo(value, SearchUtils.DEFAULT_DATETIME_FORMAT, Boolean.FALSE, LocalDateTime::parse);
+            } else if (OffsetTime.class.isAssignableFrom(valueType)) {
+                return OffsetTime.parse(value);
+            } else if (OffsetDateTime.class.isAssignableFrom(valueType)) {
+                return convertTo(value, SearchUtils.DEFAULT_OFFSET_DATETIME_FORMAT,
+                    Boolean.TRUE, OffsetDateTime::parse);
+            } else if (ZonedDateTime.class.isAssignableFrom(valueType)) {
+                return convertTo(value, SearchUtils.DEFAULT_ZONE_DATETIME_FORMAT,
+                    Boolean.TRUE, ZonedDateTime::parse);
+            } else {
+                return convertToDefaultDate(value).toInstant();
+            }
+        } catch (ParseException | DateTimeParseException e) {
+            // is that duration?
+            try {
+                Date now = new Date();
+                DatatypeFactory.newInstance().newDuration(value).addTo(now);
+                return LocalDateTime.from(now.toInstant().atZone(ZoneId.systemDefault()));
+            } catch (DatatypeConfigurationException e1) {
+                throw new SearchParseException(e1);
+            } catch (IllegalArgumentException e1) {
+                throw new SearchParseException("Can parse " + value + " neither as date nor duration", e);
+            }
+        }
+    }
 
     private Timestamp convertToTimestamp(String value) throws ParseException {
         Date date = convertToDefaultDate(value);
@@ -322,15 +377,33 @@ public abstract class AbstractSearchConditionParser<T> implements SearchConditio
 
     private Date convertToDefaultDate(String value) throws ParseException {
         DateFormat df = SearchUtils.getDateFormat(contextProperties);
+        String dateValue = normalizeTimeZone(value);
+        return df.parse(dateValue);
+    }
+
+    private <S extends Temporal> S convertTo(String value, String pattern, Boolean timezoneSupported,
+            BiFunction<String, DateTimeFormatter, S> parser) throws ParseException {
+        final DateTimeFormatter df = DateTimeFormatter.ofPattern(SearchUtils
+            .getDateFormatOrDefault(contextProperties, pattern)
+            .toPattern());
+        final String dateValue = normalizeTimeZone(value, timezoneSupported);
+        return parser.apply(dateValue, df);
+    }
+
+    private String normalizeTimeZone(String value) {
+        return normalizeTimeZone(value, Boolean.FALSE);
+    }
+
+    private String normalizeTimeZone(String value, Boolean timezoneSupported) {
         String dateValue = value;
-        if (SearchUtils.isTimeZoneSupported(contextProperties, Boolean.FALSE)) {
+        if (SearchUtils.isTimeZoneSupported(contextProperties, timezoneSupported)) {
             // zone in XML is "+01:00" in Java is "+0100"; stripping semicolon
             int idx = value.lastIndexOf(':');
             if (idx != -1) {
                 dateValue = value.substring(0, idx) + value.substring(idx + 1);
             }
         }
-        return df.parse(dateValue);
+        return dateValue;
     }
 
     private static String getMethodNameSuffix(String name) {
diff --git a/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchUtils.java b/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchUtils.java
index ba73c57..2110ab1 100644
--- a/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchUtils.java
+++ b/rt/rs/extensions/search/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchUtils.java
@@ -36,6 +36,9 @@ public final class SearchUtils {
     public static final String TIMESTAMP_NO_TIMEZONE = "yyyy-MM-dd'T'HH:mm:ss";
     public static final String TIMESTAMP_WITH_TIMEZONE_Z = "yyyy-MM-dd'T'HH:mm:ssZ";
     public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
+    public static final String DEFAULT_DATETIME_FORMAT = TIMESTAMP_NO_TIMEZONE;
+    public static final String DEFAULT_OFFSET_DATETIME_FORMAT = TIMESTAMP_WITH_TIMEZONE_Z;
+    public static final String DEFAULT_ZONE_DATETIME_FORMAT = TIMESTAMP_WITH_TIMEZONE_Z + "'['z']'";
     public static final String DATE_FORMAT_PROPERTY = "search.date-format";
     public static final String TIMEZONE_SUPPORT_PROPERTY = "search.timezone.support";
     public static final String LAX_PROPERTY_MATCH = "search.lax.property.match";
@@ -85,11 +88,20 @@ public final class SearchUtils {
         return dateFromStringWithDefaultFormats(value);
     }
 
+    public static SimpleDateFormat getDateFormatOrDefault(Map<String, String> properties, String pattern) {
+        return getDateFormatOrDefault(properties.get(DATE_FORMAT_PROPERTY), pattern);
+    }
+
     public static SimpleDateFormat getDateFormat(Map<String, String> properties) {
         return getDateFormat(properties.get(DATE_FORMAT_PROPERTY));
     }
+
+    public static SimpleDateFormat getDateFormatOrDefault(String dfProperty, String pattern) {
+        return new SimpleDateFormat(dfProperty == null ? pattern : dfProperty);
+    }
+
     public static SimpleDateFormat getDateFormat(String dfProperty) {
-        return new SimpleDateFormat(dfProperty == null ? DEFAULT_DATE_FORMAT : dfProperty);
+        return getDateFormatOrDefault(dfProperty, DEFAULT_DATE_FORMAT);
     }
 
     public static boolean isTimeZoneSupported(Map<String, String> properties, Boolean defaultValue) {
diff --git a/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/fiql/FiqlParserTest.java b/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/fiql/FiqlParserTest.java
index c3b88ef..7778b48 100644
--- a/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/fiql/FiqlParserTest.java
+++ b/rt/rs/extensions/search/src/test/java/org/apache/cxf/jaxrs/ext/search/fiql/FiqlParserTest.java
@@ -21,6 +21,14 @@ package org.apache.cxf.jaxrs.ext.search.fiql;
 import java.text.DateFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.OffsetDateTime;
+import java.time.OffsetTime;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
@@ -207,6 +215,151 @@ public class FiqlParserTest {
     }
 
     @Test
+    public void testParseLocalDateWithDefaultFormat() throws SearchParseException, ParseException {
+        SearchCondition<Condition> filter = parser.parse("localDate=le=2010-03-11");
+        DateTimeFormatter df = DateTimeFormatter.ofPattern(SearchUtils.DEFAULT_DATE_FORMAT);
+        assertTrue(filter.isMet(new Condition("whatever", 15, null, LocalDate.parse("2010-03-11", df))));
+        assertTrue(filter.isMet(new Condition(null, null, null, LocalDate.parse("2010-03-10", df))));
+        assertFalse(filter.isMet(new Condition("blah", null, null, LocalDate.parse("2010-03-12", df))));
+        assertFalse(filter.isMet(new Condition(null, 123, null, LocalDate.parse("2010-03-12", df))));
+    }
+
+    @Test
+    public void testParseInstantWithDefaultFormat() throws SearchParseException, ParseException {
+        SearchCondition<Condition> filter = parser.parse("instant=le=2010-03-11");
+        DateFormat df = new SimpleDateFormat(SearchUtils.DEFAULT_DATE_FORMAT);
+        assertTrue(filter.isMet(new Condition("whatever", 15, null, df.parse("2010-03-11").toInstant())));
+        assertTrue(filter.isMet(new Condition(null, null, null, df.parse("2010-03-10").toInstant())));
+        assertFalse(filter.isMet(new Condition("blah", null, null, df.parse("2010-03-12").toInstant())));
+        assertFalse(filter.isMet(new Condition(null, 123, null, df.parse("2010-03-12").toInstant())));
+    }
+
+    @Test
+    public void testParseInstantDuration() throws Exception {
+        SearchCondition<Condition> filter = parser.parse("localDateTime=gt=-PT1M");
+        LocalDateTime now = LocalDateTime.now();
+        LocalDateTime tenMinutesAgo = now.minusMinutes(10);
+        assertTrue(filter.isMet(new Condition(null, null, null, now)));
+        assertFalse(filter.isMet(new Condition(null, null, null, tenMinutesAgo)));
+    }
+
+    @Test
+    public void testParseLocalTime() throws SearchParseException, ParseException {
+        SearchCondition<Condition> filter = parser.parse("localTime=le=03:11:22");
+        assertTrue(filter.isMet(new Condition("whatever", 15, null, LocalTime.parse("03:11:22"))));
+        assertTrue(filter.isMet(new Condition(null, null, null, LocalTime.parse("03:11:21"))));
+        assertFalse(filter.isMet(new Condition("blah", null, null, LocalTime.parse("03:12:21"))));
+        assertFalse(filter.isMet(new Condition(null, 123, null, LocalTime.parse("03:12:21"))));
+    }
+
+    @Test
+    public void testParseOffsetTime() throws SearchParseException, ParseException {
+        SearchCondition<Condition> filter = parser.parse("offsetTime=le=03:11:22+01:00");
+        assertTrue(filter.isMet(new Condition("whatever", 15, null, OffsetTime.parse("03:11:22+01:00"))));
+        assertTrue(filter.isMet(new Condition(null, null, null, OffsetTime.parse("03:11:21+01:00"))));
+        assertFalse(filter.isMet(new Condition("blah", null, null, OffsetTime.parse("03:12:21+01:00"))));
+        assertFalse(filter.isMet(new Condition(null, 123, null, OffsetTime.parse("03:12:21+01:00"))));
+    }
+
+    @Test
+    public void testParseLocalDateTimeWithDefaultFormat() throws SearchParseException, ParseException {
+        SearchCondition<Condition> filter = parser.parse("localDateTime=le=2010-03-11T18:00:00");
+        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
+        assertTrue(filter.isMet(new Condition("whatever", 15, null,
+            LocalDateTime.parse("2010-03-11T18:00:00", df))));
+        assertTrue(filter.isMet(new Condition(null, null,  null,
+            LocalDateTime.parse("2010-03-10T22:22:00", df))));
+        assertFalse(filter.isMet(new Condition("blah", null, null,
+            LocalDateTime.parse("2010-03-12T00:00:00", df))));
+        assertFalse(filter.isMet(new Condition(null, 123, null,
+            LocalDateTime.parse("2010-03-12T00:00:00", df))));
+    }
+
+    @Test
+    public void testParseLocalDateTimeWithCustomFormat() throws SearchParseException, ParseException {
+        Map<String, String> props = new HashMap<>();
+        props.put(SearchUtils.DATE_FORMAT_PROPERTY, "yyyy-MM-dd'T'HH:mm:ss");
+        props.put(SearchUtils.TIMEZONE_SUPPORT_PROPERTY, "false");
+        parser = new FiqlParser<>(Condition.class, props);
+
+        SearchCondition<Condition> filter = parser.parse("localDateTime=le=2010-03-11T18:00:00");
+        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
+        assertTrue(filter.isMet(new Condition("whatever", 15, null,
+            LocalDateTime.parse("2010-03-11T18:00:00", df))));
+        assertTrue(filter.isMet(new Condition(null, null,  null,
+            LocalDateTime.parse("2010-03-10T22:22:00", df))));
+        assertFalse(filter.isMet(new Condition("blah", null, null,
+            LocalDateTime.parse("2010-03-12T00:00:00", df))));
+        assertFalse(filter.isMet(new Condition(null, 123, null, 
+            LocalDateTime.parse("2010-03-12T00:00:00", df))));
+    }
+
+    @Test
+    public void testParseOffsetDateTimeWithDefaultFormat() throws SearchParseException, ParseException {
+        SearchCondition<Condition> filter = parser.parse("offsetDateTime=le=2010-03-11T18:00:00+01:00");
+        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ");
+        assertTrue(filter.isMet(new Condition("whatever", 15, null,
+            OffsetDateTime.parse("2010-03-11T18:00:00+0100", df))));
+        assertTrue(filter.isMet(new Condition(null, null,  null,
+            OffsetDateTime.parse("2010-03-10T22:22:00+0100", df))));
+        assertFalse(filter.isMet(new Condition("blah", null, null,
+            OffsetDateTime.parse("2010-03-12T00:00:00+0100", df))));
+        assertFalse(filter.isMet(new Condition(null, 123, null, 
+            OffsetDateTime.parse("2010-03-12T00:00:00+0100", df))));
+    }
+
+    @Test
+    public void testParseOffsetDateTimeWithCustomFormat() throws SearchParseException, ParseException {
+        Map<String, String> props = new HashMap<>();
+        props.put(SearchUtils.DATE_FORMAT_PROPERTY, "yyyy-MM-dd'T'HH:mm:ssZ");
+        props.put(SearchUtils.TIMEZONE_SUPPORT_PROPERTY, "true");
+        parser = new FiqlParser<>(Condition.class, props);
+
+        SearchCondition<Condition> filter = parser.parse("offsetDateTime=le=2010-03-11T18:00:00+01:00");
+        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ");
+        assertTrue(filter.isMet(new Condition("whatever", 15, null, 
+            OffsetDateTime.parse("2010-03-11T18:00:00+0100", df))));
+        assertTrue(filter.isMet(new Condition(null, null,  null, 
+            OffsetDateTime.parse("2010-03-10T22:22:00+0100", df))));
+        assertFalse(filter.isMet(new Condition("blah", null, null, 
+            OffsetDateTime.parse("2010-03-12T00:00:00+0100", df))));
+        assertFalse(filter.isMet(new Condition(null, 123, null, OffsetDateTime.parse("2010-03-12T00:00:00+0100", df))));
+    }
+
+    @Test
+    public void testParseZonedDateTimeWithCustomFormat() throws SearchParseException, ParseException {
+        Map<String, String> props = new HashMap<>();
+        props.put(SearchUtils.DATE_FORMAT_PROPERTY, "yyyy-MM-dd'T'HH:mm:ss '['z']'");
+        props.put(SearchUtils.TIMEZONE_SUPPORT_PROPERTY, "false");
+        parser = new FiqlParser<>(Condition.class, props);
+
+        SearchCondition<Condition> filter = parser.parse("zonedDateTime=le=2010-03-11T18:00:00 [Europe/Paris]");
+        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss' ['z']'");
+        assertTrue(filter.isMet(new Condition("whatever", 15, null, 
+            ZonedDateTime.parse("2010-03-11T18:00:00 [Europe/Paris]", df))));
+        assertTrue(filter.isMet(new Condition(null, null,  null, 
+            ZonedDateTime.parse("2010-03-10T22:22:00 [Europe/Paris]", df))));
+        assertFalse(filter.isMet(new Condition("blah", null, null, 
+            ZonedDateTime.parse("2010-03-12T00:00:00 [Europe/Paris]", df))));
+        assertFalse(filter.isMet(new Condition(null, 123, null, 
+            ZonedDateTime.parse("2010-03-12T00:00:00 [Europe/Paris]", df))));
+    }
+    
+    @Test
+    public void testParseZonedDateTimeWithDefaultFormat() throws SearchParseException, ParseException {
+        SearchCondition<Condition> filter = parser.parse("zonedDateTime=le=2010-03-11T18:00:00+01:00[Europe/Paris]");
+        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ'['z']'");
+        assertTrue(filter.isMet(new Condition("whatever", 15, null,
+            ZonedDateTime.parse("2010-03-11T18:00:00+0100[Europe/Paris]", df))));
+        assertTrue(filter.isMet(new Condition(null, null,  null,
+            ZonedDateTime.parse("2010-03-10T22:22:00+0100[Europe/Paris]", df))));
+        assertFalse(filter.isMet(new Condition("blah", null, null,
+            ZonedDateTime.parse("2010-03-12T00:00:00+0100[Europe/Paris]", df))));
+        assertFalse(filter.isMet(new Condition(null, 123, null,
+            ZonedDateTime.parse("2010-03-12T00:00:00+0100[Europe/Paris]", df))));
+    }
+    
+    @Test
     public void testParseComplex1() throws SearchParseException {
         SearchCondition<Condition> filter = parser.parse("name==ami*;level=gt=10");
         assertEquals(ConditionType.AND, filter.getConditionType());
@@ -334,14 +487,68 @@ public class FiqlParserTest {
         private String name2;
         private Integer level;
         private Date time;
+        private LocalDate localDate;
+        private LocalTime localTime;
+        private LocalDateTime localDateTime;
+        private OffsetTime offsetTime;
+        private OffsetDateTime offsetDateTime;
+        private ZonedDateTime zonedDateTime;
+        private Instant instant;
 
         public Condition() {
         }
 
         public Condition(String name, Integer level, Date time) {
+            this(name, level, time, (LocalDate)null);
+        }
+
+        public Condition(String name, Integer level, Date time, ZonedDateTime zonedDateTime) {
             this.name = name;
             this.level = level;
             this.time = time;
+            this.zonedDateTime = zonedDateTime;
+        }
+
+        public Condition(String name, Integer level, Date time, OffsetDateTime offsetDateTime) {
+            this.name = name;
+            this.level = level;
+            this.time = time;
+            this.offsetDateTime = offsetDateTime;
+        }
+
+        public Condition(String name, Integer level, Date time, OffsetTime offsetTime) {
+            this.name = name;
+            this.level = level;
+            this.time = time;
+            this.offsetTime = offsetTime;
+        }
+
+        public Condition(String name, Integer level, Date time, LocalDateTime localDateTime) {
+            this.name = name;
+            this.level = level;
+            this.time = time;
+            this.localDateTime = localDateTime;
+        }
+
+        public Condition(String name, Integer level, Date time, LocalDate localDate) {
+            this.name = name;
+            this.level = level;
+            this.time = time;
+            this.localDate = localDate;
+        }
+
+        public Condition(String name, Integer level, Date time, LocalTime localTime) {
+            this.name = name;
+            this.level = level;
+            this.time = time;
+            this.localTime = localTime;
+        }
+
+        public Condition(String name, Integer level, Date time, Instant instant) {
+            this.name = name;
+            this.level = level;
+            this.time = time;
+            this.instant = instant;
         }
 
         public Condition(String name, Integer level, Date time, String name2) {
@@ -384,6 +591,61 @@ public class FiqlParserTest {
             return name2;
         }
 
+        public LocalDate getLocalDate() {
+            return localDate;
+        }
+        
+        public void setLocalDate(LocalDate localDate) {
+            this.localDate = localDate;
+        }
+        
+        public LocalTime getLocalTime() {
+            return localTime;
+        }
+        
+        public void setLocalTime(LocalTime localTime) {
+            this.localTime = localTime;
+        }
+        
+        public void setLocalDateTime(LocalDateTime localDateTime) {
+            this.localDateTime = localDateTime;
+        }
+        
+        public LocalDateTime getLocalDateTime() {
+            return localDateTime;
+        }
+        
+        public void setOffsetTime(OffsetTime offsetTime) {
+            this.offsetTime = offsetTime;
+        }
+        
+        public OffsetTime getOffsetTime() {
+            return offsetTime;
+        }
+        
+        public void setOffsetDateTime(OffsetDateTime offsetDateTime) {
+            this.offsetDateTime = offsetDateTime;
+        }
+        
+        public OffsetDateTime getOffsetDateTime() {
+            return offsetDateTime;
+        }
+        
+        public void setZonedDateTime(ZonedDateTime zonedDateTime) {
+            this.zonedDateTime = zonedDateTime;
+        }
+        
+        public ZonedDateTime getZonedDateTime() {
+            return zonedDateTime;
+        }
+        
+        public Instant getInstant() {
+            return instant;
+        }
+        
+        public void setInstant(Instant instant) {
+            this.instant = instant;
+        }
     }