--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/util/calendar/LocalGregorianCalendar.java Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,379 @@
+/*
+ * Copyright 2005 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.util.calendar;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.TimeZone;
+
+/**
+ *
+ * @author Masayoshi Okutsu
+ * @since 1.6
+ */
+
+public class LocalGregorianCalendar extends BaseCalendar {
+ private String name;
+ private Era[] eras;
+
+ public static class Date extends BaseCalendar.Date {
+
+ protected Date() {
+ super();
+ }
+
+ protected Date(TimeZone zone) {
+ super(zone);
+ }
+
+ private int gregorianYear = FIELD_UNDEFINED;
+
+ public Date setEra(Era era) {
+ if (getEra() != era) {
+ super.setEra(era);
+ gregorianYear = FIELD_UNDEFINED;
+ }
+ return this;
+ }
+
+ public Date addYear(int localYear) {
+ super.addYear(localYear);
+ gregorianYear += localYear;
+ return this;
+ }
+
+ public Date setYear(int localYear) {
+ if (getYear() != localYear) {
+ super.setYear(localYear);
+ gregorianYear = FIELD_UNDEFINED;
+ }
+ return this;
+ }
+
+ public int getNormalizedYear() {
+ return gregorianYear;
+ }
+
+ public void setNormalizedYear(int normalizedYear) {
+ this.gregorianYear = normalizedYear;
+ }
+
+ void setLocalEra(Era era) {
+ super.setEra(era);
+ }
+
+ void setLocalYear(int year) {
+ super.setYear(year);
+ }
+
+ public String toString() {
+ String time = super.toString();
+ time = time.substring(time.indexOf('T'));
+ StringBuffer sb = new StringBuffer();
+ Era era = getEra();
+ if (era != null) {
+ String abbr = era.getAbbreviation();
+ if (abbr != null) {
+ sb.append(abbr);
+ }
+ }
+ sb.append(getYear()).append('.');
+ CalendarUtils.sprintf0d(sb, getMonth(), 2).append('.');
+ CalendarUtils.sprintf0d(sb, getDayOfMonth(), 2);
+ sb.append(time);
+ return sb.toString();
+ }
+ }
+
+ static LocalGregorianCalendar getLocalGregorianCalendar(String name) {
+ Properties calendarProps = null;
+ try {
+ String homeDir = AccessController.doPrivileged(
+ new sun.security.action.GetPropertyAction("java.home"));
+ final String fname = homeDir + File.separator + "lib" + File.separator
+ + "calendars.properties";
+ calendarProps = (Properties) AccessController.doPrivileged(new PrivilegedExceptionAction() {
+ public Object run() throws IOException {
+ Properties props = new Properties();
+ props.load(new FileInputStream(fname));
+ return props;
+ }
+ });
+ } catch (PrivilegedActionException e) {
+ throw new RuntimeException(e.getException());
+ }
+
+ // Parse calendar.*.eras
+ String props = calendarProps.getProperty("calendar." + name + ".eras");
+ if (props == null) {
+ return null;
+ }
+ List<Era> eras = new ArrayList<Era>();
+ StringTokenizer eraTokens = new StringTokenizer(props, ";");
+ while (eraTokens.hasMoreTokens()) {
+ String items = eraTokens.nextToken().trim();
+ StringTokenizer itemTokens = new StringTokenizer(items, ",");
+ String eraName = null;
+ boolean localTime = true;
+ long since = 0;
+ String abbr = null;
+
+ while (itemTokens.hasMoreTokens()) {
+ String item = itemTokens.nextToken();
+ int index = item.indexOf('=');
+ // it must be in the key=value form.
+ if (index == -1) {
+ return null;
+ }
+ String key = item.substring(0, index);
+ String value = item.substring(index + 1);
+ if ("name".equals(key)) {
+ eraName = value;
+ } else if ("since".equals(key)) {
+ if (value.endsWith("u")) {
+ localTime = false;
+ since = Long.parseLong(value.substring(0, value.length() - 1));
+ } else {
+ since = Long.parseLong(value);
+ }
+ } else if ("abbr".equals(key)) {
+ abbr = value;
+ } else {
+ throw new RuntimeException("Unknown key word: " + key);
+ }
+ }
+ Era era = new Era(eraName, abbr, since, localTime);
+ eras.add(era);
+ }
+ Era[] eraArray = new Era[eras.size()];
+ eras.toArray(eraArray);
+
+ return new LocalGregorianCalendar(name, eraArray);
+ }
+
+ private LocalGregorianCalendar(String name, Era[] eras) {
+ this.name = name;
+ this.eras = eras;
+ setEras(eras);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Date getCalendarDate() {
+ return getCalendarDate(System.currentTimeMillis(), newCalendarDate());
+ }
+
+ public Date getCalendarDate(long millis) {
+ return getCalendarDate(millis, newCalendarDate());
+ }
+
+ public Date getCalendarDate(long millis, TimeZone zone) {
+ return getCalendarDate(millis, newCalendarDate(zone));
+ }
+
+ public Date getCalendarDate(long millis, CalendarDate date) {
+ Date ldate = (Date) super.getCalendarDate(millis, date);
+ return adjustYear(ldate, millis, ldate.getZoneOffset());
+ }
+
+ private Date adjustYear(Date ldate, long millis, int zoneOffset) {
+ int i;
+ for (i = eras.length - 1; i >= 0; --i) {
+ Era era = eras[i];
+ long since = era.getSince(null);
+ if (era.isLocalTime()) {
+ since -= zoneOffset;
+ }
+ if (millis >= since) {
+ ldate.setLocalEra(era);
+ int y = ldate.getNormalizedYear() - era.getSinceDate().getYear() + 1;
+ ldate.setLocalYear(y);
+ break;
+ }
+ }
+ if (i < 0) {
+ ldate.setLocalEra(null);
+ ldate.setLocalYear(ldate.getNormalizedYear());
+ }
+ ldate.setNormalized(true);
+ return ldate;
+ }
+
+ public Date newCalendarDate() {
+ return new Date();
+ }
+
+ public Date newCalendarDate(TimeZone zone) {
+ return new Date(zone);
+ }
+
+ public boolean validate(CalendarDate date) {
+ Date ldate = (Date) date;
+ Era era = ldate.getEra();
+ if (era != null) {
+ if (!validateEra(era)) {
+ return false;
+ }
+ ldate.setNormalizedYear(era.getSinceDate().getYear() + ldate.getYear());
+ } else {
+ ldate.setNormalizedYear(ldate.getYear());
+ }
+ return super.validate(ldate);
+ }
+
+ private boolean validateEra(Era era) {
+ // Validate the era
+ for (int i = 0; i < eras.length; i++) {
+ if (era == eras[i]) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean normalize(CalendarDate date) {
+ if (date.isNormalized()) {
+ return true;
+ }
+
+ normalizeYear(date);
+ Date ldate = (Date) date;
+
+ // Normalize it as a Gregorian date and get its millisecond value
+ super.normalize(ldate);
+
+ boolean hasMillis = false;
+ long millis = 0;
+ int year = ldate.getNormalizedYear();
+ int i;
+ Era era = null;
+ for (i = eras.length - 1; i >= 0; --i) {
+ era = eras[i];
+ if (era.isLocalTime()) {
+ CalendarDate sinceDate = era.getSinceDate();
+ int sinceYear = sinceDate.getYear();
+ if (year > sinceYear) {
+ break;
+ }
+ if (year == sinceYear) {
+ int month = ldate.getMonth();
+ int sinceMonth = sinceDate.getMonth();
+ if (month > sinceMonth) {
+ break;
+ }
+ if (month == sinceMonth) {
+ int day = ldate.getDayOfMonth();
+ int sinceDay = sinceDate.getDayOfMonth();
+ if (day > sinceDay) {
+ break;
+ }
+ if (day == sinceDay) {
+ long timeOfDay = ldate.getTimeOfDay();
+ long sinceTimeOfDay = sinceDate.getTimeOfDay();
+ if (timeOfDay >= sinceTimeOfDay) {
+ break;
+ }
+ --i;
+ break;
+ }
+ }
+ }
+ } else {
+ if (!hasMillis) {
+ millis = super.getTime(date);
+ hasMillis = true;
+ }
+
+ long since = era.getSince(date.getZone());
+ if (millis >= since) {
+ break;
+ }
+ }
+ }
+ if (i >= 0) {
+ ldate.setLocalEra(era);
+ int y = ldate.getNormalizedYear() - era.getSinceDate().getYear() + 1;
+ ldate.setLocalYear(y);
+ } else {
+ // Set Gregorian year with no era
+ ldate.setEra(null);
+ ldate.setLocalYear(year);
+ ldate.setNormalizedYear(year);
+ }
+ ldate.setNormalized(true);
+ return true;
+ }
+
+ void normalizeMonth(CalendarDate date) {
+ normalizeYear(date);
+ super.normalizeMonth(date);
+ }
+
+ void normalizeYear(CalendarDate date) {
+ Date ldate = (Date) date;
+ // Set the supposed-to-be-correct Gregorian year first
+ // e.g., Showa 90 becomes 2015 (1926 + 90 - 1).
+ Era era = ldate.getEra();
+ if (era == null || !validateEra(era)) {
+ ldate.setNormalizedYear(ldate.getYear());
+ } else {
+ ldate.setNormalizedYear(era.getSinceDate().getYear() + ldate.getYear() - 1);
+ }
+ }
+
+ /**
+ * Returns whether the specified Gregorian year is a leap year.
+ * @see #isLeapYear(Era, int)
+ */
+ public boolean isLeapYear(int gregorianYear) {
+ return CalendarUtils.isGregorianLeapYear(gregorianYear);
+ }
+
+ public boolean isLeapYear(Era era, int year) {
+ if (era == null) {
+ return isLeapYear(year);
+ }
+ int gyear = era.getSinceDate().getYear() + year - 1;
+ return isLeapYear(gyear);
+ }
+
+ public void getCalendarDateFromFixedDate(CalendarDate date, long fixedDate) {
+ Date ldate = (Date) date;
+ super.getCalendarDateFromFixedDate(ldate, fixedDate);
+ adjustYear(ldate, (fixedDate - EPOCH_OFFSET) * DAY_IN_MILLIS, 0);
+ }
+}