Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/text/CalendarBuilder.java
38829 views
/*1* Copyright (c) 2010, 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*/2425package java.text;2627import java.util.Calendar;28import static java.util.GregorianCalendar.*;2930/**31* {@code CalendarBuilder} keeps field-value pairs for setting32* the calendar fields of the given {@code Calendar}. It has the33* {@link Calendar#FIELD_COUNT FIELD_COUNT}-th field for the week year34* support. Also {@code ISO_DAY_OF_WEEK} is used to specify35* {@code DAY_OF_WEEK} in the ISO day of week numbering.36*37* <p>{@code CalendarBuilder} retains the semantic of the pseudo38* timestamp for fields. {@code CalendarBuilder} uses a single39* int array combining fields[] and stamp[] of {@code Calendar}.40*41* @author Masayoshi Okutsu42*/43class CalendarBuilder {44/*45* Pseudo time stamp constants used in java.util.Calendar46*/47private static final int UNSET = 0;48private static final int COMPUTED = 1;49private static final int MINIMUM_USER_STAMP = 2;5051private static final int MAX_FIELD = FIELD_COUNT + 1;5253public static final int WEEK_YEAR = FIELD_COUNT;54public static final int ISO_DAY_OF_WEEK = 1000; // pseudo field index5556// stamp[] (lower half) and field[] (upper half) combined57private final int[] field;58private int nextStamp;59private int maxFieldIndex;6061CalendarBuilder() {62field = new int[MAX_FIELD * 2];63nextStamp = MINIMUM_USER_STAMP;64maxFieldIndex = -1;65}6667CalendarBuilder set(int index, int value) {68if (index == ISO_DAY_OF_WEEK) {69index = DAY_OF_WEEK;70value = toCalendarDayOfWeek(value);71}72field[index] = nextStamp++;73field[MAX_FIELD + index] = value;74if (index > maxFieldIndex && index < FIELD_COUNT) {75maxFieldIndex = index;76}77return this;78}7980CalendarBuilder addYear(int value) {81field[MAX_FIELD + YEAR] += value;82field[MAX_FIELD + WEEK_YEAR] += value;83return this;84}8586boolean isSet(int index) {87if (index == ISO_DAY_OF_WEEK) {88index = DAY_OF_WEEK;89}90return field[index] > UNSET;91}9293CalendarBuilder clear(int index) {94if (index == ISO_DAY_OF_WEEK) {95index = DAY_OF_WEEK;96}97field[index] = UNSET;98field[MAX_FIELD + index] = 0;99return this;100}101102Calendar establish(Calendar cal) {103boolean weekDate = isSet(WEEK_YEAR)104&& field[WEEK_YEAR] > field[YEAR];105if (weekDate && !cal.isWeekDateSupported()) {106// Use YEAR instead107if (!isSet(YEAR)) {108set(YEAR, field[MAX_FIELD + WEEK_YEAR]);109}110weekDate = false;111}112113cal.clear();114// Set the fields from the min stamp to the max stamp so that115// the field resolution works in the Calendar.116for (int stamp = MINIMUM_USER_STAMP; stamp < nextStamp; stamp++) {117for (int index = 0; index <= maxFieldIndex; index++) {118if (field[index] == stamp) {119cal.set(index, field[MAX_FIELD + index]);120break;121}122}123}124125if (weekDate) {126int weekOfYear = isSet(WEEK_OF_YEAR) ? field[MAX_FIELD + WEEK_OF_YEAR] : 1;127int dayOfWeek = isSet(DAY_OF_WEEK) ?128field[MAX_FIELD + DAY_OF_WEEK] : cal.getFirstDayOfWeek();129if (!isValidDayOfWeek(dayOfWeek) && cal.isLenient()) {130if (dayOfWeek >= 8) {131dayOfWeek--;132weekOfYear += dayOfWeek / 7;133dayOfWeek = (dayOfWeek % 7) + 1;134} else {135while (dayOfWeek <= 0) {136dayOfWeek += 7;137weekOfYear--;138}139}140dayOfWeek = toCalendarDayOfWeek(dayOfWeek);141}142cal.setWeekDate(field[MAX_FIELD + WEEK_YEAR], weekOfYear, dayOfWeek);143}144return cal;145}146147public String toString() {148StringBuilder sb = new StringBuilder();149sb.append("CalendarBuilder:[");150for (int i = 0; i < field.length; i++) {151if (isSet(i)) {152sb.append(i).append('=').append(field[MAX_FIELD + i]).append(',');153}154}155int lastIndex = sb.length() - 1;156if (sb.charAt(lastIndex) == ',') {157sb.setLength(lastIndex);158}159sb.append(']');160return sb.toString();161}162163static int toISODayOfWeek(int calendarDayOfWeek) {164return calendarDayOfWeek == SUNDAY ? 7 : calendarDayOfWeek - 1;165}166167static int toCalendarDayOfWeek(int isoDayOfWeek) {168if (!isValidDayOfWeek(isoDayOfWeek)) {169// adjust later for lenient mode170return isoDayOfWeek;171}172return isoDayOfWeek == 7 ? SUNDAY : isoDayOfWeek + 1;173}174175static boolean isValidDayOfWeek(int dayOfWeek) {176return dayOfWeek > 0 && dayOfWeek <= 7;177}178}179180181