All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.juneau.swaps.TemporalSwap Maven / Gradle / Ivy

// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
// * with the License.  You may obtain a copy of the License at                                                              *
// *                                                                                                                         *
// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
// *                                                                                                                         *
// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
// * specific language governing permissions and limitations under the License.                                              *
// ***************************************************************************************************************************
package org.apache.juneau.swaps;

import java.lang.reflect.*;
import java.time.*;
import java.time.chrono.*;
import java.time.format.*;
import java.time.temporal.*;
import java.util.*;
import java.util.concurrent.*;

import org.apache.juneau.*;
import org.apache.juneau.internal.*;
import org.apache.juneau.reflect.*;
import org.apache.juneau.swap.*;

/**
 * Swap that converts {@link Temporal} objects to strings.
 *
 * 

* Uses the {@link DateTimeFormatter} class for converting {@link Temporal} objects to and from strings. * *

* Supports any of the following temporal objects: *

    *
  • {@link HijrahDate} *
  • {@link Instant} *
  • {@link JapaneseDate} *
  • {@link LocalDate} *
  • {@link LocalDateTime} *
  • {@link LocalTime} *
  • {@link MinguoDate} *
  • {@link OffsetDateTime} *
  • {@link OffsetTime} *
  • {@link ThaiBuddhistDate} *
  • {@link Year} *
  • {@link YearMonth} *
  • {@link ZonedDateTime} *
* *
See Also:
*/ public class TemporalSwap extends StringSwap { /** * Default swap to {@link DateTimeFormatter#BASIC_ISO_DATE}. *

* Example: "20111203" */ public static class BasicIsoDate extends TemporalSwap { /** Default instance.*/ public static final TemporalSwap DEFAULT = new BasicIsoDate(); /** Constructor.*/ public BasicIsoDate() { super("BASIC_ISO_DATE", true); } } /** * Default swap to {@link DateTimeFormatter#ISO_DATE}. *

* Example: "2011-12-03+01:00" or "2011-12-03" */ public static class IsoDate extends TemporalSwap { /** Default instance.*/ public static final TemporalSwap DEFAULT = new IsoDate(); /** Constructor.*/ public IsoDate() { super("ISO_DATE", true); } } /** * Default swap to {@link DateTimeFormatter#ISO_DATE_TIME}. *

* Example: "2011-12-03T10:15:30+01:00[Europe/Paris]" */ public static class IsoDateTime extends TemporalSwap { /** Default instance.*/ public static final TemporalSwap DEFAULT = new IsoDateTime(); /** Constructor.*/ public IsoDateTime() { super("ISO_DATE_TIME", true); } } /** * Default swap to {@link DateTimeFormatter#ISO_INSTANT}. *

* Example: "2011-12-03T10:15:30Z" */ public static class IsoInstant extends TemporalSwap { /** Default instance.*/ public static final TemporalSwap DEFAULT = new IsoInstant(); /** Constructor.*/ public IsoInstant() { super("ISO_INSTANT", false); } } /** * Default swap to {@link DateTimeFormatter#ISO_LOCAL_DATE}. *

* Example: "2011-12-03" */ public static class IsoLocalDate extends TemporalSwap { /** Default instance.*/ public static final TemporalSwap DEFAULT = new IsoLocalDate(); /** Constructor.*/ public IsoLocalDate() { super("ISO_LOCAL_DATE", false); } } /** * Default swap to {@link DateTimeFormatter#ISO_LOCAL_DATE_TIME}. *

* Example: "2011-12-03T10:15:30" */ public static class IsoLocalDateTime extends TemporalSwap { /** Default instance.*/ public static final TemporalSwap DEFAULT = new IsoLocalDateTime(); /** Constructor.*/ public IsoLocalDateTime() { super("ISO_LOCAL_DATE_TIME", true); } } /** * Default swap to {@link DateTimeFormatter#ISO_LOCAL_TIME}. *

* Example: "10:15:30" */ public static class IsoLocalTime extends TemporalSwap { /** Default instance.*/ public static final TemporalSwap DEFAULT = new IsoLocalTime(); /** Constructor.*/ public IsoLocalTime() { super("ISO_LOCAL_TIME", true); } } /** * Default swap to {@link DateTimeFormatter#ISO_OFFSET_DATE}. *

* Example: "2011-12-03" */ public static class IsoOffsetDate extends TemporalSwap { /** Default instance.*/ public static final TemporalSwap DEFAULT = new IsoOffsetDate(); /** Constructor.*/ public IsoOffsetDate() { super("ISO_OFFSET_DATE", false); } } /** * Default swap to {@link DateTimeFormatter#ISO_OFFSET_DATE_TIME}. *

* Example: "2011-12-03T10:15:30+01:00" */ public static class IsoOffsetDateTime extends TemporalSwap { /** Default instance.*/ public static final TemporalSwap DEFAULT = new IsoOffsetDateTime(); /** Constructor.*/ public IsoOffsetDateTime() { super("ISO_OFFSET_DATE_TIME", false); } } /** * Default swap to {@link DateTimeFormatter#ISO_OFFSET_TIME}. *

* Example: "10:15:30+01:00" */ public static class IsoOffsetTime extends TemporalSwap { /** Default instance.*/ public static final TemporalSwap DEFAULT = new IsoOffsetTime(); /** Constructor.*/ public IsoOffsetTime() { super("ISO_OFFSET_TIME", false); } } /** * Default swap to {@link DateTimeFormatter#ISO_ORDINAL_DATE}. *

* Example: "2012-337" */ public static class IsoOrdinalDate extends TemporalSwap { /** Default instance.*/ public static final TemporalSwap DEFAULT = new IsoOrdinalDate(); /** Constructor.*/ public IsoOrdinalDate() { super("ISO_ORDINAL_DATE", true); } } /** * Default swap to {@link DateTimeFormatter#ISO_TIME}. *

* Example: "10:15:30+01:00" or "10:15:30" */ public static class IsoTime extends TemporalSwap { /** Default instance.*/ public static final TemporalSwap DEFAULT = new IsoTime(); /** Constructor.*/ public IsoTime() { super("ISO_TIME", true); } } /** * Default swap to {@link DateTimeFormatter#ISO_WEEK_DATE}. *

* Example: "2012-W48-6" */ public static class IsoWeekDate extends TemporalSwap { /** Default instance.*/ public static final TemporalSwap DEFAULT = new IsoWeekDate(); /** Constructor.*/ public IsoWeekDate() { super("ISO_WEEK_DATE", true); } } /** * Default swap to {@link DateTimeFormatter#ISO_WEEK_DATE}. *

* Example: "2011" */ public static class IsoYear extends TemporalSwap { /** Default instance.*/ public static final TemporalSwap DEFAULT = new IsoYear(); /** Constructor.*/ public IsoYear() { super("uuuu", true); } } /** * Default swap to {@link DateTimeFormatter#ISO_WEEK_DATE}. *

* Example: "2011-12" */ public static class IsoYearMonth extends TemporalSwap { /** Default instance.*/ public static final TemporalSwap DEFAULT = new IsoYearMonth(); /** Constructor.*/ public IsoYearMonth() { super("uuuu-MM", true); } } /** * Default swap to {@link DateTimeFormatter#ISO_ZONED_DATE_TIME}. *

* Example: "2011-12-03T10:15:30+01:00[Europe/Paris]" */ public static class IsoZonedDateTime extends TemporalSwap { /** Default instance.*/ public static final TemporalSwap DEFAULT = new IsoZonedDateTime(); /** Constructor.*/ public IsoZonedDateTime() { super("ISO_ZONED_DATE_TIME", false); } } /** * Default swap to {@link DateTimeFormatter#RFC_1123_DATE_TIME}. *

* Example: "Tue, 3 Jun 2008 11:05:30 GMT" */ public static class Rfc1123DateTime extends TemporalSwap { /** Default instance.*/ public static final TemporalSwap DEFAULT = new Rfc1123DateTime(); /** Constructor.*/ public Rfc1123DateTime() { super("RFC_1123_DATE_TIME", false); } } private static final ZoneId Z = ZoneId.of("Z"); private static final Map,Method> FROM_METHODS = new ConcurrentHashMap<>(); private static Method findParseMethod(Class c) throws ExecutableException { Method m = FROM_METHODS.get(c); if (m == null) { MethodInfo mi = ClassInfo.of(c).getPublicMethod( x -> x.isStatic() && x.isNotDeprecated() && x.hasName("from") && x.hasReturnType(c) && x.hasParamTypes(TemporalAccessor.class) ); if (mi == null) throw new ExecutableException("Parse method not found on temporal class ''{0}''", c.getSimpleName()); m = mi.inner(); FROM_METHODS.put(c, m); } return m; } private final DateTimeFormatter formatter; private final boolean zoneOptional; /** * Constructor. * * @param pattern The timestamp format or name of predefined {@link DateTimeFormatter}. * @param zoneOptional true if the time zone on the pattern is optional. */ public TemporalSwap(String pattern, boolean zoneOptional) { super(Temporal.class); this.formatter = DateUtils.getFormatter(pattern); this.zoneOptional = zoneOptional; } /** * Returns true if the time zone on the pattern is optional. * *

* If it's not optional, then local dates/times must be converted into zoned times using the session time zone. * Otherwise, local date/times are fine. * * @return true if the time zone on the pattern is optional. */ protected boolean zoneOptional() { return zoneOptional; } @Override /* ObjectSwap */ public String swap(BeanSession session, Temporal o) throws Exception { if (o == null) return null; o = convertToSerializable(session, o); return formatter.format(o); } /** * Converts the specified temporal object to a form suitable to be serialized using any pattern. * * @param session The current bean session. * @param t The temporal object to convert. * @return The converted temporal object. */ protected Temporal convertToSerializable(BeanSession session, Temporal t) { ZoneId zoneId = session.getTimeZoneId(); Class tc = t.getClass(); // Instant is always serialized in GMT. if (tc == Instant.class) return ZonedDateTime.from(defaulting(t, Z)); // These can handle any pattern. if (tc == ZonedDateTime.class || tc == OffsetDateTime.class) return t; // Pattern optionally includes a time zone, so zoned and local date-times are good. if (zoneOptional()) { if (tc == LocalDateTime.class) return t; if (tc == OffsetTime.class) return ZonedDateTime.from(defaulting(t, zoneId)); return LocalDateTime.from(defaulting(t, zoneId)); } return ZonedDateTime.from(defaulting(t, zoneId)); } @SuppressWarnings("unchecked") @Override /* ObjectSwap */ public Temporal unswap(BeanSession session, String f, ClassMeta hint) throws Exception { if (hint == null) hint = session.getClassMeta(Instant.class); Class tc = (Class)hint.getInnerClass(); ZoneId offset = session.getTimeZoneId(); if (tc == Instant.class) offset = Z; Method parseMethod = findParseMethod(tc); TemporalAccessor ta = defaulting(formatter.parse(f), offset); return (Temporal)parseMethod.invoke(null, ta); } private final TemporalAccessor defaulting(TemporalAccessor t, ZoneId zoneId) { return new DefaultingTemporalAccessor(t, zoneId); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy