381 lines · 12.3 KB · Java
RawDownload
/* * 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);    }}