Package javax.time.calendar

Source Code of javax.time.calendar.ZoneResolvers$PostTransition

/*
* Copyright (c) 2007-2009, Stephen Colebourne & Michael Nascimento Santos
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*  * Redistributions of source code must retain the above copyright notice,
*    this list of conditions and the following disclaimer.
*
*  * Redistributions in binary form must reproduce the above copyright notice,
*    this list of conditions and the following disclaimer in the documentation
*    and/or other materials provided with the distribution.
*
*  * Neither the name of JSR-310 nor the names of its contributors
*    may be used to endorse or promote products derived from this software
*    without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package javax.time.calendar;

import javax.time.CalendricalException;
import javax.time.Instant;
import javax.time.calendar.zone.ZoneOffsetTransition;
import javax.time.calendar.zone.ZoneRules;

/**
* Provides implementations of {@link ZoneResolver}.
* <p>
* ZoneResolvers is a utility class.
* All resolvers returned are immutable and thread-safe.
*
* @author Stephen Colebourne
*/
public final class ZoneResolvers {

    /**
     * Private constructor.
     */
    private ZoneResolvers() {
    }

    //-----------------------------------------------------------------------
    /**
     * Returns the strict zone resolver which rejects all gaps and overlaps
     * as invalid, resulting in an exception.
     *
     * @return the strict resolver, never null
     */
    public static ZoneResolver strict() {
        return Strict.INSTANCE;
    }

    /**
     * Class implementing strict resolver.
     */
    private static class Strict extends ZoneResolver {
        /** The singleton instance. */
        private static final Strict INSTANCE = new Strict();
       
        /** {@inheritDoc} */
        @Override
        protected OffsetDateTime handleGap(
                TimeZone zone, ZoneRules rules, ZoneOffsetTransition discontinuity,
                LocalDateTime newDateTime, OffsetDateTime oldDateTime) {
            throw new CalendricalException("Local time " + newDateTime + " does not exist in time zone " +
                    zone + " due to a gap in the local time-line");
        }
        /** {@inheritDoc} */
        @Override
        protected OffsetDateTime handleOverlap(
                TimeZone zone, ZoneRules rules, ZoneOffsetTransition discontinuity,
                LocalDateTime newDateTime, OffsetDateTime oldDateTime) {
            throw new CalendricalException("Local time " + newDateTime +
                    " has two matching offsets, " + discontinuity.getOffsetBefore() +
                    " and " + discontinuity.getOffsetAfter() + ", in time zone " + zone);
        }
    }

    //-----------------------------------------------------------------------
    /**
     * Returns the pre-transition zone resolver, which returns the instant
     * one nanosecond before the transition for gaps, and the earlier offset
     * for overlaps.
     *
     * @return the pre-transition resolver, never null
     */
    public static ZoneResolver preTransition() {
        return PreTransition.INSTANCE;
    }

    /**
     * Class implementing preTransition resolver.
     */
    private static class PreTransition extends ZoneResolver {
        /** The singleton instance. */
        private static final ZoneResolver INSTANCE = new PreTransition();
       
        /** {@inheritDoc} */
        @Override
        protected OffsetDateTime handleGap(
                TimeZone zone, ZoneRules rules, ZoneOffsetTransition discontinuity,
                LocalDateTime newDateTime, OffsetDateTime oldDateTime) {
            Instant instantBefore = discontinuity.getInstant().minusNanos(1);
            return OffsetDateTime.fromInstant(instantBefore, discontinuity.getOffsetBefore());
        }
        /** {@inheritDoc} */
        @Override
        protected OffsetDateTime handleOverlap(
                TimeZone zone, ZoneRules rules, ZoneOffsetTransition discontinuity,
                LocalDateTime newDateTime, OffsetDateTime oldDateTime) {
            return OffsetDateTime.dateTime(newDateTime, discontinuity.getOffsetBefore());
        }
    }

    //-----------------------------------------------------------------------
    /**
     * Returns the post-transition zone resolver, which returns the instant
     * after the transition for gaps, and the later offset for overlaps.
     *
     * @return the post-transition resolver, never null
     */
    public static ZoneResolver postTransition() {
        return PostTransition.INSTANCE;
    }

    /**
     * Class implementing postTransition resolver.
     */
    private static class PostTransition extends ZoneResolver {
        /** The singleton instance. */
        private static final ZoneResolver INSTANCE = new PostTransition();
       
        /** {@inheritDoc} */
        @Override
        protected OffsetDateTime handleGap(
                TimeZone zone, ZoneRules rules, ZoneOffsetTransition discontinuity,
                LocalDateTime newDateTime, OffsetDateTime oldDateTime) {
            return discontinuity.getDateTimeAfter();
        }
        /** {@inheritDoc} */
        @Override
        protected OffsetDateTime handleOverlap(
                TimeZone zone, ZoneRules rules, ZoneOffsetTransition discontinuity,
                LocalDateTime newDateTime, OffsetDateTime oldDateTime) {
            return OffsetDateTime.dateTime(newDateTime, discontinuity.getOffsetAfter());
        }
    }

    //-----------------------------------------------------------------------
    /**
     * Returns the post-gap-pre-overlap zone resolver, which returns the instant
     * after the transition for gaps, and the earlier offset for overlaps.
     *
     * @return the post-transition resolver, never null
     */
    public static ZoneResolver postGapPreOverlap() {
        return PostGapPreOverlap.INSTANCE;
    }

    /**
     * Class implementing postGapPreOverlap resolver.
     */
    private static class PostGapPreOverlap extends ZoneResolver {
        /** The singleton instance. */
        private static final ZoneResolver INSTANCE = new PostGapPreOverlap();
       
        /** {@inheritDoc} */
        @Override
        protected OffsetDateTime handleGap(
                TimeZone zone, ZoneRules rules, ZoneOffsetTransition discontinuity,
                LocalDateTime newDateTime, OffsetDateTime oldDateTime) {
            return discontinuity.getDateTimeAfter();
        }
        /** {@inheritDoc} */
        @Override
        protected OffsetDateTime handleOverlap(
                TimeZone zone, ZoneRules rules, ZoneOffsetTransition discontinuity,
                LocalDateTime newDateTime, OffsetDateTime oldDateTime) {
            return OffsetDateTime.dateTime(newDateTime, discontinuity.getOffsetBefore());
        }
    }

    //-----------------------------------------------------------------------
    /**
     * Returns the retain offset resolver, which returns the instant after the
     * transition for gaps, and the same offset for overlaps.
     * <p>
     * This resolver is the same as the {{@link #postTransition()} resolver with
     * one additional rule. When processing an overlap, this resolver attempts
     * to use the same offset as the offset specified in the old date-time.
     * If that offset is invalid then the later offset is chosen
     * <p>
     * This resolver is most commonly useful when adding or subtracting time
     * from a <code>ZonedDateTime</code>.
     *
     * @return the retain offset resolver, never null
     */
    public static ZoneResolver retainOffset() {
        return RetainOffset.INSTANCE;
    }

    /**
     * Class implementing retain offset resolver.
     */
    private static class RetainOffset extends ZoneResolver {
        /** The singleton instance. */
        private static final ZoneResolver INSTANCE = new RetainOffset();
       
        /** {@inheritDoc} */
        @Override
        protected OffsetDateTime handleGap(
                TimeZone zone, ZoneRules rules, ZoneOffsetTransition discontinuity,
                LocalDateTime newDateTime, OffsetDateTime oldDateTime) {
            return discontinuity.getDateTimeAfter();
        }
        /** {@inheritDoc} */
        @Override
        protected OffsetDateTime handleOverlap(
                TimeZone zone, ZoneRules rules, ZoneOffsetTransition discontinuity,
                LocalDateTime newDateTime, OffsetDateTime oldDateTime) {
            if (oldDateTime != null && discontinuity.isValidOffset(oldDateTime.getOffset())) {
                return OffsetDateTime.dateTime(newDateTime, oldDateTime.getOffset());
            }
            return OffsetDateTime.dateTime(newDateTime, discontinuity.getOffsetAfter());
        }
    }

    //-----------------------------------------------------------------------
    /**
     * Returns the push forward resolver, which changes the time of the result
     * in a gap by adding the lenth of the gap.
     * <p>
     * If the discontinuity is a gap, then the resolver will add the length of
     * the gap in seconds to the local time.
     * For example, given a gap from 01:00 to 02:00 and a time of 01:20, this
     * will add one hour to result in 02:20.
     * <p>
     * If the discontinuity is an overlap, then the resolver will choose the
     * later of the two offsets.
     *
     * @return the push forward resolver, never null
     */
    public static ZoneResolver pushForward() {
        return PushForward.INSTANCE;
    }

    /**
     * Class implementing push forward resolver.
     */
    private static class PushForward extends ZoneResolver {
        /** The singleton instance. */
        private static final ZoneResolver INSTANCE = new PushForward();
       
        /** {@inheritDoc} */
        @Override
        protected OffsetDateTime handleGap(
                TimeZone zone, ZoneRules rules, ZoneOffsetTransition discontinuity,
                LocalDateTime newDateTime, OffsetDateTime oldDateTime) {
            LocalDateTime result = newDateTime.plus(discontinuity.getTransitionSize());
            return OffsetDateTime.dateTime(result, discontinuity.getOffsetAfter());
        }
        /** {@inheritDoc} */
        @Override
        protected OffsetDateTime handleOverlap(
                TimeZone zone, ZoneRules rules, ZoneOffsetTransition discontinuity,
                LocalDateTime newDateTime, OffsetDateTime oldDateTime) {
            return OffsetDateTime.dateTime(newDateTime, discontinuity.getOffsetAfter());
        }
    }

    //-----------------------------------------------------------------------
    /**
     * Creates a combined resolver, using two different strategies for gap and overlap.
     * <p>
     * If either argument is <code>null</code> then the {@link #strict()} resolver is used.
     *
     * @param gapResolver  the resolver to use for a gap, null means strict
     * @param overlapResolver  the resolver to use for an overlap, null means strict
     * @return the combination resolver, never null
     */
    public static ZoneResolver combination(ZoneResolver gapResolver, ZoneResolver overlapResolver) {
        gapResolver = (gapResolver == null ? strict() : gapResolver);
        overlapResolver = (overlapResolver == null ? strict() : overlapResolver);
        if (gapResolver == overlapResolver) {
            return gapResolver;
        }
        return new Combination(gapResolver, overlapResolver);
    }

    /**
     * Class implementing combination resolver.
     */
    private static class Combination extends ZoneResolver {
        /** The gap resolver. */
        private final ZoneResolver gapResolver;
        /** The overlap resolver. */
        private final ZoneResolver overlapResolver;
       
        /**
         * Constructor.
         * @param gapResolver  the resolver to use for a gap, not null
         * @param overlapResolver  the resolver to use for an overlap, not null
         */
        public Combination(ZoneResolver gapResolver, ZoneResolver overlapResolver) {
            this.gapResolver = gapResolver;
            this.overlapResolver = overlapResolver;
        }
        /** {@inheritDoc} */
        @Override
        protected OffsetDateTime handleGap(
                TimeZone zone, ZoneRules rules, ZoneOffsetTransition discontinuity,
                LocalDateTime newDateTime, OffsetDateTime oldDateTime) {
            return gapResolver.handleGap(zone, rules, discontinuity, newDateTime, oldDateTime);
        }
        /** {@inheritDoc} */
        @Override
        protected OffsetDateTime handleOverlap(
                TimeZone zone, ZoneRules rules, ZoneOffsetTransition discontinuity,
                LocalDateTime newDateTime, OffsetDateTime oldDateTime) {
            return overlapResolver.handleOverlap(zone, rules, discontinuity, newDateTime, oldDateTime);
        }
    }

}
TOP

Related Classes of javax.time.calendar.ZoneResolvers$PostTransition

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.