Package javax.time.calendar

Source Code of javax.time.calendar.DateAdjusters$DayOfWeekInMonth

/*
* 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 static javax.time.calendar.field.MonthOfYear.*;

import java.io.Serializable;

import javax.time.calendar.field.DayOfMonth;
import javax.time.calendar.field.DayOfWeek;

/**
* Provides common implementations of <code>DateAdjuster</code>.
* <p>
* DateAdjusters is a utility class.
* All adjusters returned are immutable and thread-safe.
*
* @author Michael Nascimento Santos
* @author Stephen Colebourne
*/
public final class DateAdjusters {

    /**
     * Private constructor since this is a utility class
     */
    private DateAdjusters() {
    }

    //-----------------------------------------------------------------------
    /**
     * Returns the last day of month adjuster, which returns a new date with
     * the day of month changed to be the last valid day of the month.
     * <p>
     * The input 2007-01-15 will return 2007-01-31.<br />
     * The input 2007-02-15 will return 2007-02-28.<br />
     * The input 2007-03-15 will return 2007-03-31.<br />
     * The input 2007-04-15 will return 2007-04-30.<br />
     * The input 2008-02-15 will return 2008-02-29.
     *
     * @return the last day of month adjuster, never null
     */
    public static DateAdjuster lastDayOfMonth() {
        return Impl.LAST_DAY_OF_MONTH;
    }

    /**
     * Returns the last day of year adjuster, which returns a new date with
     * the day of year changed to be the last valid day of the year.
     * <p>
     * The input 2007-01-15 will return 2007-12-31.<br />
     * The input 2008-02-15 will return 2008-12-31.<br />
     *
     * @return the last day of year adjuster, never null
     */
    public static DateAdjuster lastDayOfYear() {
        return Impl.LAST_DAY_OF_YEAR;
    }

    /**
     * Returns the next non weekend day adjuster, which adjusts the date one day
     * forward skipping Saturday and Sunday.
     *
     * @return the next working day adjuster, never null
     */
    public static DateAdjuster nextNonWeekendDay() {
        return Impl.NEXT_NON_WEEKEND;
    }

    //-----------------------------------------------------------------------
    /**
     * Enum implementing the adjusters.
     */
    private static enum Impl implements DateAdjuster {
        /** Last day of month adjuster. */
        LAST_DAY_OF_MONTH {
            /** {@inheritDoc} */
            public LocalDate adjustDate(LocalDate date) {
                DayOfMonth dom = date.getMonthOfYear().getLastDayOfMonth(date.toYear());
                return date.with(dom);
            }
        },
        /** Last day of year adjuster. */
        LAST_DAY_OF_YEAR {
            /** {@inheritDoc} */
            public LocalDate adjustDate(LocalDate date) {
                return LocalDate.date(date.getYear(), DECEMBER, 31);
            }
        },
        /** Next non weekend day adjuster. */
        NEXT_NON_WEEKEND {
            /** {@inheritDoc} */
            public LocalDate adjustDate(LocalDate date) {
                DayOfWeek dow = date.getDayOfWeek();
                switch (dow) {
                    case SATURDAY:
                        return date.plusDays(2);
                    case FRIDAY:
                        return date.plusDays(3);
                    default:
                        return date.plusDays(1);
                }
            }
        },
    }

    //-----------------------------------------------------------------------
    /**
     * Returns the first in month adjuster, which returns a new date
     * in the same month with the first matching day of week. This is used for
     * expressions like 'first tuesday in March'.
     * <p>
     * The input 2007-12-15 for (MONDAY) will return 2007-12-03.<br />
     * The input 2007-12-15 for (TUESDAY) will return 2007-12-04.<br />
     *
     * @param dayOfWeek  the day of week, not null
     * @return the first in month adjuster, never null
     */
    public static DateAdjuster firstInMonth(DayOfWeek dayOfWeek) {
        if (dayOfWeek == null) {
            throw new NullPointerException("DayOfWeek must not be null");
        }
        return new DayOfWeekInMonth(1, dayOfWeek);
    }

    /**
     * Returns the day of week in month adjuster, which returns a new date
     * in the same month with the ordinal day of week. This is used for
     * expressions like 'second tuesday in March'.
     * <p>
     * The input 2007-12-15 for (1,MONDAY) will return 2007-12-03.<br />
     * The input 2007-12-15 for (2,TUESDAY) will return 2007-12-11.<br />
     * The input 2007-12-15 for (3,TUESDAY) will return 2007-12-18.<br />
     * The input 2007-12-15 for (4,TUESDAY) will return 2007-12-25.<br />
     * The input 2007-12-15 for (5,TUESDAY) will return 2008-01-01.<br />
     * <p>
     * If the ordinal is 5 and there is no 5th of the requested day of week,
     * then the first of the next month is returned.
     *
     * @param ordinal  ordinal, from 1 to 5
     * @param dayOfWeek  the day of week, not null
     * @return the day of week in month adjuster, never null
     * @throws IllegalArgumentException if the ordinal is invalid
     */
    public static DateAdjuster dayOfWeekInMonth(int ordinal, DayOfWeek dayOfWeek) {
        if (ordinal < 1 || ordinal > 5) {
            throw new IllegalArgumentException("Illegal value for ordinal, value " + ordinal +
                    " is not in the range 1 to 5");
        }
        if (dayOfWeek == null) {
            throw new NullPointerException("DayOfWeek must not be null");
        }
        return new DayOfWeekInMonth(ordinal, dayOfWeek);
    }

    /**
     * Class implementing day of week in month adjuster.
     */
    private static final class DayOfWeekInMonth implements DateAdjuster, Serializable {
        /**
         * A serialization identifier for this class.
         */
        private static final long serialVersionUID = 1L;

        /** The ordinal, from 1 to 5. */
        private final int ordinal;
        /** The day of week. */
        private final DayOfWeek dayOfWeek;

        /**
         * Constructor.
         * @param ordinal  ordinal, from 1 to 5
         * @param dayOfWeek  the day of week, not null
         */
        private DayOfWeekInMonth(int ordinal, DayOfWeek dayOfWeek) {
            super();
            this.ordinal = ordinal;
            this.dayOfWeek = dayOfWeek;
        }

        /** {@inheritDoc} */
        public LocalDate adjustDate(LocalDate date) {
            LocalDate temp = date.withDayOfMonth(1);
            int curDow = temp.getDayOfWeek().ordinal();
            int newDow = dayOfWeek.ordinal();
            int dowDiff = (newDow - curDow + 7) % 7;
            dowDiff += (ordinal - 1) * 7;
            return temp.plusDays(dowDiff);
        }

        /** {@inheritDoc} */
        @Override
        public boolean equals(Object obj) {
            if (obj instanceof DayOfWeekInMonth) {
                DayOfWeekInMonth other = (DayOfWeekInMonth) obj;
                return ordinal == other.ordinal && dayOfWeek == other.dayOfWeek;
            }
            return false;
        }

        /** {@inheritDoc} */
        @Override
        public int hashCode() {
            return ordinal + 8 * dayOfWeek.ordinal();
        }
    }

    //-----------------------------------------------------------------------
    // TODO: This set of adjusters is incomplete, for example what about
    // June this year vs next June vs nextOrCurrent June vs previous...
//    /**
//     * Returns the next Monday adjuster, which adjusts the date to be the
//     * next Monday after the specified date.
//     *
//     * @return the next Monday adjuster, never null
//     */
//    public static DateAdjuster nextMonday() {
//        return new RelativeDayOfWeek(0, DayOfWeek.MONDAY);
//    }

    /**
     * Returns the next day of week adjuster, which adjusts the date to be
     * the next of the specified day of week after the specified date.
     *
     * @param dow  the day of week to move the date to, not null
     * @return the next day of week adjuster, never null
     */
    public static DateAdjuster next(DayOfWeek dow) {
        if (dow == null) {
            throw new NullPointerException("dow must not be null");
        }
        return new RelativeDayOfWeek(2, dow);
    }

    /**
     * Returns the next or current day of week adjuster, which adjusts the
     * date to be be the next of the specified day of week, returning the
     * input date if the day of week matched.
     *
     * @param dow  the day of week to move the date to, not null
     * @return the next day of week adjuster, never null
     */
    public static DateAdjuster nextOrCurrent(DayOfWeek dow) {
        if (dow == null) {
            throw new NullPointerException("dow must not be null");
        }
        return new RelativeDayOfWeek(0, dow);
    }

    /**
     * Returns the previous day of week adjuster, which adjusts the date to be
     * the previous of the specified day of week after the specified date.
     *
     * @param dow  the day of week to move the date to, not null
     * @return the next day of week adjuster, never null
     */
    public static DateAdjuster previous(DayOfWeek dow) {
        if (dow == null) {
            throw new NullPointerException("dow must not be null");
        }
        return new RelativeDayOfWeek(3, dow);
    }

    /**
     * Returns the previous or current day of week adjuster, which adjusts the
     * date to be be the previous of the specified day of week, returning the
     * input date if the day of week matched.
     *
     * @param dow  the day of week to move the date to, not null
     * @return the next day of week adjuster, never null
     */
    public static DateAdjuster previousOrCurrent(DayOfWeek dow) {
        if (dow == null) {
            throw new NullPointerException("dow must not be null");
        }
        return new RelativeDayOfWeek(1, dow);
    }

    /**
     * Implementation of next, previous or current day of week.
     */
    private static final class RelativeDayOfWeek implements DateAdjuster, Serializable {
        /**
         * A serialization identifier for this class.
         */
        private static final long serialVersionUID = 1L;
        /** Whether the current date is a valid answer. */
        private final int relative;
        /** The day of week to find. */
        private final DayOfWeek dow;

        private RelativeDayOfWeek(int relative, DayOfWeek dow) {
            this.relative = relative;
            this.dow = dow;
        }

        /** {@inheritDoc} */
        public LocalDate adjustDate(LocalDate date) {
            DayOfWeek dow = date.getDayOfWeek();
            if (relative < 2 && dow == this.dow) {
                return date;
            }
            if ((relative & 1) == 0) {
                int daysDiff = dow.ordinal() - this.dow.ordinal();
                return date.plusDays(daysDiff >= 0 ? 7 - daysDiff : -daysDiff);
            } else {
                int daysDiff = this.dow.ordinal() - dow.ordinal();
                return date.minusDays(daysDiff >= 0 ? 7 - daysDiff : -daysDiff);
            }
        }

        /** {@inheritDoc} */
        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (this == obj) {
                return true;
            }
            if (!(obj instanceof RelativeDayOfWeek)) {
                return false;
            }
            final RelativeDayOfWeek other = (RelativeDayOfWeek) obj;
            if (this.relative != other.relative) {
                return false;
            }
            if (this.dow != other.dow) {
                return false;
            }
            return true;
        }

        @Override
        public int hashCode() {
            int hash = 13;
            hash = 19 * hash + relative;
            hash = 19 * hash + dow.hashCode();
            return hash;
        }
    }
}
TOP

Related Classes of javax.time.calendar.DateAdjusters$DayOfWeekInMonth

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.