/* * Copyright (c) 2005, 2011, 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.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(); try (FileInputStream fis = new FileInputStream(fname)) { props.load(fis); } 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); }}
/*
* Copyright (c) 2005, 2011, 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.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();
try (FileInputStream fis = new FileInputStream(fname)) {
props.load(fis);
}
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);
}
}