/* * ----------------------------------------------------------------------- * Copyright © 2013-2016 Meno Hochschild, <http://www.menodata.de/> * ----------------------------------------------------------------------- * This file (Weekday.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 <http://www.gnu.org/licenses/>. * ----------------------------------------------------------------------- */ package net.time4j; import net.time4j.base.GregorianDate; import net.time4j.base.GregorianMath; import net.time4j.engine.ChronoCondition; import net.time4j.format.CalendarText; import net.time4j.format.OutputContext; import net.time4j.format.TextWidth; import java.util.Locale; /** * <p>Enumeration of weekdays. </p> * * <p>Several methods with a {@code Weekmodel}-parameter support other * week models, too. </p> * * @author Meno Hochschild */ /*[deutsch] * <p>Wochentagsaufzählung. </p> * * <p>Verschiedene Methoden mit einem {@code Weekmodel}-Argument * unterstützen zusätzlich andere Wochenmodelle. </p> * * @author Meno Hochschild */ public enum Weekday implements ChronoCondition<GregorianDate> { //~ Statische Felder/Initialisierungen -------------------------------- /** Monday with the numerical ISO-value {@code 1}. */ /*[deutsch] Montag mit dem numerischen ISO-Wert {@code 1}. */ MONDAY, /** Tuesday with the numerical ISO-value {@code 2}. */ /*[deutsch] Dienstag mit dem numerischen ISO-Wert {@code 2}. */ TUESDAY, /** Wednesday with the numerical ISO-value {@code 3}. */ /*[deutsch] Mittwoch mit dem numerischen ISO-Wert {@code 3}. */ WEDNESDAY, /** Thursday with the numerical ISO-value {@code 4}. */ /*[deutsch] Donnerstag mit dem numerischen ISO-Wert {@code 4}. */ THURSDAY, /** Friday with the numerical ISO-value {@code 5}. */ /*[deutsch] Freitag mit dem numerischen ISO-Wert {@code 5}. */ FRIDAY, /** Saturday with the numerical ISO-value {@code 6}. */ /*[deutsch] Samstag mit dem numerischen ISO-Wert {@code 6}. */ SATURDAY, /** Sunday with the numerical ISO-value {@code 7}. */ /*[deutsch] Sonntag mit dem numerischen ISO-Wert {@code 7}. */ SUNDAY; private static final Weekday[] ENUMS = Weekday.values(); // Cache //~ Methoden ---------------------------------------------------------- /** * <p>Gets the corresponding numerical ISO-value. </p> * * @return {@code monday=1, tuesday=2, wednesday=3, thursday=4, friday=5, saturday=6, sunday=7} * @see #valueOf(int) * @see Weekmodel#ISO */ /*[deutsch] * <p>Liefert den korrespondierenden kalendarischen Integer-Wert * entsprechend der ISO-8601-Norm. </p> * * @return {@code monday=1, tuesday=2, wednesday=3, thursday=4, friday=5, saturday=6, sunday=7} * @see #valueOf(int) * @see Weekmodel#ISO */ public int getValue() { return (this.ordinal() + 1); } /** * <p>Gets the numerical value corresponding to the rule of given * week model on which day a week starts. </p> * * <p>In US, the rule is applied that weeks start with Sunday. If so then * this method will yield {@code 1} for {@code Weekmodel.of(Locale.US)} * (instead of the ISO-value {@code 7}). </p> * * @param model localized week model * @return localized weekday number (1 - 7) * @see Weekmodel#getFirstDayOfWeek() * @see #values(Weekmodel) * @see #valueOf(int, Weekmodel) */ /*[deutsch] * <p>Liefert eine Wochentagsnummer passend zur im Modell enthaltenen * Regel, mit welchem Tag eine Woche beginnt. </p> * * <p>Wird z.B. die in den USA übliche Regel angewandt, daß * der erste Tag einer Woche der Sonntag sein soll, dann hat der Sonntag * die Nummer 1 (statt 7 nach ISO-8601). </p> * * @param model localized week model * @return localized weekday number (1 - 7) * @see Weekmodel#getFirstDayOfWeek() * @see #values(Weekmodel) * @see #valueOf(int, Weekmodel) */ public int getValue(Weekmodel model) { int shift = model.getFirstDayOfWeek().ordinal(); return ((7 + this.ordinal() - shift) % 7) + 1; } /** * <p>Yields an array which is sorted corresponding to the rule of given * week model on which day a week starts. </p> * * <p>The alternative method generated by compiler without any parameters * creates an array sorted according to ISO-8601-standard. This method * is an overloaded variation where sorting is adjusted. </p> * * @param model localized week model * @return new weekday array * @see Weekmodel#getFirstDayOfWeek() * @see #getValue(Weekmodel) * @see #valueOf(int, Weekmodel) */ /*[deutsch] * <p>Liefert ein Array, das passend zur im Model enthaltenen Regel * sortiert ist, mit welchem Tag eine Woche beginnt. </p> * * <p>Die vom Java-Compiler generierte {@code values()}-Methode ohne * Argument richtet sich nach dem ISO-8601-Wochenmodell. Diese Methode * ist die überladene Variante, in der die Sortierung angepasst * ist. </p> * * @param model localized week model * @return new weekday array * @see Weekmodel#getFirstDayOfWeek() * @see #getValue(Weekmodel) * @see #valueOf(int, Weekmodel) */ public static Weekday[] values(Weekmodel model) { Weekday[] enums = new Weekday[7]; Weekday wd = model.getFirstDayOfWeek(); for (int i = 0; i < 7; i++) { enums[i] = wd; wd = wd.next(); } return enums; } /** * <p>Gets the enum-constant which corresponds to the given numerical * value. </p> * * @param dayOfWeek (monday=1, tuesday=2, wednesday=3, thursday=4, * friday=5, saturday=6, sunday=7) * @return weekday as enum * @throws IllegalArgumentException if the argument is out of range * @see #getValue() * @see Weekmodel#ISO */ /*[deutsch] * <p>Liefert die zum kalendarischen Integer-Wert passende * Enum-Konstante entsprechend der ISO-8601-Norm. </p> * * @param dayOfWeek (monday=1, tuesday=2, wednesday=3, thursday=4, * friday=5, saturday=6, sunday=7) * @return weekday as enum * @throws IllegalArgumentException if the argument is out of range * @see #getValue() * @see Weekmodel#ISO */ public static Weekday valueOf(int dayOfWeek) { if ((dayOfWeek < 1) || (dayOfWeek > 7)) { throw new IllegalArgumentException("Out of range: " + dayOfWeek); } return ENUMS[dayOfWeek - 1]; } /** * <p>Gets the enum-constant which corresponds to the given localized * numerical value taking into account given week model. </p> * * @param dayOfWeek localized weekday number (1 - 7) * @param model localized week model * @return weekday as enum * @throws IllegalArgumentException if the int-argument is out of range * @see Weekmodel#getFirstDayOfWeek() * @see #values(Weekmodel) * @see #getValue(Weekmodel) */ /*[deutsch] * <p>Liefert die zum kalendarischen Integer-Wert passende * Enum-Konstante passend zum angegebenen Wochenmodell. </p> * * @param dayOfWeek localized weekday number (1 - 7) * @param model localized week model * @return weekday as enum * @throws IllegalArgumentException if the int-argument is out of range * @see Weekmodel#getFirstDayOfWeek() * @see #values(Weekmodel) * @see #getValue(Weekmodel) */ public static Weekday valueOf( int dayOfWeek, Weekmodel model ) { if ( (dayOfWeek < 1) || (dayOfWeek > 7) ) { throw new IllegalArgumentException( "Weekday out of range: " + dayOfWeek); } int shift = model.getFirstDayOfWeek().ordinal(); return ENUMS[(dayOfWeek - 1 + shift) % 7]; } /** * <p>Gets the weekday corresponding to given gregorian date. </p> * * <p>The proleptic gregorian calendar as defined in ISO-8601 is the * calculation basis. That means the current leap year rule is even * applied for dates before the introduction of gregorian calendar. </p> * * @param year proleptic iso year * @param monthOfYear gregorian month * @param dayOfMonth day of month (1 - 31) * @return weekday * @throws IllegalArgumentException if the day is out of range */ /*[deutsch] * <p>Liefert den Wochentag zum angegebenen Datum. </p> * * <p>Grundlage ist der gregorianische Kalender proleptisch für * alle Zeiten ohne Kalenderwechsel angewandt. Es wird also so getan, * als ob der gregorianische Kalender schon vor dem 15. Oktober 1582 * existiert hätte, so wie im ISO-8601-Format vorgesehen. </p> * * @param year proleptic iso year * @param monthOfYear gregorian month * @param dayOfMonth day of month (1 - 31) * @return weekday * @throws IllegalArgumentException if the day is out of range */ public static Weekday valueOf( int year, Month monthOfYear, int dayOfMonth ) { return Weekday.valueOf( GregorianMath.getDayOfWeek( year, monthOfYear.getValue(), dayOfMonth ) ); } /** * <p>Rolls to the next day of week. </p> * * <p>The result is Monday if this method is applied on Sunday. </p> * * @return next weekday */ /*[deutsch] * <p>Ermittelt den nächsten Wochentag. </p> * * <p>Auf den Sonntag angewandt ist das Ergebnis der Montag. </p> * * @return next weekday */ public Weekday next() { int index = this.ordinal() + 1; if (index == 7) { index = 0; } return ENUMS[index]; } /** * <p>Rolls to the previous day of week. </p> * * <p>The result is Sunday if this method is applied on Monday. </p> * * @return previous weekday */ /*[deutsch] * <p>Ermittelt den vorherigen Wochentag. </p> * * <p>Auf den Montag angewandt ist das Ergebnis der Sonntag. </p> * * @return previous weekday */ public Weekday previous() { return this.roll(-1); } /** * <p>Rolls this day of week by given amount of days. </p> * * @param days count of days (maybe negative) * @return result of rolling operation */ /*[deutsch] * <p>Rollt um die angegebene Anzahl von Tagen vor oder zurück. </p> * * @param days count of days (maybe negative) * @return result of rolling operation */ public Weekday roll(int days) { return Weekday.valueOf((this.ordinal() + (days % 7 + 7)) % 7 + 1); } /** * <p>Equivalent to the expression * {@code getDisplayName(locale, TextWidth.WIDE, OutputContext.FORMAT)}. * </p> * * @param locale language setting * @return descriptive text (long form, never {@code null}) * @see #getDisplayName(Locale, TextWidth, OutputContext) */ /*[deutsch] * <p>Entspricht dem Ausdruck * {@code getDisplayName(locale, TextWidth.WIDE, OutputContext.FORMAT)}. * </p> * * @param locale language setting * @return descriptive text (long form, never {@code null}) * @see #getDisplayName(Locale, TextWidth, OutputContext) */ public String getDisplayName(Locale locale) { return this.getDisplayName( locale, TextWidth.WIDE, OutputContext.FORMAT); } /** * <p>Gets the description text dependent on the locale and style * parameters. </p> * * <p>The second argument controls the width of description while the * third argument is only relevant for languages which make a difference * between stand-alone forms and embedded text forms (does not matter in * English). </p> * * @param locale language setting * @param width text width * @param context output context * @return descriptive text for given locale and style (never {@code null}) */ /*[deutsch] * <p>Liefert den sprachabhängigen Beschreibungstext. </p> * * <p>Über das zweite Argument kann gesteuert werden, ob eine kurze * oder eine lange Form des Beschreibungstexts ausgegeben werden soll. Das * ist besonders sinnvoll in Benutzeroberflächen, wo zwischen der * Beschriftung und der detaillierten Erläuterung einer graphischen * Komponente unterschieden wird. Das dritte Argument ist in Sprachen von * Belang, die verschiedene grammatikalische Formen für die Ausgabe * als alleinstehend oder eingebettet in formatierten Text kennen. </p> * * @param locale language setting * @param width text width * @param context output context * @return descriptive text for given locale and style (never {@code null}) */ public String getDisplayName( Locale locale, TextWidth width, OutputContext context ) { return CalendarText.getIsoInstance(locale).getWeekdays(width, context).print(this); } @Override public boolean test(GregorianDate context) { int y = context.getYear(); int m = context.getMonth(); int dom = context.getDayOfMonth(); return (GregorianMath.getDayOfWeek(y, m, dom) == this.getValue()); } }