Path: blob/master/src/java.base/share/classes/java/time/DayOfWeek.java
41152 views
/*1* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425/*26* This file is available under and governed by the GNU General Public27* License version 2 only, as published by the Free Software Foundation.28* However, the following notice accompanied the original version of this29* file:30*31* Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos32*33* All rights reserved.34*35* Redistribution and use in source and binary forms, with or without36* modification, are permitted provided that the following conditions are met:37*38* * Redistributions of source code must retain the above copyright notice,39* this list of conditions and the following disclaimer.40*41* * Redistributions in binary form must reproduce the above copyright notice,42* this list of conditions and the following disclaimer in the documentation43* and/or other materials provided with the distribution.44*45* * Neither the name of JSR-310 nor the names of its contributors46* may be used to endorse or promote products derived from this software47* without specific prior written permission.48*49* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS50* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT51* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR52* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR53* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,54* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,55* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR56* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF57* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING58* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS59* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.60*/61package java.time;6263import static java.time.temporal.ChronoField.DAY_OF_WEEK;64import static java.time.temporal.ChronoUnit.DAYS;6566import java.time.format.DateTimeFormatterBuilder;67import java.time.format.TextStyle;68import java.time.temporal.ChronoField;69import java.time.temporal.Temporal;70import java.time.temporal.TemporalAccessor;71import java.time.temporal.TemporalAdjuster;72import java.time.temporal.TemporalField;73import java.time.temporal.TemporalQueries;74import java.time.temporal.TemporalQuery;75import java.time.temporal.UnsupportedTemporalTypeException;76import java.time.temporal.ValueRange;77import java.time.temporal.WeekFields;78import java.util.Locale;7980/**81* A day-of-week, such as 'Tuesday'.82* <p>83* {@code DayOfWeek} is an enum representing the 7 days of the week -84* Monday, Tuesday, Wednesday, Thursday, Friday, Saturday and Sunday.85* <p>86* In addition to the textual enum name, each day-of-week has an {@code int} value.87* The {@code int} value follows the ISO-8601 standard, from 1 (Monday) to 7 (Sunday).88* It is recommended that applications use the enum rather than the {@code int} value89* to ensure code clarity.90* <p>91* This enum provides access to the localized textual form of the day-of-week.92* Some locales also assign different numeric values to the days, declaring93* Sunday to have the value 1, however this class provides no support for this.94* See {@link WeekFields} for localized week-numbering.95* <p>96* <b>Do not use {@code ordinal()} to obtain the numeric representation of {@code DayOfWeek}.97* Use {@code getValue()} instead.</b>98* <p>99* This enum represents a common concept that is found in many calendar systems.100* As such, this enum may be used by any calendar system that has the day-of-week101* concept defined exactly equivalent to the ISO calendar system.102*103* @implSpec104* This is an immutable and thread-safe enum.105*106* @since 1.8107*/108public enum DayOfWeek implements TemporalAccessor, TemporalAdjuster {109110/**111* The singleton instance for the day-of-week of Monday.112* This has the numeric value of {@code 1}.113*/114MONDAY,115/**116* The singleton instance for the day-of-week of Tuesday.117* This has the numeric value of {@code 2}.118*/119TUESDAY,120/**121* The singleton instance for the day-of-week of Wednesday.122* This has the numeric value of {@code 3}.123*/124WEDNESDAY,125/**126* The singleton instance for the day-of-week of Thursday.127* This has the numeric value of {@code 4}.128*/129THURSDAY,130/**131* The singleton instance for the day-of-week of Friday.132* This has the numeric value of {@code 5}.133*/134FRIDAY,135/**136* The singleton instance for the day-of-week of Saturday.137* This has the numeric value of {@code 6}.138*/139SATURDAY,140/**141* The singleton instance for the day-of-week of Sunday.142* This has the numeric value of {@code 7}.143*/144SUNDAY;145/**146* Private cache of all the constants.147*/148private static final DayOfWeek[] ENUMS = DayOfWeek.values();149150//-----------------------------------------------------------------------151/**152* Obtains an instance of {@code DayOfWeek} from an {@code int} value.153* <p>154* {@code DayOfWeek} is an enum representing the 7 days of the week.155* This factory allows the enum to be obtained from the {@code int} value.156* The {@code int} value follows the ISO-8601 standard, from 1 (Monday) to 7 (Sunday).157*158* @param dayOfWeek the day-of-week to represent, from 1 (Monday) to 7 (Sunday)159* @return the day-of-week singleton, not null160* @throws DateTimeException if the day-of-week is invalid161*/162public static DayOfWeek of(int dayOfWeek) {163if (dayOfWeek < 1 || dayOfWeek > 7) {164throw new DateTimeException("Invalid value for DayOfWeek: " + dayOfWeek);165}166return ENUMS[dayOfWeek - 1];167}168169//-----------------------------------------------------------------------170/**171* Obtains an instance of {@code DayOfWeek} from a temporal object.172* <p>173* This obtains a day-of-week based on the specified temporal.174* A {@code TemporalAccessor} represents an arbitrary set of date and time information,175* which this factory converts to an instance of {@code DayOfWeek}.176* <p>177* The conversion extracts the {@link ChronoField#DAY_OF_WEEK DAY_OF_WEEK} field.178* <p>179* This method matches the signature of the functional interface {@link TemporalQuery}180* allowing it to be used as a query via method reference, {@code DayOfWeek::from}.181*182* @param temporal the temporal object to convert, not null183* @return the day-of-week, not null184* @throws DateTimeException if unable to convert to a {@code DayOfWeek}185*/186public static DayOfWeek from(TemporalAccessor temporal) {187if (temporal instanceof DayOfWeek) {188return (DayOfWeek) temporal;189}190try {191return of(temporal.get(DAY_OF_WEEK));192} catch (DateTimeException ex) {193throw new DateTimeException("Unable to obtain DayOfWeek from TemporalAccessor: " +194temporal + " of type " + temporal.getClass().getName(), ex);195}196}197198//-----------------------------------------------------------------------199/**200* Gets the day-of-week {@code int} value.201* <p>202* The values are numbered following the ISO-8601 standard, from 1 (Monday) to 7 (Sunday).203* See {@link java.time.temporal.WeekFields#dayOfWeek()} for localized week-numbering.204*205* @return the day-of-week, from 1 (Monday) to 7 (Sunday)206*/207public int getValue() {208return ordinal() + 1;209}210211//-----------------------------------------------------------------------212/**213* Gets the textual representation, such as 'Mon' or 'Friday'.214* <p>215* This returns the textual name used to identify the day-of-week,216* suitable for presentation to the user.217* The parameters control the style of the returned text and the locale.218* <p>219* If no textual mapping is found then the {@link #getValue() numeric value} is returned.220*221* @param style the length of the text required, not null222* @param locale the locale to use, not null223* @return the text value of the day-of-week, not null224*/225public String getDisplayName(TextStyle style, Locale locale) {226return new DateTimeFormatterBuilder().appendText(DAY_OF_WEEK, style).toFormatter(locale).format(this);227}228229//-----------------------------------------------------------------------230/**231* Checks if the specified field is supported.232* <p>233* This checks if this day-of-week can be queried for the specified field.234* If false, then calling the {@link #range(TemporalField) range} and235* {@link #get(TemporalField) get} methods will throw an exception.236* <p>237* If the field is {@link ChronoField#DAY_OF_WEEK DAY_OF_WEEK} then238* this method returns true.239* All other {@code ChronoField} instances will return false.240* <p>241* If the field is not a {@code ChronoField}, then the result of this method242* is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}243* passing {@code this} as the argument.244* Whether the field is supported is determined by the field.245*246* @param field the field to check, null returns false247* @return true if the field is supported on this day-of-week, false if not248*/249@Override250public boolean isSupported(TemporalField field) {251if (field instanceof ChronoField) {252return field == DAY_OF_WEEK;253}254return field != null && field.isSupportedBy(this);255}256257/**258* Gets the range of valid values for the specified field.259* <p>260* The range object expresses the minimum and maximum valid values for a field.261* This day-of-week is used to enhance the accuracy of the returned range.262* If it is not possible to return the range, because the field is not supported263* or for some other reason, an exception is thrown.264* <p>265* If the field is {@link ChronoField#DAY_OF_WEEK DAY_OF_WEEK} then the266* range of the day-of-week, from 1 to 7, will be returned.267* All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.268* <p>269* If the field is not a {@code ChronoField}, then the result of this method270* is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}271* passing {@code this} as the argument.272* Whether the range can be obtained is determined by the field.273*274* @param field the field to query the range for, not null275* @return the range of valid values for the field, not null276* @throws DateTimeException if the range for the field cannot be obtained277* @throws UnsupportedTemporalTypeException if the field is not supported278*/279@Override280public ValueRange range(TemporalField field) {281if (field == DAY_OF_WEEK) {282return field.range();283}284return TemporalAccessor.super.range(field);285}286287/**288* Gets the value of the specified field from this day-of-week as an {@code int}.289* <p>290* This queries this day-of-week for the value of the specified field.291* The returned value will always be within the valid range of values for the field.292* If it is not possible to return the value, because the field is not supported293* or for some other reason, an exception is thrown.294* <p>295* If the field is {@link ChronoField#DAY_OF_WEEK DAY_OF_WEEK} then the296* value of the day-of-week, from 1 to 7, will be returned.297* All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.298* <p>299* If the field is not a {@code ChronoField}, then the result of this method300* is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}301* passing {@code this} as the argument. Whether the value can be obtained,302* and what the value represents, is determined by the field.303*304* @param field the field to get, not null305* @return the value for the field, within the valid range of values306* @throws DateTimeException if a value for the field cannot be obtained or307* the value is outside the range of valid values for the field308* @throws UnsupportedTemporalTypeException if the field is not supported or309* the range of values exceeds an {@code int}310* @throws ArithmeticException if numeric overflow occurs311*/312@Override313public int get(TemporalField field) {314if (field == DAY_OF_WEEK) {315return getValue();316}317return TemporalAccessor.super.get(field);318}319320/**321* Gets the value of the specified field from this day-of-week as a {@code long}.322* <p>323* This queries this day-of-week for the value of the specified field.324* If it is not possible to return the value, because the field is not supported325* or for some other reason, an exception is thrown.326* <p>327* If the field is {@link ChronoField#DAY_OF_WEEK DAY_OF_WEEK} then the328* value of the day-of-week, from 1 to 7, will be returned.329* All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.330* <p>331* If the field is not a {@code ChronoField}, then the result of this method332* is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}333* passing {@code this} as the argument. Whether the value can be obtained,334* and what the value represents, is determined by the field.335*336* @param field the field to get, not null337* @return the value for the field338* @throws DateTimeException if a value for the field cannot be obtained339* @throws UnsupportedTemporalTypeException if the field is not supported340* @throws ArithmeticException if numeric overflow occurs341*/342@Override343public long getLong(TemporalField field) {344if (field == DAY_OF_WEEK) {345return getValue();346} else if (field instanceof ChronoField) {347throw new UnsupportedTemporalTypeException("Unsupported field: " + field);348}349return field.getFrom(this);350}351352//-----------------------------------------------------------------------353/**354* Returns the day-of-week that is the specified number of days after this one.355* <p>356* The calculation rolls around the end of the week from Sunday to Monday.357* The specified period may be negative.358* <p>359* This instance is immutable and unaffected by this method call.360*361* @param days the days to add, positive or negative362* @return the resulting day-of-week, not null363*/364public DayOfWeek plus(long days) {365int amount = (int) (days % 7);366return ENUMS[(ordinal() + (amount + 7)) % 7];367}368369/**370* Returns the day-of-week that is the specified number of days before this one.371* <p>372* The calculation rolls around the start of the year from Monday to Sunday.373* The specified period may be negative.374* <p>375* This instance is immutable and unaffected by this method call.376*377* @param days the days to subtract, positive or negative378* @return the resulting day-of-week, not null379*/380public DayOfWeek minus(long days) {381return plus(-(days % 7));382}383384//-----------------------------------------------------------------------385/**386* Queries this day-of-week using the specified query.387* <p>388* This queries this day-of-week using the specified query strategy object.389* The {@code TemporalQuery} object defines the logic to be used to390* obtain the result. Read the documentation of the query to understand391* what the result of this method will be.392* <p>393* The result of this method is obtained by invoking the394* {@link TemporalQuery#queryFrom(TemporalAccessor)} method on the395* specified query passing {@code this} as the argument.396*397* @param <R> the type of the result398* @param query the query to invoke, not null399* @return the query result, null may be returned (defined by the query)400* @throws DateTimeException if unable to query (defined by the query)401* @throws ArithmeticException if numeric overflow occurs (defined by the query)402*/403@SuppressWarnings("unchecked")404@Override405public <R> R query(TemporalQuery<R> query) {406if (query == TemporalQueries.precision()) {407return (R) DAYS;408}409return TemporalAccessor.super.query(query);410}411412/**413* Adjusts the specified temporal object to have this day-of-week.414* <p>415* This returns a temporal object of the same observable type as the input416* with the day-of-week changed to be the same as this.417* <p>418* The adjustment is equivalent to using {@link Temporal#with(TemporalField, long)}419* passing {@link ChronoField#DAY_OF_WEEK} as the field.420* Note that this adjusts forwards or backwards within a Monday to Sunday week.421* See {@link java.time.temporal.WeekFields#dayOfWeek()} for localized week start days.422* See {@code TemporalAdjuster} for other adjusters with more control,423* such as {@code next(MONDAY)}.424* <p>425* In most cases, it is clearer to reverse the calling pattern by using426* {@link Temporal#with(TemporalAdjuster)}:427* <pre>428* // these two lines are equivalent, but the second approach is recommended429* temporal = thisDayOfWeek.adjustInto(temporal);430* temporal = temporal.with(thisDayOfWeek);431* </pre>432* <p>433* For example, given a date that is a Wednesday, the following are output:434* <pre>435* dateOnWed.with(MONDAY); // two days earlier436* dateOnWed.with(TUESDAY); // one day earlier437* dateOnWed.with(WEDNESDAY); // same date438* dateOnWed.with(THURSDAY); // one day later439* dateOnWed.with(FRIDAY); // two days later440* dateOnWed.with(SATURDAY); // three days later441* dateOnWed.with(SUNDAY); // four days later442* </pre>443* <p>444* This instance is immutable and unaffected by this method call.445*446* @param temporal the target object to be adjusted, not null447* @return the adjusted object, not null448* @throws DateTimeException if unable to make the adjustment449* @throws ArithmeticException if numeric overflow occurs450*/451@Override452public Temporal adjustInto(Temporal temporal) {453return temporal.with(DAY_OF_WEEK, getValue());454}455456}457458459