0N/A/*
2362N/A * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.util.calendar;
0N/A
0N/Aimport java.util.TimeZone;
0N/A
0N/A/**
0N/A * Julian calendar implementation.
0N/A *
0N/A * @author Masayoshi Okutsu
0N/A * @since 1.5
0N/A */
0N/Apublic class JulianCalendar extends BaseCalendar {
0N/A
0N/A private static final int BCE = 0;
0N/A private static final int CE = 1;
0N/A
0N/A private static final Era[] eras = {
0N/A new Era("BeforeCommonEra", "B.C.E.", Long.MIN_VALUE, false),
0N/A new Era("CommonEra", "C.E.", -62135709175808L, true)
0N/A };
0N/A private static final int JULIAN_EPOCH = -1;
0N/A
0N/A private static class Date extends BaseCalendar.Date {
0N/A protected Date() {
0N/A super();
0N/A setCache(1, -1L, 365); // January 1, 1 CE (Julian)
0N/A }
0N/A
0N/A protected Date(TimeZone zone) {
0N/A super(zone);
0N/A setCache(1, -1L, 365); // January 1, 1 CE (Julian)
0N/A }
0N/A
0N/A public Date setEra(Era era) {
0N/A if (era == null) {
0N/A throw new NullPointerException();
0N/A }
0N/A if (era != eras[0] || era != eras[1]) {
0N/A throw new IllegalArgumentException("unknown era: " + era);
0N/A }
0N/A super.setEra(era);
0N/A return this;
0N/A }
0N/A
0N/A protected void setKnownEra(Era era) {
0N/A super.setEra(era);
0N/A }
0N/A
0N/A public int getNormalizedYear() {
0N/A if (getEra() == eras[BCE]) {
0N/A return 1 - getYear();
0N/A }
0N/A return getYear();
0N/A }
0N/A
0N/A // Use the year numbering ..., -2, -1, 0, 1, 2, ... for
0N/A // normalized years. This differs from "Calendrical
0N/A // Calculations" in which the numbering is ..., -2, -1, 1, 2,
0N/A // ...
0N/A public void setNormalizedYear(int year) {
0N/A if (year <= 0) {
0N/A setYear(1 - year);
0N/A setKnownEra(eras[BCE]);
0N/A } else {
0N/A setYear(year);
0N/A setKnownEra(eras[CE]);
0N/A }
0N/A }
0N/A
0N/A public String toString() {
0N/A String time = super.toString();
0N/A time = time.substring(time.indexOf('T'));
0N/A StringBuffer sb = new StringBuffer();
0N/A Era era = getEra();
0N/A if (era != null) {
0N/A String n = era.getAbbreviation();
0N/A if (n != null) {
0N/A sb.append(n).append(' ');
0N/A }
0N/A }
0N/A sb.append(getYear()).append('-');
0N/A CalendarUtils.sprintf0d(sb, getMonth(), 2).append('-');
0N/A CalendarUtils.sprintf0d(sb, getDayOfMonth(), 2);
0N/A sb.append(time);
0N/A return sb.toString();
0N/A }
0N/A }
0N/A
0N/A JulianCalendar() {
0N/A setEras(eras);
0N/A }
0N/A
0N/A public String getName() {
0N/A return "julian";
0N/A }
0N/A
0N/A public Date getCalendarDate() {
0N/A return getCalendarDate(System.currentTimeMillis(), newCalendarDate());
0N/A }
0N/A
0N/A public Date getCalendarDate(long millis) {
0N/A return getCalendarDate(millis, newCalendarDate());
0N/A }
0N/A
0N/A public Date getCalendarDate(long millis, CalendarDate date) {
0N/A return (Date) super.getCalendarDate(millis, date);
0N/A }
0N/A
0N/A public Date getCalendarDate(long millis, TimeZone zone) {
0N/A return getCalendarDate(millis, newCalendarDate(zone));
0N/A }
0N/A
0N/A public Date newCalendarDate() {
0N/A return new Date();
0N/A }
0N/A
0N/A public Date newCalendarDate(TimeZone zone) {
0N/A return new Date(zone);
0N/A }
0N/A
0N/A /**
0N/A * @param jyear normalized Julian year
0N/A */
0N/A public long getFixedDate(int jyear, int month, int dayOfMonth, BaseCalendar.Date cache) {
0N/A boolean isJan1 = month == JANUARY && dayOfMonth == 1;
0N/A
0N/A // Look up the one year cache
0N/A if (cache != null && cache.hit(jyear)) {
0N/A if (isJan1) {
0N/A return cache.getCachedJan1();
0N/A }
0N/A return cache.getCachedJan1() + getDayOfYear(jyear, month, dayOfMonth) - 1;
0N/A }
0N/A
0N/A long y = jyear;
0N/A long days = JULIAN_EPOCH - 1 + (365 * (y - 1)) + dayOfMonth;
0N/A if (y > 0) {
0N/A // CE years
0N/A days += (y - 1) / 4;
0N/A } else {
0N/A // BCE years
0N/A days += CalendarUtils.floorDivide(y - 1, 4);
0N/A }
0N/A if (month > 0) {
0N/A days += ((367 * (long) month) - 362) / 12;
0N/A } else {
0N/A days += CalendarUtils.floorDivide((367 * (long) month) - 362, 12);
0N/A }
0N/A if (month > FEBRUARY) {
0N/A days -= CalendarUtils.isJulianLeapYear(jyear) ? 1 : 2;
0N/A }
0N/A
0N/A // If it's January 1, update the cache.
0N/A if (cache != null && isJan1) {
0N/A cache.setCache(jyear, days, CalendarUtils.isJulianLeapYear(jyear) ? 366 : 365);
0N/A }
0N/A
0N/A return days;
0N/A }
0N/A
0N/A public void getCalendarDateFromFixedDate(CalendarDate date, long fixedDate) {
0N/A Date jdate = (Date) date;
0N/A long fd = 4 * (fixedDate - JULIAN_EPOCH) + 1464;
0N/A int year;
0N/A if (fd >= 0) {
0N/A year = (int)(fd / 1461);
0N/A } else {
0N/A year = (int) CalendarUtils.floorDivide(fd, 1461);
0N/A }
0N/A int priorDays = (int)(fixedDate - getFixedDate(year, JANUARY, 1, jdate));
0N/A boolean isLeap = CalendarUtils.isJulianLeapYear(year);
0N/A if (fixedDate >= getFixedDate(year, MARCH, 1, jdate)) {
0N/A priorDays += isLeap ? 1 : 2;
0N/A }
0N/A int month = 12 * priorDays + 373;
0N/A if (month > 0) {
0N/A month /= 367;
0N/A } else {
0N/A month = CalendarUtils.floorDivide(month, 367);
0N/A }
0N/A int dayOfMonth = (int)(fixedDate - getFixedDate(year, month, 1, jdate)) + 1;
0N/A int dayOfWeek = getDayOfWeekFromFixedDate(fixedDate);
0N/A assert dayOfWeek > 0 : "negative day of week " + dayOfWeek;
0N/A jdate.setNormalizedYear(year);
0N/A jdate.setMonth(month);
0N/A jdate.setDayOfMonth(dayOfMonth);
0N/A jdate.setDayOfWeek(dayOfWeek);
0N/A jdate.setLeapYear(isLeap);
0N/A jdate.setNormalized(true);
0N/A }
0N/A
0N/A /**
0N/A * Returns the normalized Julian year number of the given fixed date.
0N/A */
0N/A public int getYearFromFixedDate(long fixedDate) {
0N/A int year = (int) CalendarUtils.floorDivide(4 * (fixedDate - JULIAN_EPOCH) + 1464, 1461);
0N/A return year;
0N/A }
0N/A
0N/A public int getDayOfWeek(CalendarDate date) {
0N/A // TODO: should replace this with a faster calculation, such
0N/A // as cache table lookup
0N/A long fixedDate = getFixedDate(date);
0N/A return getDayOfWeekFromFixedDate(fixedDate);
0N/A }
0N/A
0N/A boolean isLeapYear(int jyear) {
0N/A return CalendarUtils.isJulianLeapYear(jyear);
0N/A }
0N/A}