Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/util/calendar/LocalGregorianCalendar.java
38918 views
/*1* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.util.calendar;2627import java.io.IOException;28import java.util.ArrayList;29import java.util.List;30import java.util.Properties;31import java.util.StringTokenizer;32import java.util.TimeZone;3334/**35*36* @author Masayoshi Okutsu37* @since 1.638*/3940public class LocalGregorianCalendar extends BaseCalendar {41private String name;42private Era[] eras;4344public static class Date extends BaseCalendar.Date {4546protected Date() {47super();48}4950protected Date(TimeZone zone) {51super(zone);52}5354private int gregorianYear = FIELD_UNDEFINED;5556@Override57public Date setEra(Era era) {58if (getEra() != era) {59super.setEra(era);60gregorianYear = FIELD_UNDEFINED;61}62return this;63}6465@Override66public Date addYear(int localYear) {67super.addYear(localYear);68gregorianYear += localYear;69return this;70}7172@Override73public Date setYear(int localYear) {74if (getYear() != localYear) {75super.setYear(localYear);76gregorianYear = FIELD_UNDEFINED;77}78return this;79}8081@Override82public int getNormalizedYear() {83return gregorianYear;84}8586@Override87public void setNormalizedYear(int normalizedYear) {88this.gregorianYear = normalizedYear;89}9091void setLocalEra(Era era) {92super.setEra(era);93}9495void setLocalYear(int year) {96super.setYear(year);97}9899@Override100public String toString() {101String time = super.toString();102time = time.substring(time.indexOf('T'));103StringBuffer sb = new StringBuffer();104Era era = getEra();105if (era != null) {106String abbr = era.getAbbreviation();107if (abbr != null) {108sb.append(abbr);109}110}111sb.append(getYear()).append('.');112CalendarUtils.sprintf0d(sb, getMonth(), 2).append('.');113CalendarUtils.sprintf0d(sb, getDayOfMonth(), 2);114sb.append(time);115return sb.toString();116}117}118119static LocalGregorianCalendar getLocalGregorianCalendar(String name) {120Properties calendarProps;121try {122calendarProps = CalendarSystem.getCalendarProperties();123} catch (IOException | IllegalArgumentException e) {124throw new InternalError(e);125}126// Parse calendar.*.eras127String props = calendarProps.getProperty("calendar." + name + ".eras");128if (props == null) {129return null;130}131List<Era> eras = new ArrayList<>();132StringTokenizer eraTokens = new StringTokenizer(props, ";");133while (eraTokens.hasMoreTokens()) {134String items = eraTokens.nextToken().trim();135StringTokenizer itemTokens = new StringTokenizer(items, ",");136String eraName = null;137boolean localTime = true;138long since = 0;139String abbr = null;140141while (itemTokens.hasMoreTokens()) {142String item = itemTokens.nextToken();143int index = item.indexOf('=');144// it must be in the key=value form.145if (index == -1) {146return null;147}148String key = item.substring(0, index);149String value = item.substring(index + 1);150if ("name".equals(key)) {151eraName = value;152} else if ("since".equals(key)) {153if (value.endsWith("u")) {154localTime = false;155since = Long.parseLong(value.substring(0, value.length() - 1));156} else {157since = Long.parseLong(value);158}159} else if ("abbr".equals(key)) {160abbr = value;161} else {162throw new RuntimeException("Unknown key word: " + key);163}164}165Era era = new Era(eraName, abbr, since, localTime);166eras.add(era);167}168Era[] eraArray = new Era[eras.size()];169eras.toArray(eraArray);170171return new LocalGregorianCalendar(name, eraArray);172}173174private LocalGregorianCalendar(String name, Era[] eras) {175this.name = name;176this.eras = eras;177setEras(eras);178}179180@Override181public String getName() {182return name;183}184185@Override186public Date getCalendarDate() {187return getCalendarDate(System.currentTimeMillis(), newCalendarDate());188}189190@Override191public Date getCalendarDate(long millis) {192return getCalendarDate(millis, newCalendarDate());193}194195@Override196public Date getCalendarDate(long millis, TimeZone zone) {197return getCalendarDate(millis, newCalendarDate(zone));198}199200@Override201public Date getCalendarDate(long millis, CalendarDate date) {202Date ldate = (Date) super.getCalendarDate(millis, date);203return adjustYear(ldate, millis, ldate.getZoneOffset());204}205206private Date adjustYear(Date ldate, long millis, int zoneOffset) {207int i;208for (i = eras.length - 1; i >= 0; --i) {209Era era = eras[i];210long since = era.getSince(null);211if (era.isLocalTime()) {212since -= zoneOffset;213}214if (millis >= since) {215ldate.setLocalEra(era);216int y = ldate.getNormalizedYear() - era.getSinceDate().getYear() + 1;217ldate.setLocalYear(y);218break;219}220}221if (i < 0) {222ldate.setLocalEra(null);223ldate.setLocalYear(ldate.getNormalizedYear());224}225ldate.setNormalized(true);226return ldate;227}228229@Override230public Date newCalendarDate() {231return new Date();232}233234@Override235public Date newCalendarDate(TimeZone zone) {236return new Date(zone);237}238239@Override240public boolean validate(CalendarDate date) {241Date ldate = (Date) date;242Era era = ldate.getEra();243if (era != null) {244if (!validateEra(era)) {245return false;246}247ldate.setNormalizedYear(era.getSinceDate().getYear() + ldate.getYear() - 1);248Date tmp = newCalendarDate(date.getZone());249tmp.setEra(era).setDate(date.getYear(), date.getMonth(), date.getDayOfMonth());250normalize(tmp);251if (tmp.getEra() != era) {252return false;253}254} else {255if (date.getYear() >= eras[0].getSinceDate().getYear()) {256return false;257}258ldate.setNormalizedYear(ldate.getYear());259}260return super.validate(ldate);261}262263private boolean validateEra(Era era) {264// Validate the era265for (int i = 0; i < eras.length; i++) {266if (era == eras[i]) {267return true;268}269}270return false;271}272273@Override274public boolean normalize(CalendarDate date) {275if (date.isNormalized()) {276return true;277}278279normalizeYear(date);280Date ldate = (Date) date;281282// Normalize it as a Gregorian date and get its millisecond value283super.normalize(ldate);284285boolean hasMillis = false;286long millis = 0;287int year = ldate.getNormalizedYear();288int i;289Era era = null;290for (i = eras.length - 1; i >= 0; --i) {291era = eras[i];292if (era.isLocalTime()) {293CalendarDate sinceDate = era.getSinceDate();294int sinceYear = sinceDate.getYear();295if (year > sinceYear) {296break;297}298if (year == sinceYear) {299int month = ldate.getMonth();300int sinceMonth = sinceDate.getMonth();301if (month > sinceMonth) {302break;303}304if (month == sinceMonth) {305int day = ldate.getDayOfMonth();306int sinceDay = sinceDate.getDayOfMonth();307if (day > sinceDay) {308break;309}310if (day == sinceDay) {311long timeOfDay = ldate.getTimeOfDay();312long sinceTimeOfDay = sinceDate.getTimeOfDay();313if (timeOfDay >= sinceTimeOfDay) {314break;315}316--i;317break;318}319}320}321} else {322if (!hasMillis) {323millis = super.getTime(date);324hasMillis = true;325}326327long since = era.getSince(date.getZone());328if (millis >= since) {329break;330}331}332}333if (i >= 0) {334ldate.setLocalEra(era);335int y = ldate.getNormalizedYear() - era.getSinceDate().getYear() + 1;336ldate.setLocalYear(y);337} else {338// Set Gregorian year with no era339ldate.setEra(null);340ldate.setLocalYear(year);341ldate.setNormalizedYear(year);342}343ldate.setNormalized(true);344return true;345}346347@Override348void normalizeMonth(CalendarDate date) {349normalizeYear(date);350super.normalizeMonth(date);351}352353void normalizeYear(CalendarDate date) {354Date ldate = (Date) date;355// Set the supposed-to-be-correct Gregorian year first356// e.g., Showa 90 becomes 2015 (1926 + 90 - 1).357Era era = ldate.getEra();358if (era == null || !validateEra(era)) {359ldate.setNormalizedYear(ldate.getYear());360} else {361ldate.setNormalizedYear(era.getSinceDate().getYear() + ldate.getYear() - 1);362}363}364365/**366* Returns whether the specified Gregorian year is a leap year.367* @see #isLeapYear(Era, int)368*/369@Override370public boolean isLeapYear(int gregorianYear) {371return CalendarUtils.isGregorianLeapYear(gregorianYear);372}373374public boolean isLeapYear(Era era, int year) {375if (era == null) {376return isLeapYear(year);377}378int gyear = era.getSinceDate().getYear() + year - 1;379return isLeapYear(gyear);380}381382@Override383public void getCalendarDateFromFixedDate(CalendarDate date, long fixedDate) {384Date ldate = (Date) date;385super.getCalendarDateFromFixedDate(ldate, fixedDate);386adjustYear(ldate, (fixedDate - EPOCH_OFFSET) * DAY_IN_MILLIS, 0);387}388}389390391