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

net.time4j.WeekdayInMonthElement Maven / Gradle / Ivy

There is a newer version: 4.38
Show newest version
/*
 * -----------------------------------------------------------------------
 * Copyright © 2013-2016 Meno Hochschild, 
 * -----------------------------------------------------------------------
 * This file (WeekdayInMonthElement.java) is part of project Time4J.
 *
 * Time4J is free software: You can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation, either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * Time4J is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Time4J. If not, see .
 * -----------------------------------------------------------------------
 */

package net.time4j;

import net.time4j.base.GregorianMath;
import net.time4j.engine.ChronoEntity;
import net.time4j.engine.ChronoException;
import net.time4j.engine.ChronoOperator;
import net.time4j.format.NumericalElement;

import java.io.ObjectStreamException;


/**
 * 

Das Element für den x-ten Wochentag im Monat.

* *

Eine Instanz ist erhältlich über den Ausdruck * {@link PlainDate#WEEKDAY_IN_MONTH}. Diese Klasse bietet neben * den vom Interface {@code AdjustableElement} geerbten Methoden * weitere Spezialmethoden zum Setzen des Wochentags im Monat.

* * @author Meno Hochschild * @doctags.concurrency {immutable} */ final class WeekdayInMonthElement extends AbstractDateElement implements OrdinalWeekdayElement, NumericalElement { //~ Statische Felder/Initialisierungen -------------------------------- /** *

Singleton.

*/ static final WeekdayInMonthElement INSTANCE = new WeekdayInMonthElement(); private static final int LAST = Integer.MAX_VALUE; private static final long serialVersionUID = -2378018589067147278L; //~ Konstruktoren ----------------------------------------------------- private WeekdayInMonthElement() { super("WEEKDAY_IN_MONTH"); } //~ Methoden ---------------------------------------------------------- @Override public Class getType() { return Integer.class; } @Override public char getSymbol() { return 'F'; } @Override public int numerical(Integer value) { return value.intValue(); } /** * Definiert das Standardminimum. * * @return {@code 1} */ @Override public Integer getDefaultMinimum() { return Integer.valueOf(1); } /** * Definiert das Standardmaximum. * * @return {@code 5} */ @Override public Integer getDefaultMaximum() { return Integer.valueOf(5); } @Override public boolean isDateElement() { return true; } @Override public boolean isTimeElement() { return false; } @Override public ElementOperator setToFirst(Weekday dayOfWeek) { return this.setTo(1, dayOfWeek); } @Override public ElementOperator setToSecond(Weekday dayOfWeek) { return this.setTo(2, dayOfWeek); } @Override public ElementOperator setToThird(Weekday dayOfWeek) { return this.setTo(3, dayOfWeek); } @Override public ElementOperator setToFourth(Weekday dayOfWeek) { return this.setTo(4, dayOfWeek); } @Override public ElementOperator setToLast(Weekday dayOfWeek) { return this.setTo(LAST, dayOfWeek); } @Override public ElementOperator setTo( int ordinal, Weekday dayOfWeek ) { return new SpecialOperator(ordinal, dayOfWeek); } @Override protected boolean isSingleton() { return true; // exists only once in PlainDate } private Object readResolve() throws ObjectStreamException { return INSTANCE; } //~ Innere Klassen ---------------------------------------------------- private static class SpecialOperator extends ElementOperator { //~ Instanzvariablen ---------------------------------------------- private final int ordinal; private final Weekday dayOfWeek; private final ChronoOperator specialTS; //~ Konstruktoren ------------------------------------------------- SpecialOperator( int ordinal, Weekday dayOfWeek ) { super(WeekdayInMonthElement.INSTANCE, OP_WIM); if (dayOfWeek == null) { throw new NullPointerException("Missing value."); } this.ordinal = ordinal; this.dayOfWeek = dayOfWeek; this.specialTS = this::doApply; } //~ Methoden ------------------------------------------------------ @Override public PlainDate apply(PlainDate entity) { return this.doApply(entity); } @Override ChronoOperator onTimestamp() { return this.specialTS; } private > T doApply(T entity) { if (entity.contains(PlainDate.CALENDAR_DATE)) { PlainDate date = entity.get(PlainDate.CALENDAR_DATE); Weekday current = date.get(PlainDate.DAY_OF_WEEK); int delta = this.dayOfWeek.getValue() - current.getValue(); int dom = date.getDayOfMonth() + delta; int days; if (this.ordinal == LAST) { days = (5 - (Math.floorDiv(dom - 1, 7) + 1)) * 7 + delta; int max = GregorianMath.getLengthOfMonth(date.getYear(), date.getMonth()); if (date.getDayOfMonth() + days > max) { days -= 7; } } else { days = (this.ordinal - (Math.floorDiv(dom - 1, 7) + 1)) * 7 + delta; } date = date.plus(days, CalendarUnit.DAYS); return entity.with(PlainDate.CALENDAR_DATE, date); } else { throw new ChronoException( "Rule not found for ordinal day of week in month: " + entity); } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy