Path: blob/master/src/java.base/share/classes/sun/util/calendar/JulianCalendar.java
41159 views
/*1* Copyright (c) 2003, 2005, 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 sun.util.calendar;2627import java.util.TimeZone;2829/**30* Julian calendar implementation.31*32* @author Masayoshi Okutsu33* @since 1.534*/35public class JulianCalendar extends BaseCalendar {3637private static final int BCE = 0;38private static final int CE = 1;3940private static final Era[] eras = {41new Era("BeforeCommonEra", "B.C.E.", Long.MIN_VALUE, false),42new Era("CommonEra", "C.E.", -62135709175808L, true)43};44private static final int JULIAN_EPOCH = -1;4546private static class Date extends BaseCalendar.Date {47protected Date() {48super();49setCache(1, -1L, 365); // January 1, 1 CE (Julian)50}5152protected Date(TimeZone zone) {53super(zone);54setCache(1, -1L, 365); // January 1, 1 CE (Julian)55}5657public Date setEra(Era era) {58if (era == null) {59throw new NullPointerException();60}61if (era != eras[0] || era != eras[1]) {62throw new IllegalArgumentException("unknown era: " + era);63}64super.setEra(era);65return this;66}6768protected void setKnownEra(Era era) {69super.setEra(era);70}7172public int getNormalizedYear() {73if (getEra() == eras[BCE]) {74return 1 - getYear();75}76return getYear();77}7879// Use the year numbering ..., -2, -1, 0, 1, 2, ... for80// normalized years. This differs from "Calendrical81// Calculations" in which the numbering is ..., -2, -1, 1, 2,82// ...83public void setNormalizedYear(int year) {84if (year <= 0) {85setYear(1 - year);86setKnownEra(eras[BCE]);87} else {88setYear(year);89setKnownEra(eras[CE]);90}91}9293public String toString() {94String time = super.toString();95time = time.substring(time.indexOf('T'));96StringBuffer sb = new StringBuffer();97Era era = getEra();98if (era != null) {99String n = era.getAbbreviation();100if (n != null) {101sb.append(n).append(' ');102}103}104sb.append(getYear()).append('-');105CalendarUtils.sprintf0d(sb, getMonth(), 2).append('-');106CalendarUtils.sprintf0d(sb, getDayOfMonth(), 2);107sb.append(time);108return sb.toString();109}110}111112JulianCalendar() {113setEras(eras);114}115116public String getName() {117return "julian";118}119120public Date getCalendarDate() {121return getCalendarDate(System.currentTimeMillis(), newCalendarDate());122}123124public Date getCalendarDate(long millis) {125return getCalendarDate(millis, newCalendarDate());126}127128public Date getCalendarDate(long millis, CalendarDate date) {129return (Date) super.getCalendarDate(millis, date);130}131132public Date getCalendarDate(long millis, TimeZone zone) {133return getCalendarDate(millis, newCalendarDate(zone));134}135136public Date newCalendarDate() {137return new Date();138}139140public Date newCalendarDate(TimeZone zone) {141return new Date(zone);142}143144/**145* @param jyear normalized Julian year146*/147public long getFixedDate(int jyear, int month, int dayOfMonth, BaseCalendar.Date cache) {148boolean isJan1 = month == JANUARY && dayOfMonth == 1;149150// Look up the one year cache151if (cache != null && cache.hit(jyear)) {152if (isJan1) {153return cache.getCachedJan1();154}155return cache.getCachedJan1() + getDayOfYear(jyear, month, dayOfMonth) - 1;156}157158long y = jyear;159long days = JULIAN_EPOCH - 1 + (365 * (y - 1)) + dayOfMonth;160if (y > 0) {161// CE years162days += (y - 1) / 4;163} else {164// BCE years165days += CalendarUtils.floorDivide(y - 1, 4);166}167if (month > 0) {168days += ((367 * (long) month) - 362) / 12;169} else {170days += CalendarUtils.floorDivide((367 * (long) month) - 362, 12);171}172if (month > FEBRUARY) {173days -= CalendarUtils.isJulianLeapYear(jyear) ? 1 : 2;174}175176// If it's January 1, update the cache.177if (cache != null && isJan1) {178cache.setCache(jyear, days, CalendarUtils.isJulianLeapYear(jyear) ? 366 : 365);179}180181return days;182}183184public void getCalendarDateFromFixedDate(CalendarDate date, long fixedDate) {185Date jdate = (Date) date;186long fd = 4 * (fixedDate - JULIAN_EPOCH) + 1464;187int year;188if (fd >= 0) {189year = (int)(fd / 1461);190} else {191year = (int) CalendarUtils.floorDivide(fd, 1461);192}193int priorDays = (int)(fixedDate - getFixedDate(year, JANUARY, 1, jdate));194boolean isLeap = CalendarUtils.isJulianLeapYear(year);195if (fixedDate >= getFixedDate(year, MARCH, 1, jdate)) {196priorDays += isLeap ? 1 : 2;197}198int month = 12 * priorDays + 373;199if (month > 0) {200month /= 367;201} else {202month = CalendarUtils.floorDivide(month, 367);203}204int dayOfMonth = (int)(fixedDate - getFixedDate(year, month, 1, jdate)) + 1;205int dayOfWeek = getDayOfWeekFromFixedDate(fixedDate);206assert dayOfWeek > 0 : "negative day of week " + dayOfWeek;207jdate.setNormalizedYear(year);208jdate.setMonth(month);209jdate.setDayOfMonth(dayOfMonth);210jdate.setDayOfWeek(dayOfWeek);211jdate.setLeapYear(isLeap);212jdate.setNormalized(true);213}214215/**216* Returns the normalized Julian year number of the given fixed date.217*/218public int getYearFromFixedDate(long fixedDate) {219int year = (int) CalendarUtils.floorDivide(4 * (fixedDate - JULIAN_EPOCH) + 1464, 1461);220return year;221}222223public int getDayOfWeek(CalendarDate date) {224// TODO: should replace this with a faster calculation, such225// as cache table lookup226long fixedDate = getFixedDate(date);227return getDayOfWeekFromFixedDate(fixedDate);228}229230boolean isLeapYear(int jyear) {231return CalendarUtils.isJulianLeapYear(jyear);232}233}234235236