BaseCalendar.java revision 51b1b6997fd3f980076b8081f7f1165ccc2a4008
151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage sun.util.calendar; 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.Locale; 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.TimeZone; 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The <code>BaseCalendar</code> provides basic calendar calculation 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * functions to support the Julian, Gregorian, and Gregorian-based 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * calendar systems. 3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Masayoshi Okutsu 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.5 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic abstract class BaseCalendar extends AbstractCalendar { 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final int JANUARY = 1; 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final int FEBRUARY = 2; 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final int MARCH = 3; 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final int APRIL = 4; 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final int MAY = 5; 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final int JUNE = 6; 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final int JULY = 7; 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final int AUGUST = 8; 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final int SEPTEMBER = 9; 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final int OCTOBER = 10; 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final int NOVEMBER = 11; 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final int DECEMBER = 12; 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // day of week constants 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final int SUNDAY = 1; 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final int MONDAY = 2; 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final int TUESDAY = 3; 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final int WEDNESDAY = 4; 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final int THURSDAY = 5; 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final int FRIDAY = 6; 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final int SATURDAY = 7; 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // The base Gregorian year of FIXED_DATES[] 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int BASE_YEAR = 1970; 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Pre-calculated fixed dates of January 1 from BASE_YEAR 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // (Gregorian). This table covers all the years that can be 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // supported by the POSIX time_t (32-bit) after the Epoch. Note 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // that the data type is int[]. 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int[] FIXED_DATES = { 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 719163, // 1970 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 719528, // 1971 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 719893, // 1972 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 720259, // 1973 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 720624, // 1974 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 720989, // 1975 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 721354, // 1976 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 721720, // 1977 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 722085, // 1978 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 722450, // 1979 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 722815, // 1980 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 723181, // 1981 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 723546, // 1982 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 723911, // 1983 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 724276, // 1984 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 724642, // 1985 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 725007, // 1986 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 725372, // 1987 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 725737, // 1988 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 726103, // 1989 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 726468, // 1990 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 726833, // 1991 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 727198, // 1992 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 727564, // 1993 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 727929, // 1994 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 728294, // 1995 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 728659, // 1996 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 729025, // 1997 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 729390, // 1998 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 729755, // 1999 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 730120, // 2000 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 730486, // 2001 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 730851, // 2002 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 731216, // 2003 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 731581, // 2004 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 731947, // 2005 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 732312, // 2006 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 732677, // 2007 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 733042, // 2008 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 733408, // 2009 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 733773, // 2010 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 734138, // 2011 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 734503, // 2012 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 734869, // 2013 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 735234, // 2014 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 735599, // 2015 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 735964, // 2016 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 736330, // 2017 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 736695, // 2018 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 737060, // 2019 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 737425, // 2020 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 737791, // 2021 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 738156, // 2022 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 738521, // 2023 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 738886, // 2024 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 739252, // 2025 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 739617, // 2026 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 739982, // 2027 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 740347, // 2028 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 740713, // 2029 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 741078, // 2030 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 741443, // 2031 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 741808, // 2032 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 742174, // 2033 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 742539, // 2034 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 742904, // 2035 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 743269, // 2036 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 743635, // 2037 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 744000, // 2038 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 744365, // 2039 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski }; 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public abstract static class Date extends CalendarDate { 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected Date() { 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski super(); 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected Date(TimeZone zone) { 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski super(zone); 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Date setNormalizedDate(int normalizedYear, int month, int dayOfMonth) { 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski setNormalizedYear(normalizedYear); 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski setMonth(month).setDayOfMonth(dayOfMonth); 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return this; 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public abstract int getNormalizedYear(); 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public abstract void setNormalizedYear(int normalizedYear); 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Cache for the fixed date of January 1 and year length of the 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // cachedYear. A simple benchmark showed 7% performance 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // improvement with >90% cache hit. The initial values are for Gregorian. 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int cachedYear = 2004; 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long cachedFixedDateJan1 = 731581L; 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long cachedFixedDateNextJan1 = cachedFixedDateJan1 + 366; 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected final boolean hit(int year) { 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return year == cachedYear; 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected final boolean hit(long fixedDate) { 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (fixedDate >= cachedFixedDateJan1 && 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski fixedDate < cachedFixedDateNextJan1); 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected int getCachedYear() { 17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return cachedYear; 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected long getCachedJan1() { 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return cachedFixedDateJan1; 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected void setCache(int year, long jan1, int len) { 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cachedYear = year; 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cachedFixedDateJan1 = jan1; 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cachedFixedDateNextJan1 = jan1 + len; 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean validate(CalendarDate date) { 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Date bdate = (Date) date; 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bdate.isNormalized()) { 19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int month = bdate.getMonth(); 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (month < JANUARY || month > DECEMBER) { 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int d = bdate.getDayOfMonth(); 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (d <= 0 || d > getMonthLength(bdate.getNormalizedYear(), month)) { 20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int dow = bdate.getDayOfWeek(); 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (dow != bdate.FIELD_UNDEFINED && dow != getDayOfWeek(bdate)) { 20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!validateTime(date)) { 21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bdate.setNormalized(true); 21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean normalize(CalendarDate date) { 21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (date.isNormalized()) { 22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Date bdate = (Date) date; 22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski TimeZone zi = bdate.getZone(); 22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // If the date has a time zone, then we need to recalculate 22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the calendar fields. Let getTime() do it. 22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (zi != null) { 22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getTime(date); 23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int days = normalizeTime(bdate); 23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski normalizeMonth(bdate); 23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long d = (long)bdate.getDayOfMonth() + days; 23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int m = bdate.getMonth(); 23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int y = bdate.getNormalizedYear(); 23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int ml = getMonthLength(y, m); 23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!(d > 0 && d <= ml)) { 24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (d <= 0 && d > -28) { 24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ml = getMonthLength(y, --m); 24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski d += ml; 24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bdate.setDayOfMonth((int) d); 24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (m == 0) { 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski m = DECEMBER; 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bdate.setNormalizedYear(y - 1); 24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bdate.setMonth(m); 25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (d > ml && d < (ml + 28)) { 25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski d -= ml; 25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ++m; 25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bdate.setDayOfMonth((int)d); 25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (m > DECEMBER) { 25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bdate.setNormalizedYear(y + 1); 25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski m = JANUARY; 25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bdate.setMonth(m); 25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long fixedDate = d + getFixedDate(y, m, 1, bdate) - 1L; 26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getCalendarDateFromFixedDate(bdate, fixedDate); 26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bdate.setDayOfWeek(getDayOfWeek(bdate)); 26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski date.setLeapYear(isLeapYear(bdate.getNormalizedYear())); 26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski date.setZoneOffset(0); 26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski date.setDaylightSaving(0); 26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bdate.setNormalized(true); 27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void normalizeMonth(CalendarDate date) { 27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Date bdate = (Date) date; 27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int year = bdate.getNormalizedYear(); 27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long month = bdate.getMonth(); 27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (month <= 0) { 27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long xm = 1L - month; 27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski year -= (int)((xm / 12) + 1); 28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski month = 13 - (xm % 12); 28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bdate.setNormalizedYear(year); 28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bdate.setMonth((int) month); 28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (month > DECEMBER) { 28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski year += (int)((month - 1) / 12); 28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski month = ((month - 1)) % 12 + 1; 28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bdate.setNormalizedYear(year); 28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bdate.setMonth((int) month); 28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns 366 if the specified date is in a leap year, or 365 29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * otherwise This method does not perform the normalization with 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the specified <code>CalendarDate</code>. The 29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>CalendarDate</code> must be normalized to get a correct 29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * value. 29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param a <code>CalendarDate</code> 29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return a year length in days 30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws ClassCastException if the specified date is not a 30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@link BaseCalendar.Date} 30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int getYearLength(CalendarDate date) { 30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return isLeapYear(((Date)date).getNormalizedYear()) ? 366 : 365; 30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int getYearLengthInMonths(CalendarDate date) { 30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 12; 30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static final int[] DAYS_IN_MONTH 31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 12 1 2 3 4 5 6 7 8 9 10 11 12 31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski = { 31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static final int[] ACCUMULATED_DAYS_IN_MONTH 31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 12/1 1/1 2/1 3/1 4/1 5/1 6/1 7/1 8/1 9/1 10/1 11/1 12/1 31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski = { -30, 0, 31, 59, 90,120,151,181,212,243, 273, 304, 334}; 31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static final int[] ACCUMULATED_DAYS_IN_MONTH_LEAP 31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 12/1 1/1 2/1 3/1 4/1 5/1 6/1 7/1 8/1 9/1 10/1 11/1 12/1 32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski = { -30, 0, 31, 59+1, 90+1,120+1,151+1,181+1,212+1,243+1, 273+1, 304+1, 334+1}; 32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int getMonthLength(CalendarDate date) { 32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Date gdate = (Date) date; 32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int month = gdate.getMonth(); 32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (month < JANUARY || month > DECEMBER) { 32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("Illegal month value: " + month); 32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return getMonthLength(gdate.getNormalizedYear(), month); 32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // accepts 0 (December in the previous year) to 12. 33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final int getMonthLength(int year, int month) { 33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int days = DAYS_IN_MONTH[month]; 33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (month == FEBRUARY && isLeapYear(year)) { 33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski days++; 33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return days; 33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public long getDayOfYear(CalendarDate date) { 34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return getDayOfYear(((Date)date).getNormalizedYear(), 34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski date.getMonth(), 34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski date.getDayOfMonth()); 34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski final long getDayOfYear(int year, int month, int dayOfMonth) { 34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (long) dayOfMonth 34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + (isLeapYear(year) ? 34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ACCUMULATED_DAYS_IN_MONTH_LEAP[month] : ACCUMULATED_DAYS_IN_MONTH[month]); 35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // protected 35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public long getFixedDate(CalendarDate date) { 35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!date.isNormalized()) { 35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski normalizeMonth(date); 35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return getFixedDate(((Date)date).getNormalizedYear(), 35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski date.getMonth(), 35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski date.getDayOfMonth(), 36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (BaseCalendar.Date) date); 36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // public for java.util.GregorianCalendar 36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public long getFixedDate(int year, int month, int dayOfMonth, BaseCalendar.Date cache) { 36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean isJan1 = month == JANUARY && dayOfMonth == 1; 36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Look up the one year cache 36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cache != null && cache.hit(year)) { 36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isJan1) { 37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return cache.getCachedJan1(); 37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return cache.getCachedJan1() + getDayOfYear(year, month, dayOfMonth) - 1; 37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Look up the pre-calculated fixed date table 37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = year - BASE_YEAR; 37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (n >= 0 && n < FIXED_DATES.length) { 37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long jan1 = FIXED_DATES[n]; 37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cache != null) { 38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cache.setCache(year, jan1, isLeapYear(year) ? 366 : 365); 38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return isJan1 ? jan1 : jan1 + getDayOfYear(year, month, dayOfMonth) - 1; 38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long prevyear = (long)year - 1; 38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long days = dayOfMonth; 38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (prevyear >= 0) { 38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski days += (365 * prevyear) 39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + (prevyear / 4) 39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski - (prevyear / 100) 39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + (prevyear / 400) 39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + ((367 * month - 362) / 12); 39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski days += (365 * prevyear) 39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + CalendarUtils.floorDivide(prevyear, 4) 39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski - CalendarUtils.floorDivide(prevyear, 100) 39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + CalendarUtils.floorDivide(prevyear, 400) 39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski + CalendarUtils.floorDivide((367 * month - 362), 12); 40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (month > FEBRUARY) { 40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski days -= isLeapYear(year) ? 1 : 2; 40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // If it's January 1, update the cache. 40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cache != null && isJan1) { 40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cache.setCache(year, days, isLeapYear(year) ? 366 : 365); 40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return days; 41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Calculates calendar fields and store them in the specified 41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>CalendarDate</code>. 41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // should be 'protected' 41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void getCalendarDateFromFixedDate(CalendarDate date, 42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long fixedDate) { 42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Date gdate = (Date) date; 42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int year; 42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long jan1; 42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean isLeap; 42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (gdate.hit(fixedDate)) { 42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski year = gdate.getCachedYear(); 42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jan1 = gdate.getCachedJan1(); 42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isLeap = isLeapYear(year); 42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Looking up FIXED_DATES[] here didn't improve performance 43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // much. So we calculate year and jan1. getFixedDate() 43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // will look up FIXED_DATES[] actually. 43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski year = getGregorianYearFromFixedDate(fixedDate); 43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski jan1 = getFixedDate(year, JANUARY, 1, null); 43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isLeap = isLeapYear(year); 43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Update the cache data 43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski gdate.setCache (year, jan1, isLeap ? 366 : 365); 43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int priorDays = (int)(fixedDate - jan1); 44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long mar1 = jan1 + 31 + 28; 44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isLeap) { 44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ++mar1; 44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (fixedDate >= mar1) { 44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski priorDays += isLeap ? 1 : 2; 44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int month = 12 * priorDays + 373; 44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (month > 0) { 45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski month /= 367; 45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski month = CalendarUtils.floorDivide(month, 367); 45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long month1 = jan1 + ACCUMULATED_DAYS_IN_MONTH[month]; 45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isLeap && month >= MARCH) { 45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ++month1; 45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int dayOfMonth = (int)(fixedDate - month1) + 1; 45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int dayOfWeek = getDayOfWeekFromFixedDate(fixedDate); 46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert dayOfWeek > 0 : "negative day of week " + dayOfWeek; 46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski gdate.setNormalizedYear(year); 46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski gdate.setMonth(month); 46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski gdate.setDayOfMonth(dayOfMonth); 46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski gdate.setDayOfWeek(dayOfWeek); 46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski gdate.setLeapYear(isLeap); 46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski gdate.setNormalized(true); 46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the day of week of the given Gregorian date. 47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int getDayOfWeek(CalendarDate date) { 47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long fixedDate = getFixedDate(date); 47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return getDayOfWeekFromFixedDate(fixedDate); 47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static final int getDayOfWeekFromFixedDate(long fixedDate) { 47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // The fixed day 1 (January 1, 1 Gregorian) is Monday. 47951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (fixedDate >= 0) { 48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (int)(fixedDate % 7) + SUNDAY; 48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 48251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (int)CalendarUtils.mod(fixedDate, 7) + SUNDAY; 48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int getYearFromFixedDate(long fixedDate) { 48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return getGregorianYearFromFixedDate(fixedDate); 48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the Gregorian year number of the given fixed date. 49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski final int getGregorianYearFromFixedDate(long fixedDate) { 49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long d0; 49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int d1, d2, d3, d4; 49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n400, n100, n4, n1; 49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int year; 49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (fixedDate > 0) { 49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski d0 = fixedDate - 1; 50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n400 = (int)(d0 / 146097); 50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski d1 = (int)(d0 % 146097); 50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n100 = d1 / 36524; 50351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski d2 = d1 % 36524; 50451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n4 = d2 / 1461; 50551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski d3 = d2 % 1461; 50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n1 = d3 / 365; 50751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski d4 = (d3 % 365) + 1; 50851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski d0 = fixedDate - 1; 51051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n400 = (int)CalendarUtils.floorDivide(d0, 146097L); 51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski d1 = (int)CalendarUtils.mod(d0, 146097L); 51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n100 = CalendarUtils.floorDivide(d1, 36524); 51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski d2 = CalendarUtils.mod(d1, 36524); 51451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n4 = CalendarUtils.floorDivide(d2, 1461); 51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski d3 = CalendarUtils.mod(d2, 1461); 51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n1 = CalendarUtils.floorDivide(d3, 365); 51751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski d4 = CalendarUtils.mod(d3, 365) + 1; 51851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 51951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski year = 400 * n400 + 100 * n100 + 4 * n4 + n1; 52051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!(n100 == 4 || n1 == 4)) { 52151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ++year; 52251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 52351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return year; 52451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 52551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 52651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 52751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return true if the specified year is a Gregorian leap year, or 52851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * false otherwise. 52951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see BaseCalendar#isGregorianLeapYear 53051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected boolean isLeapYear(CalendarDate date) { 53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return isLeapYear(((Date)date).getNormalizedYear()); 53351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 53451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 53551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean isLeapYear(int normalizedYear) { 53651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return CalendarUtils.isGregorianLeapYear(normalizedYear); 53751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 53851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 539