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