8316435: sun.util.calendar.CalendarSystem subclassing should be restricted

Reviewed-by: naoto
This commit is contained in:
Justin Lu 2023-09-21 21:31:07 +00:00
parent 1100dbc6b2
commit 496264c1f9
9 changed files with 142 additions and 48 deletions

View file

@ -44,7 +44,8 @@ import java.util.TimeZone;
* @since 1.5 * @since 1.5
*/ */
public abstract class AbstractCalendar extends CalendarSystem { public sealed abstract class AbstractCalendar extends CalendarSystem
permits BaseCalendar {
// The constants assume no leap seconds support. // The constants assume no leap seconds support.
static final int SECOND_IN_MILLIS = 1000; static final int SECOND_IN_MILLIS = 1000;
@ -60,6 +61,7 @@ public abstract class AbstractCalendar extends CalendarSystem {
protected AbstractCalendar() { protected AbstractCalendar() {
} }
@Override
public Era getEra(String eraName) { public Era getEra(String eraName) {
if (eras != null) { if (eras != null) {
for (Era era : eras) { for (Era era : eras) {
@ -71,6 +73,7 @@ public abstract class AbstractCalendar extends CalendarSystem {
return null; return null;
} }
@Override
public Era[] getEras() { public Era[] getEras() {
Era[] e = null; Era[] e = null;
if (eras != null) { if (eras != null) {
@ -84,19 +87,23 @@ public abstract class AbstractCalendar extends CalendarSystem {
this.eras = eras; this.eras = eras;
} }
@Override
public CalendarDate getCalendarDate() { public CalendarDate getCalendarDate() {
return getCalendarDate(System.currentTimeMillis(), newCalendarDate()); return getCalendarDate(System.currentTimeMillis(), newCalendarDate());
} }
@Override
public CalendarDate getCalendarDate(long millis) { public CalendarDate getCalendarDate(long millis) {
return getCalendarDate(millis, newCalendarDate()); return getCalendarDate(millis, newCalendarDate());
} }
@Override
public CalendarDate getCalendarDate(long millis, TimeZone zone) { public CalendarDate getCalendarDate(long millis, TimeZone zone) {
CalendarDate date = newCalendarDate(zone); CalendarDate date = newCalendarDate(zone);
return getCalendarDate(millis, date); return getCalendarDate(millis, date);
} }
@Override
public CalendarDate getCalendarDate(long millis, CalendarDate date) { public CalendarDate getCalendarDate(long millis, CalendarDate date) {
int ms = 0; // time of day int ms = 0; // time of day
int zoneOffset = 0; int zoneOffset = 0;
@ -156,6 +163,7 @@ public abstract class AbstractCalendar extends CalendarSystem {
return date; return date;
} }
@Override
public long getTime(CalendarDate date) { public long getTime(CalendarDate date) {
long gd = getFixedDate(date); long gd = getFixedDate(date);
long ms = (gd - EPOCH_OFFSET) * DAY_IN_MILLIS + getTimeOfDay(date); long ms = (gd - EPOCH_OFFSET) * DAY_IN_MILLIS + getTimeOfDay(date);
@ -232,6 +240,7 @@ public abstract class AbstractCalendar extends CalendarSystem {
protected abstract boolean isLeapYear(CalendarDate date); protected abstract boolean isLeapYear(CalendarDate date);
@Override
public CalendarDate getNthDayOfWeek(int nth, int dayOfWeek, CalendarDate date) { public CalendarDate getNthDayOfWeek(int nth, int dayOfWeek, CalendarDate date) {
CalendarDate ndate = (CalendarDate) date.clone(); CalendarDate ndate = (CalendarDate) date.clone();
normalize(ndate); normalize(ndate);

View file

@ -36,7 +36,8 @@ import java.util.TimeZone;
* @since 1.5 * @since 1.5
*/ */
public abstract class BaseCalendar extends AbstractCalendar { public sealed abstract class BaseCalendar extends AbstractCalendar
permits Gregorian, JulianCalendar, LocalGregorianCalendar {
public static final int JANUARY = 1; public static final int JANUARY = 1;
public static final int FEBRUARY = 2; public static final int FEBRUARY = 2;
@ -140,7 +141,8 @@ public abstract class BaseCalendar extends AbstractCalendar {
744365, // 2039 744365, // 2039
}; };
public abstract static class Date extends CalendarDate { public sealed abstract static class Date extends CalendarDate
permits Gregorian.Date, ImmutableGregorianDate, JulianCalendar.Date, LocalGregorianCalendar.Date {
protected Date() { protected Date() {
super(); super();
} }
@ -188,6 +190,7 @@ public abstract class BaseCalendar extends AbstractCalendar {
} }
} }
@Override
public boolean validate(CalendarDate date) { public boolean validate(CalendarDate date) {
Date bdate = (Date) date; Date bdate = (Date) date;
if (bdate.isNormalized()) { if (bdate.isNormalized()) {
@ -214,6 +217,7 @@ public abstract class BaseCalendar extends AbstractCalendar {
return true; return true;
} }
@Override
public boolean normalize(CalendarDate date) { public boolean normalize(CalendarDate date) {
if (date.isNormalized()) { if (date.isNormalized()) {
return true; return true;
@ -303,6 +307,7 @@ public abstract class BaseCalendar extends AbstractCalendar {
* @throws ClassCastException if the specified date is not a * @throws ClassCastException if the specified date is not a
* {@link BaseCalendar.Date} * {@link BaseCalendar.Date}
*/ */
@Override
public int getYearLength(CalendarDate date) { public int getYearLength(CalendarDate date) {
return isLeapYear(((Date)date).getNormalizedYear()) ? 366 : 365; return isLeapYear(((Date)date).getNormalizedYear()) ? 366 : 365;
} }
@ -318,6 +323,7 @@ public abstract class BaseCalendar extends AbstractCalendar {
// 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 // 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
= { -30, 0, 31, 59+1, 90+1,120+1,151+1,181+1,212+1,243+1, 273+1, 304+1, 334+1}; = { -30, 0, 31, 59+1, 90+1,120+1,151+1,181+1,212+1,243+1, 273+1, 304+1, 334+1};
@Override
public int getMonthLength(CalendarDate date) { public int getMonthLength(CalendarDate date) {
Date gdate = (Date) date; Date gdate = (Date) date;
int month = gdate.getMonth(); int month = gdate.getMonth();
@ -349,6 +355,7 @@ public abstract class BaseCalendar extends AbstractCalendar {
} }
// protected // protected
@Override
public long getFixedDate(CalendarDate date) { public long getFixedDate(CalendarDate date) {
if (!date.isNormalized()) { if (!date.isNormalized()) {
normalizeMonth(date); normalizeMonth(date);
@ -415,6 +422,7 @@ public abstract class BaseCalendar extends AbstractCalendar {
* {@code CalendarDate}. * {@code CalendarDate}.
*/ */
// should be 'protected' // should be 'protected'
@Override
public void getCalendarDateFromFixedDate(CalendarDate date, public void getCalendarDateFromFixedDate(CalendarDate date,
long fixedDate) { long fixedDate) {
Date gdate = (Date) date; Date gdate = (Date) date;
@ -473,7 +481,7 @@ public abstract class BaseCalendar extends AbstractCalendar {
return getDayOfWeekFromFixedDate(fixedDate); return getDayOfWeekFromFixedDate(fixedDate);
} }
public static final int getDayOfWeekFromFixedDate(long fixedDate) { public static int getDayOfWeekFromFixedDate(long fixedDate) {
// The fixed day 1 (January 1, 1 Gregorian) is Monday. // The fixed day 1 (January 1, 1 Gregorian) is Monday.
if (fixedDate >= 0) { if (fixedDate >= 0) {
return (int)(fixedDate % 7) + SUNDAY; return (int)(fixedDate % 7) + SUNDAY;
@ -525,6 +533,7 @@ public abstract class BaseCalendar extends AbstractCalendar {
* false otherwise. * false otherwise.
* @see CalendarUtils#isGregorianLeapYear * @see CalendarUtils#isGregorianLeapYear
*/ */
@Override
protected boolean isLeapYear(CalendarDate date) { protected boolean isLeapYear(CalendarDate date) {
return isLeapYear(((Date)date).getNormalizedYear()); return isLeapYear(((Date)date).getNormalizedYear());
} }

View file

@ -59,7 +59,8 @@ import java.util.TimeZone;
* @author Masayoshi Okutsu * @author Masayoshi Okutsu
* @since 1.5 * @since 1.5
*/ */
public abstract class CalendarDate implements Cloneable { public sealed abstract class CalendarDate implements Cloneable
permits BaseCalendar.Date {
public static final int FIELD_UNDEFINED = Integer.MIN_VALUE; public static final int FIELD_UNDEFINED = Integer.MIN_VALUE;
public static final long TIME_UNDEFINED = Long.MIN_VALUE; public static final long TIME_UNDEFINED = Long.MIN_VALUE;
@ -340,6 +341,7 @@ public abstract class CalendarDate implements Cloneable {
&& zoneOffset == that.zoneOffset); && zoneOffset == that.zoneOffset);
} }
@Override
public int hashCode() { public int hashCode() {
// a pseudo (local standard) time stamp value in milliseconds // a pseudo (local standard) time stamp value in milliseconds
// from the Epoch, assuming Gregorian calendar fields. // from the Epoch, assuming Gregorian calendar fields.
@ -362,6 +364,7 @@ public abstract class CalendarDate implements Cloneable {
* *
* @return a copy of this <code>CalendarDate</code> * @return a copy of this <code>CalendarDate</code>
*/ */
@Override
public Object clone() { public Object clone() {
try { try {
return super.clone(); return super.clone();
@ -380,6 +383,7 @@ public abstract class CalendarDate implements Cloneable {
* *
* @see java.text.SimpleDateFormat * @see java.text.SimpleDateFormat
*/ */
@Override
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
CalendarUtils.sprintf0d(sb, year, 4).append('-'); CalendarUtils.sprintf0d(sb, year, 4).append('-');

View file

@ -65,7 +65,7 @@ import java.util.concurrent.ConcurrentMap;
* @since 1.5 * @since 1.5
*/ */
public abstract class CalendarSystem { public sealed abstract class CalendarSystem permits AbstractCalendar {
/////////////////////// Calendar Factory Methods ///////////////////////// /////////////////////// Calendar Factory Methods /////////////////////////

View file

@ -25,7 +25,10 @@
package sun.util.calendar; package sun.util.calendar;
public class CalendarUtils { public final class CalendarUtils {
// Utility class should not be instantiated
private CalendarUtils() {}
/** /**
* Returns whether the specified year is a leap year in the Gregorian * Returns whether the specified year is a leap year in the Gregorian
@ -36,9 +39,9 @@ public class CalendarUtils {
* calendar system. * calendar system.
* @see CalendarDate#isLeapYear * @see CalendarDate#isLeapYear
*/ */
public static final boolean isGregorianLeapYear(int gregorianYear) { public static boolean isGregorianLeapYear(int gregorianYear) {
return (((gregorianYear % 4) == 0) return (((gregorianYear % 4) == 0) && (((gregorianYear % 100) != 0)
&& (((gregorianYear % 100) != 0) || ((gregorianYear % 400) == 0))); || ((gregorianYear % 400) == 0)));
} }
/** /**
@ -51,7 +54,7 @@ public class CalendarUtils {
* calendar system. * calendar system.
* @see CalendarDate#isLeapYear * @see CalendarDate#isLeapYear
*/ */
public static final boolean isJulianLeapYear(int normalizedJulianYear) { public static boolean isJulianLeapYear(int normalizedJulianYear) {
return (normalizedJulianYear % 4) == 0; return (normalizedJulianYear % 4) == 0;
} }
@ -64,7 +67,7 @@ public class CalendarUtils {
* @param d a divisor that must be greater than 0 * @param d a divisor that must be greater than 0
* @return the floor of the quotient * @return the floor of the quotient
*/ */
public static final long floorDivide(long n, long d) { public static long floorDivide(long n, long d) {
return ((n >= 0) ? return ((n >= 0) ?
(n / d) : (((n + 1L) / d) - 1L)); (n / d) : (((n + 1L) / d) - 1L));
} }
@ -78,7 +81,7 @@ public class CalendarUtils {
* @param d a divisor that must be greater than 0 * @param d a divisor that must be greater than 0
* @return the floor of the quotient * @return the floor of the quotient
*/ */
public static final int floorDivide(int n, int d) { public static int floorDivide(int n, int d) {
return ((n >= 0) ? return ((n >= 0) ?
(n / d) : (((n + 1) / d) - 1)); (n / d) : (((n + 1) / d) - 1));
} }
@ -96,7 +99,7 @@ public class CalendarUtils {
* <code>mod(n, d)</code> is returned. * <code>mod(n, d)</code> is returned.
* @return the floor of the quotient. * @return the floor of the quotient.
*/ */
public static final int floorDivide(int n, int d, int[] r) { public static int floorDivide(int n, int d, int[] r) {
if (n >= 0) { if (n >= 0) {
r[0] = n % d; r[0] = n % d;
return n / d; return n / d;
@ -106,20 +109,20 @@ public class CalendarUtils {
return q; return q;
} }
public static final long mod(long x, long y) { public static long mod(long x, long y) {
return (x - y * floorDivide(x, y)); return (x - y * floorDivide(x, y));
} }
public static final int mod(int x, int y) { public static int mod(int x, int y) {
return (x - y * floorDivide(x, y)); return (x - y * floorDivide(x, y));
} }
public static final int amod(int x, int y) { public static int amod(int x, int y) {
int z = mod(x, y); int z = mod(x, y);
return (z == 0) ? y : z; return (z == 0) ? y : z;
} }
public static final long amod(long x, long y) { public static long amod(long x, long y) {
long z = mod(x, y); long z = mod(x, y);
return (z == 0) ? y : z; return (z == 0) ? y : z;
} }
@ -127,7 +130,7 @@ public class CalendarUtils {
/** /**
* Mimics sprintf(buf, "%0*d", decaimal, width). * Mimics sprintf(buf, "%0*d", decaimal, width).
*/ */
public static final StringBuilder sprintf0d(StringBuilder sb, int value, int width) { public static StringBuilder sprintf0d(StringBuilder sb, int value, int width) {
long d = value; long d = value;
if (d < 0) { if (d < 0) {
sb.append('-'); sb.append('-');
@ -146,7 +149,7 @@ public class CalendarUtils {
return sb; return sb;
} }
public static final StringBuffer sprintf0d(StringBuffer sb, int value, int width) { public static StringBuffer sprintf0d(StringBuffer sb, int value, int width) {
long d = value; long d = value;
if (d < 0) { if (d < 0) {
sb.append('-'); sb.append('-');

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -34,21 +34,23 @@ import java.util.TimeZone;
* @since 1.5 * @since 1.5
*/ */
public class Gregorian extends BaseCalendar { public final class Gregorian extends BaseCalendar {
static class Date extends BaseCalendar.Date { static final class Date extends BaseCalendar.Date {
protected Date() { Date() {
super(); super();
} }
protected Date(TimeZone zone) { Date(TimeZone zone) {
super(zone); super(zone);
} }
@Override
public int getNormalizedYear() { public int getNormalizedYear() {
return getYear(); return getYear();
} }
@Override
public void setNormalizedYear(int normalizedYear) { public void setNormalizedYear(int normalizedYear) {
setYear(normalizedYear); setYear(normalizedYear);
} }
@ -57,30 +59,37 @@ public class Gregorian extends BaseCalendar {
Gregorian() { Gregorian() {
} }
@Override
public String getName() { public String getName() {
return "gregorian"; return "gregorian";
} }
@Override
public Date getCalendarDate() { public Date getCalendarDate() {
return getCalendarDate(System.currentTimeMillis(), newCalendarDate()); return getCalendarDate(System.currentTimeMillis(), newCalendarDate());
} }
@Override
public Date getCalendarDate(long millis) { public Date getCalendarDate(long millis) {
return getCalendarDate(millis, newCalendarDate()); return getCalendarDate(millis, newCalendarDate());
} }
@Override
public Date getCalendarDate(long millis, CalendarDate date) { public Date getCalendarDate(long millis, CalendarDate date) {
return (Date) super.getCalendarDate(millis, date); return (Date) super.getCalendarDate(millis, date);
} }
@Override
public Date getCalendarDate(long millis, TimeZone zone) { public Date getCalendarDate(long millis, TimeZone zone) {
return getCalendarDate(millis, newCalendarDate(zone)); return getCalendarDate(millis, newCalendarDate(zone));
} }
@Override
public Date newCalendarDate() { public Date newCalendarDate() {
return new Date(); return new Date();
} }
@Override
public Date newCalendarDate(TimeZone zone) { public Date newCalendarDate(TimeZone zone) {
return new Date(zone); return new Date(zone);
} }

View file

@ -25,192 +25,238 @@
package sun.util.calendar; package sun.util.calendar;
import java.util.Objects;
import java.util.TimeZone; import java.util.TimeZone;
class ImmutableGregorianDate extends BaseCalendar.Date { /*
* This class is immutable, and thus any methods from the base classes
* that can modify the state are overridden to throw an exception.
*/
final class ImmutableGregorianDate extends BaseCalendar.Date {
private final BaseCalendar.Date date; private final BaseCalendar.Date date;
ImmutableGregorianDate(BaseCalendar.Date date) { ImmutableGregorianDate(BaseCalendar.Date date) {
if (date == null) { this.date = Objects.requireNonNull(date);
throw new NullPointerException();
}
this.date = date;
} }
@Override
public Era getEra() { public Era getEra() {
return date.getEra(); return date.getEra();
} }
@Override
public CalendarDate setEra(Era era) { public CalendarDate setEra(Era era) {
unsupported(); return this; unsupported(); return this;
} }
@Override
public int getYear() { public int getYear() {
return date.getYear(); return date.getYear();
} }
@Override
public CalendarDate setYear(int year) { public CalendarDate setYear(int year) {
unsupported(); return this; unsupported(); return this;
} }
@Override
public CalendarDate addYear(int n) { public CalendarDate addYear(int n) {
unsupported(); return this; unsupported(); return this;
} }
@Override
public boolean isLeapYear() { public boolean isLeapYear() {
return date.isLeapYear(); return date.isLeapYear();
} }
@Override
void setLeapYear(boolean leapYear) { void setLeapYear(boolean leapYear) {
unsupported(); unsupported();
} }
@Override
public int getMonth() { public int getMonth() {
return date.getMonth(); return date.getMonth();
} }
@Override
public CalendarDate setMonth(int month) { public CalendarDate setMonth(int month) {
unsupported(); return this; unsupported(); return this;
} }
@Override
public CalendarDate addMonth(int n) { public CalendarDate addMonth(int n) {
unsupported(); return this; unsupported(); return this;
} }
@Override
public int getDayOfMonth() { public int getDayOfMonth() {
return date.getDayOfMonth(); return date.getDayOfMonth();
} }
@Override
public CalendarDate setDayOfMonth(int date) { public CalendarDate setDayOfMonth(int date) {
unsupported(); return this; unsupported(); return this;
} }
@Override
public int getDayOfWeek() { public int getDayOfWeek() {
return date.getDayOfWeek(); return date.getDayOfWeek();
} }
@Override
public int getHours() { public int getHours() {
return date.getHours(); return date.getHours();
} }
@Override
public CalendarDate setHours(int hours) { public CalendarDate setHours(int hours) {
unsupported(); return this; unsupported(); return this;
} }
@Override
public CalendarDate addHours(int n) { public CalendarDate addHours(int n) {
unsupported(); return this; unsupported(); return this;
} }
@Override
public int getMinutes() { public int getMinutes() {
return date.getMinutes(); return date.getMinutes();
} }
@Override
public CalendarDate setMinutes(int minutes) { public CalendarDate setMinutes(int minutes) {
unsupported(); return this; unsupported(); return this;
} }
@Override
public int getSeconds() { public int getSeconds() {
return date.getSeconds(); return date.getSeconds();
} }
@Override
public CalendarDate setSeconds(int seconds) { public CalendarDate setSeconds(int seconds) {
unsupported(); return this; unsupported(); return this;
} }
@Override
public int getMillis() { public int getMillis() {
return date.getMillis(); return date.getMillis();
} }
@Override
public CalendarDate setMillis(int millis) { public CalendarDate setMillis(int millis) {
unsupported(); return this; unsupported(); return this;
} }
@Override
public long getTimeOfDay() { public long getTimeOfDay() {
return date.getTimeOfDay(); return date.getTimeOfDay();
} }
@Override
public CalendarDate setDate(int year, int month, int dayOfMonth) { public CalendarDate setDate(int year, int month, int dayOfMonth) {
unsupported(); return this; unsupported(); return this;
} }
@Override
public CalendarDate setTimeOfDay(int hours, int minutes, int seconds, int millis) { public CalendarDate setTimeOfDay(int hours, int minutes, int seconds, int millis) {
unsupported(); return this; unsupported(); return this;
} }
@Override
protected void setTimeOfDay(long fraction) { protected void setTimeOfDay(long fraction) {
unsupported(); unsupported();
} }
@Override
public boolean isNormalized() { public boolean isNormalized() {
return date.isNormalized(); return date.isNormalized();
} }
@Override
public boolean isDaylightTime() { public boolean isDaylightTime() {
return date.isDaylightTime(); return date.isDaylightTime();
} }
@Override
public TimeZone getZone() { public TimeZone getZone() {
return date.getZone(); return date.getZone();
} }
@Override
public CalendarDate setZone(TimeZone zoneinfo) { public CalendarDate setZone(TimeZone zoneinfo) {
unsupported(); return this; unsupported(); return this;
} }
@Override
public boolean isSameDate(CalendarDate date) { public boolean isSameDate(CalendarDate date) {
return date.isSameDate(date); return date.isSameDate(date);
} }
@Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) { if (this == obj) {
return true; return true;
} }
if (!(obj instanceof ImmutableGregorianDate)) { if (obj instanceof ImmutableGregorianDate igd) {
return date.equals(igd.date);
} else {
return false; return false;
} }
return date.equals(((ImmutableGregorianDate) obj).date);
} }
@Override
public int hashCode() { public int hashCode() {
return date.hashCode(); return date.hashCode();
} }
@Override
public Object clone() { public Object clone() {
return super.clone(); return super.clone();
} }
@Override
public String toString() { public String toString() {
return date.toString(); return date.toString();
} }
@Override
protected void setDayOfWeek(int dayOfWeek) { protected void setDayOfWeek(int dayOfWeek) {
unsupported(); unsupported();
} }
@Override
protected void setNormalized(boolean normalized) { protected void setNormalized(boolean normalized) {
unsupported(); unsupported();
} }
@Override
public int getZoneOffset() { public int getZoneOffset() {
return date.getZoneOffset(); return date.getZoneOffset();
} }
@Override
protected void setZoneOffset(int offset) { protected void setZoneOffset(int offset) {
unsupported(); unsupported();
} }
@Override
public int getDaylightSaving() { public int getDaylightSaving() {
return date.getDaylightSaving(); return date.getDaylightSaving();
} }
@Override
protected void setDaylightSaving(int daylightSaving) { protected void setDaylightSaving(int daylightSaving) {
unsupported(); unsupported();
} }
@Override
public int getNormalizedYear() { public int getNormalizedYear() {
return date.getNormalizedYear(); return date.getNormalizedYear();
} }
@Override
public void setNormalizedYear(int normalizedYear) { public void setNormalizedYear(int normalizedYear) {
unsupported(); unsupported();
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -33,7 +33,7 @@ import java.util.TimeZone;
* @author Masayoshi Okutsu * @author Masayoshi Okutsu
* @since 1.5 * @since 1.5
*/ */
public class JulianCalendar extends BaseCalendar { public final class JulianCalendar extends BaseCalendar {
private static final int BCE = 0; private static final int BCE = 0;
private static final int CE = 1; private static final int CE = 1;
@ -44,17 +44,18 @@ public class JulianCalendar extends BaseCalendar {
}; };
private static final int JULIAN_EPOCH = -1; private static final int JULIAN_EPOCH = -1;
private static class Date extends BaseCalendar.Date { static final class Date extends BaseCalendar.Date {
protected Date() { Date() {
super(); super();
setCache(1, -1L, 365); // January 1, 1 CE (Julian) setCache(1, -1L, 365); // January 1, 1 CE (Julian)
} }
protected Date(TimeZone zone) { Date(TimeZone zone) {
super(zone); super(zone);
setCache(1, -1L, 365); // January 1, 1 CE (Julian) setCache(1, -1L, 365); // January 1, 1 CE (Julian)
} }
@Override
public Date setEra(Era era) { public Date setEra(Era era) {
if (era == null) { if (era == null) {
throw new NullPointerException(); throw new NullPointerException();
@ -66,10 +67,11 @@ public class JulianCalendar extends BaseCalendar {
return this; return this;
} }
protected void setKnownEra(Era era) { void setKnownEra(Era era) {
super.setEra(era); super.setEra(era);
} }
@Override
public int getNormalizedYear() { public int getNormalizedYear() {
if (getEra() == eras[BCE]) { if (getEra() == eras[BCE]) {
return 1 - getYear(); return 1 - getYear();
@ -81,6 +83,7 @@ public class JulianCalendar extends BaseCalendar {
// normalized years. This differs from "Calendrical // normalized years. This differs from "Calendrical
// Calculations" in which the numbering is ..., -2, -1, 1, 2, // Calculations" in which the numbering is ..., -2, -1, 1, 2,
// ... // ...
@Override
public void setNormalizedYear(int year) { public void setNormalizedYear(int year) {
if (year <= 0) { if (year <= 0) {
setYear(1 - year); setYear(1 - year);
@ -91,6 +94,7 @@ public class JulianCalendar extends BaseCalendar {
} }
} }
@Override
public String toString() { public String toString() {
String time = super.toString(); String time = super.toString();
time = time.substring(time.indexOf('T')); time = time.substring(time.indexOf('T'));
@ -114,30 +118,37 @@ public class JulianCalendar extends BaseCalendar {
setEras(eras); setEras(eras);
} }
@Override
public String getName() { public String getName() {
return "julian"; return "julian";
} }
@Override
public Date getCalendarDate() { public Date getCalendarDate() {
return getCalendarDate(System.currentTimeMillis(), newCalendarDate()); return getCalendarDate(System.currentTimeMillis(), newCalendarDate());
} }
@Override
public Date getCalendarDate(long millis) { public Date getCalendarDate(long millis) {
return getCalendarDate(millis, newCalendarDate()); return getCalendarDate(millis, newCalendarDate());
} }
@Override
public Date getCalendarDate(long millis, CalendarDate date) { public Date getCalendarDate(long millis, CalendarDate date) {
return (Date) super.getCalendarDate(millis, date); return (Date) super.getCalendarDate(millis, date);
} }
@Override
public Date getCalendarDate(long millis, TimeZone zone) { public Date getCalendarDate(long millis, TimeZone zone) {
return getCalendarDate(millis, newCalendarDate(zone)); return getCalendarDate(millis, newCalendarDate(zone));
} }
@Override
public Date newCalendarDate() { public Date newCalendarDate() {
return new Date(); return new Date();
} }
@Override
public Date newCalendarDate(TimeZone zone) { public Date newCalendarDate(TimeZone zone) {
return new Date(zone); return new Date(zone);
} }
@ -145,6 +156,7 @@ public class JulianCalendar extends BaseCalendar {
/** /**
* @param jyear normalized Julian year * @param jyear normalized Julian year
*/ */
@Override
public long getFixedDate(int jyear, int month, int dayOfMonth, BaseCalendar.Date cache) { public long getFixedDate(int jyear, int month, int dayOfMonth, BaseCalendar.Date cache) {
boolean isJan1 = month == JANUARY && dayOfMonth == 1; boolean isJan1 = month == JANUARY && dayOfMonth == 1;
@ -182,6 +194,7 @@ public class JulianCalendar extends BaseCalendar {
return days; return days;
} }
@Override
public void getCalendarDateFromFixedDate(CalendarDate date, long fixedDate) { public void getCalendarDateFromFixedDate(CalendarDate date, long fixedDate) {
Date jdate = (Date) date; Date jdate = (Date) date;
long fd = 4 * (fixedDate - JULIAN_EPOCH) + 1464; long fd = 4 * (fixedDate - JULIAN_EPOCH) + 1464;
@ -216,18 +229,18 @@ public class JulianCalendar extends BaseCalendar {
/** /**
* Returns the normalized Julian year number of the given fixed date. * Returns the normalized Julian year number of the given fixed date.
*/ */
@Override
public int getYearFromFixedDate(long fixedDate) { public int getYearFromFixedDate(long fixedDate) {
int year = (int) CalendarUtils.floorDivide(4 * (fixedDate - JULIAN_EPOCH) + 1464, 1461); return (int) CalendarUtils.floorDivide(4 * (fixedDate - JULIAN_EPOCH) + 1464, 1461);
return year;
} }
@Override
public int getDayOfWeek(CalendarDate date) { public int getDayOfWeek(CalendarDate date) {
// TODO: should replace this with a faster calculation, such // TODO: should replace with faster calculation, e.g. cache table lookup
// as cache table lookup return getDayOfWeekFromFixedDate(getFixedDate(date));
long fixedDate = getFixedDate(date);
return getDayOfWeekFromFixedDate(fixedDate);
} }
@Override
boolean isLeapYear(int jyear) { boolean isLeapYear(int jyear) {
return CalendarUtils.isJulianLeapYear(jyear); return CalendarUtils.isJulianLeapYear(jyear);
} }

View file

@ -36,7 +36,7 @@ import sun.security.action.GetPropertyAction;
* @since 1.6 * @since 1.6
*/ */
public class LocalGregorianCalendar extends BaseCalendar { public final class LocalGregorianCalendar extends BaseCalendar {
private static final Era[] JAPANESE_ERAS = { private static final Era[] JAPANESE_ERAS = {
new Era("Meiji", "M", -3218832000000L, true), new Era("Meiji", "M", -3218832000000L, true),
new Era("Taisho", "T", -1812153600000L, true), new Era("Taisho", "T", -1812153600000L, true),
@ -63,13 +63,14 @@ public class LocalGregorianCalendar extends BaseCalendar {
private String name; private String name;
private Era[] eras; private Era[] eras;
public static class Date extends BaseCalendar.Date { // Used within java.time and java.util
public static final class Date extends BaseCalendar.Date {
protected Date() { Date() {
super(); super();
} }
protected Date(TimeZone zone) { Date(TimeZone zone) {
super(zone); super(zone);
} }