src/share/classes/sun/util/calendar/LocalGregorianCalendar.java

Print this page


   1 /*
   2  * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.util.calendar;
  27 
  28 import java.io.File;
  29 import java.io.FileInputStream;
  30 import java.io.IOException;
  31 import java.security.AccessController;
  32 import java.security.PrivilegedActionException;
  33 import java.security.PrivilegedExceptionAction;
  34 import java.util.ArrayList;
  35 import java.util.List;
  36 import java.util.Properties;
  37 import java.util.StringTokenizer;
  38 import java.util.TimeZone;
  39 
  40 /**
  41  *
  42  * @author Masayoshi Okutsu
  43  * @since 1.6
  44  */
  45 
  46 public class LocalGregorianCalendar extends BaseCalendar {
  47     private String name;
  48     private Era[] eras;
  49 
  50     public static class Date extends BaseCalendar.Date {
  51 
  52         protected Date() {
  53             super();
  54         }
  55 
  56         protected Date(TimeZone zone) {
  57             super(zone);
  58         }
  59 
  60         private int gregorianYear = FIELD_UNDEFINED;
  61 

  62         public Date setEra(Era era) {
  63             if (getEra() != era) {
  64                 super.setEra(era);
  65                 gregorianYear = FIELD_UNDEFINED;
  66             }
  67             return this;
  68         }
  69 

  70         public Date addYear(int localYear) {
  71             super.addYear(localYear);
  72             gregorianYear += localYear;
  73             return this;
  74         }
  75 

  76         public Date setYear(int localYear) {
  77             if (getYear() != localYear) {
  78                 super.setYear(localYear);
  79                 gregorianYear = FIELD_UNDEFINED;
  80             }
  81             return this;
  82         }
  83 

  84         public int getNormalizedYear() {
  85             return gregorianYear;
  86         }
  87 

  88         public void setNormalizedYear(int normalizedYear) {
  89             this.gregorianYear = normalizedYear;
  90         }
  91 
  92         void setLocalEra(Era era) {
  93             super.setEra(era);
  94         }
  95 
  96         void setLocalYear(int year) {
  97             super.setYear(year);
  98         }
  99 

 100         public String toString() {
 101             String time = super.toString();
 102             time = time.substring(time.indexOf('T'));
 103             StringBuffer sb = new StringBuffer();
 104             Era era = getEra();
 105             if (era != null) {
 106                 String abbr = era.getAbbreviation();
 107                 if (abbr != null) {
 108                     sb.append(abbr);
 109                 }
 110             }
 111             sb.append(getYear()).append('.');
 112             CalendarUtils.sprintf0d(sb, getMonth(), 2).append('.');
 113             CalendarUtils.sprintf0d(sb, getDayOfMonth(), 2);
 114             sb.append(time);
 115             return sb.toString();
 116         }
 117     }
 118 
 119     static LocalGregorianCalendar getLocalGregorianCalendar(String name) {
 120         Properties calendarProps = null;
 121         try {
 122             String homeDir = AccessController.doPrivileged(
 123                 new sun.security.action.GetPropertyAction("java.home"));
 124             final String fname = homeDir + File.separator + "lib" + File.separator
 125                                  + "calendars.properties";
 126             calendarProps = AccessController.doPrivileged(new PrivilegedExceptionAction<Properties>() {
 127                 public Properties run() throws IOException {
 128                     Properties props = new Properties();
 129                     try (FileInputStream fis = new FileInputStream(fname)) {
 130                         props.load(fis);
 131                     }
 132                     return props;
 133                 }
 134             });
 135         } catch (PrivilegedActionException e) {
 136             throw new RuntimeException(e.getException());
 137         }
 138 
 139         // Parse calendar.*.eras
 140         String props = calendarProps.getProperty("calendar." + name + ".eras");
 141         if (props == null) {
 142             return null;
 143         }
 144         List<Era> eras = new ArrayList<>();
 145         StringTokenizer eraTokens = new StringTokenizer(props, ";");
 146         while (eraTokens.hasMoreTokens()) {
 147             String items = eraTokens.nextToken().trim();
 148             StringTokenizer itemTokens = new StringTokenizer(items, ",");
 149             String eraName = null;
 150             boolean localTime = true;
 151             long since = 0;
 152             String abbr = null;
 153 
 154             while (itemTokens.hasMoreTokens()) {
 155                 String item = itemTokens.nextToken();
 156                 int index = item.indexOf('=');
 157                 // it must be in the key=value form.
 158                 if (index == -1) {


 173                     abbr = value;
 174                 } else {
 175                     throw new RuntimeException("Unknown key word: " + key);
 176                 }
 177             }
 178             Era era = new Era(eraName, abbr, since, localTime);
 179             eras.add(era);
 180         }
 181         Era[] eraArray = new Era[eras.size()];
 182         eras.toArray(eraArray);
 183 
 184         return new LocalGregorianCalendar(name, eraArray);
 185     }
 186 
 187     private LocalGregorianCalendar(String name, Era[] eras) {
 188         this.name = name;
 189         this.eras = eras;
 190         setEras(eras);
 191     }
 192 

 193     public String getName() {
 194         return name;
 195     }
 196 

 197     public Date getCalendarDate() {
 198         return getCalendarDate(System.currentTimeMillis(), newCalendarDate());
 199     }
 200 

 201     public Date getCalendarDate(long millis) {
 202         return getCalendarDate(millis, newCalendarDate());
 203     }
 204 

 205     public Date getCalendarDate(long millis, TimeZone zone) {
 206         return getCalendarDate(millis, newCalendarDate(zone));
 207     }
 208 

 209     public Date getCalendarDate(long millis, CalendarDate date) {
 210         Date ldate = (Date) super.getCalendarDate(millis, date);
 211         return adjustYear(ldate, millis, ldate.getZoneOffset());
 212     }
 213 
 214     private Date adjustYear(Date ldate, long millis, int zoneOffset) {
 215         int i;
 216         for (i = eras.length - 1; i >= 0; --i) {
 217             Era era = eras[i];
 218             long since = era.getSince(null);
 219             if (era.isLocalTime()) {
 220                 since -= zoneOffset;
 221             }
 222             if (millis >= since) {
 223                 ldate.setLocalEra(era);
 224                 int y = ldate.getNormalizedYear() - era.getSinceDate().getYear() + 1;
 225                 ldate.setLocalYear(y);
 226                 break;
 227             }
 228         }
 229         if (i < 0) {
 230             ldate.setLocalEra(null);
 231             ldate.setLocalYear(ldate.getNormalizedYear());
 232         }
 233         ldate.setNormalized(true);
 234         return ldate;
 235     }
 236 

 237     public Date newCalendarDate() {
 238         return new Date();
 239     }
 240 

 241     public Date newCalendarDate(TimeZone zone) {
 242         return new Date(zone);
 243     }
 244 

 245     public boolean validate(CalendarDate date) {
 246         Date ldate = (Date) date;
 247         Era era = ldate.getEra();
 248         if (era != null) {
 249             if (!validateEra(era)) {
 250                 return false;
 251             }
 252             ldate.setNormalizedYear(era.getSinceDate().getYear() + ldate.getYear());









 253         } else {
 254             ldate.setNormalizedYear(ldate.getYear());
 255         }
 256         return super.validate(ldate);
 257     }
 258 
 259     private boolean validateEra(Era era) {
 260         // Validate the era
 261         for (int i = 0; i < eras.length; i++) {
 262             if (era == eras[i]) {
 263                 return true;
 264             }
 265         }
 266         return false;
 267     }
 268 

 269     public boolean normalize(CalendarDate date) {
 270         if (date.isNormalized()) {
 271             return true;
 272         }
 273 
 274         normalizeYear(date);
 275         Date ldate = (Date) date;
 276 
 277         // Normalize it as a Gregorian date and get its millisecond value
 278         super.normalize(ldate);
 279 
 280         boolean hasMillis = false;
 281         long millis = 0;
 282         int year = ldate.getNormalizedYear();
 283         int i;
 284         Era era = null;
 285         for (i = eras.length - 1; i >= 0; --i) {
 286             era = eras[i];
 287             if (era.isLocalTime()) {
 288                 CalendarDate sinceDate = era.getSinceDate();


 322                 long since = era.getSince(date.getZone());
 323                 if (millis >= since) {
 324                     break;
 325                 }
 326             }
 327         }
 328         if (i >= 0) {
 329             ldate.setLocalEra(era);
 330             int y = ldate.getNormalizedYear() - era.getSinceDate().getYear() + 1;
 331             ldate.setLocalYear(y);
 332         } else {
 333             // Set Gregorian year with no era
 334             ldate.setEra(null);
 335             ldate.setLocalYear(year);
 336             ldate.setNormalizedYear(year);
 337         }
 338         ldate.setNormalized(true);
 339         return true;
 340     }
 341 

 342     void normalizeMonth(CalendarDate date) {
 343         normalizeYear(date);
 344         super.normalizeMonth(date);
 345     }
 346 
 347     void normalizeYear(CalendarDate date) {
 348         Date ldate = (Date) date;
 349         // Set the supposed-to-be-correct Gregorian year first
 350         // e.g., Showa 90 becomes 2015 (1926 + 90 - 1).
 351         Era era = ldate.getEra();
 352         if (era == null || !validateEra(era)) {
 353             ldate.setNormalizedYear(ldate.getYear());
 354         } else {
 355             ldate.setNormalizedYear(era.getSinceDate().getYear() + ldate.getYear() - 1);
 356         }
 357     }
 358 
 359     /**
 360      * Returns whether the specified Gregorian year is a leap year.
 361      * @see #isLeapYear(Era, int)
 362      */

 363     public boolean isLeapYear(int gregorianYear) {
 364         return CalendarUtils.isGregorianLeapYear(gregorianYear);
 365     }
 366 
 367     public boolean isLeapYear(Era era, int year) {
 368         if (era == null) {
 369             return isLeapYear(year);
 370         }
 371         int gyear = era.getSinceDate().getYear() + year - 1;
 372         return isLeapYear(gyear);
 373     }
 374 

 375     public void getCalendarDateFromFixedDate(CalendarDate date, long fixedDate) {
 376         Date ldate = (Date) date;
 377         super.getCalendarDateFromFixedDate(ldate, fixedDate);
 378         adjustYear(ldate, (fixedDate - EPOCH_OFFSET) * DAY_IN_MILLIS, 0);
 379     }
 380 }
   1 /*
   2  * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.util.calendar;
  27 


  28 import java.io.IOException;



  29 import java.util.ArrayList;
  30 import java.util.List;
  31 import java.util.Properties;
  32 import java.util.StringTokenizer;
  33 import java.util.TimeZone;
  34 
  35 /**
  36  *
  37  * @author Masayoshi Okutsu
  38  * @since 1.6
  39  */
  40 
  41 public class LocalGregorianCalendar extends BaseCalendar {
  42     private String name;
  43     private Era[] eras;
  44 
  45     public static class Date extends BaseCalendar.Date {
  46 
  47         protected Date() {
  48             super();
  49         }
  50 
  51         protected Date(TimeZone zone) {
  52             super(zone);
  53         }
  54 
  55         private int gregorianYear = FIELD_UNDEFINED;
  56 
  57         @Override
  58         public Date setEra(Era era) {
  59             if (getEra() != era) {
  60                 super.setEra(era);
  61                 gregorianYear = FIELD_UNDEFINED;
  62             }
  63             return this;
  64         }
  65 
  66         @Override
  67         public Date addYear(int localYear) {
  68             super.addYear(localYear);
  69             gregorianYear += localYear;
  70             return this;
  71         }
  72 
  73         @Override
  74         public Date setYear(int localYear) {
  75             if (getYear() != localYear) {
  76                 super.setYear(localYear);
  77                 gregorianYear = FIELD_UNDEFINED;
  78             }
  79             return this;
  80         }
  81 
  82         @Override
  83         public int getNormalizedYear() {
  84             return gregorianYear;
  85         }
  86 
  87         @Override
  88         public void setNormalizedYear(int normalizedYear) {
  89             this.gregorianYear = normalizedYear;
  90         }
  91 
  92         void setLocalEra(Era era) {
  93             super.setEra(era);
  94         }
  95 
  96         void setLocalYear(int year) {
  97             super.setYear(year);
  98         }
  99 
 100         @Override
 101         public String toString() {
 102             String time = super.toString();
 103             time = time.substring(time.indexOf('T'));
 104             StringBuffer sb = new StringBuffer();
 105             Era era = getEra();
 106             if (era != null) {
 107                 String abbr = era.getAbbreviation();
 108                 if (abbr != null) {
 109                     sb.append(abbr);
 110                 }
 111             }
 112             sb.append(getYear()).append('.');
 113             CalendarUtils.sprintf0d(sb, getMonth(), 2).append('.');
 114             CalendarUtils.sprintf0d(sb, getDayOfMonth(), 2);
 115             sb.append(time);
 116             return sb.toString();
 117         }
 118     }
 119 
 120     static LocalGregorianCalendar getLocalGregorianCalendar(String name) {
 121         Properties calendarProps;
 122         try {
 123             calendarProps = CalendarSystem.getCalendarProperties();
 124         } catch (IOException | IllegalArgumentException e) {
 125             throw new InternalError(e);












 126         }

 127         // Parse calendar.*.eras
 128         String props = calendarProps.getProperty("calendar." + name + ".eras");
 129         if (props == null) {
 130             return null;
 131         }
 132         List<Era> eras = new ArrayList<>();
 133         StringTokenizer eraTokens = new StringTokenizer(props, ";");
 134         while (eraTokens.hasMoreTokens()) {
 135             String items = eraTokens.nextToken().trim();
 136             StringTokenizer itemTokens = new StringTokenizer(items, ",");
 137             String eraName = null;
 138             boolean localTime = true;
 139             long since = 0;
 140             String abbr = null;
 141 
 142             while (itemTokens.hasMoreTokens()) {
 143                 String item = itemTokens.nextToken();
 144                 int index = item.indexOf('=');
 145                 // it must be in the key=value form.
 146                 if (index == -1) {


 161                     abbr = value;
 162                 } else {
 163                     throw new RuntimeException("Unknown key word: " + key);
 164                 }
 165             }
 166             Era era = new Era(eraName, abbr, since, localTime);
 167             eras.add(era);
 168         }
 169         Era[] eraArray = new Era[eras.size()];
 170         eras.toArray(eraArray);
 171 
 172         return new LocalGregorianCalendar(name, eraArray);
 173     }
 174 
 175     private LocalGregorianCalendar(String name, Era[] eras) {
 176         this.name = name;
 177         this.eras = eras;
 178         setEras(eras);
 179     }
 180 
 181     @Override
 182     public String getName() {
 183         return name;
 184     }
 185 
 186     @Override
 187     public Date getCalendarDate() {
 188         return getCalendarDate(System.currentTimeMillis(), newCalendarDate());
 189     }
 190 
 191     @Override
 192     public Date getCalendarDate(long millis) {
 193         return getCalendarDate(millis, newCalendarDate());
 194     }
 195 
 196     @Override
 197     public Date getCalendarDate(long millis, TimeZone zone) {
 198         return getCalendarDate(millis, newCalendarDate(zone));
 199     }
 200 
 201     @Override
 202     public Date getCalendarDate(long millis, CalendarDate date) {
 203         Date ldate = (Date) super.getCalendarDate(millis, date);
 204         return adjustYear(ldate, millis, ldate.getZoneOffset());
 205     }
 206 
 207     private Date adjustYear(Date ldate, long millis, int zoneOffset) {
 208         int i;
 209         for (i = eras.length - 1; i >= 0; --i) {
 210             Era era = eras[i];
 211             long since = era.getSince(null);
 212             if (era.isLocalTime()) {
 213                 since -= zoneOffset;
 214             }
 215             if (millis >= since) {
 216                 ldate.setLocalEra(era);
 217                 int y = ldate.getNormalizedYear() - era.getSinceDate().getYear() + 1;
 218                 ldate.setLocalYear(y);
 219                 break;
 220             }
 221         }
 222         if (i < 0) {
 223             ldate.setLocalEra(null);
 224             ldate.setLocalYear(ldate.getNormalizedYear());
 225         }
 226         ldate.setNormalized(true);
 227         return ldate;
 228     }
 229 
 230     @Override
 231     public Date newCalendarDate() {
 232         return new Date();
 233     }
 234 
 235     @Override
 236     public Date newCalendarDate(TimeZone zone) {
 237         return new Date(zone);
 238     }
 239 
 240     @Override
 241     public boolean validate(CalendarDate date) {
 242         Date ldate = (Date) date;
 243         Era era = ldate.getEra();
 244         if (era != null) {
 245             if (!validateEra(era)) {
 246                 return false;
 247             }
 248             ldate.setNormalizedYear(era.getSinceDate().getYear() + ldate.getYear() - 1);
 249             // If it's not the last Era, validate the date.
 250             if (era != eras[eras.length - 1]) {
 251                 Date tmp = newCalendarDate(date.getZone());
 252                 tmp.setEra(era).setDate(date.getYear(), date.getMonth(), date.getDayOfMonth());
 253                 normalize(tmp);
 254                 if (tmp.getEra() != era) {
 255                     return false;
 256                 }
 257             }
 258         } else {
 259             ldate.setNormalizedYear(ldate.getYear());
 260         }
 261         return super.validate(ldate);
 262     }
 263 
 264     private boolean validateEra(Era era) {
 265         // Validate the era
 266         for (int i = 0; i < eras.length; i++) {
 267             if (era == eras[i]) {
 268                 return true;
 269             }
 270         }
 271         return false;
 272     }
 273 
 274     @Override
 275     public boolean normalize(CalendarDate date) {
 276         if (date.isNormalized()) {
 277             return true;
 278         }
 279 
 280         normalizeYear(date);
 281         Date ldate = (Date) date;
 282 
 283         // Normalize it as a Gregorian date and get its millisecond value
 284         super.normalize(ldate);
 285 
 286         boolean hasMillis = false;
 287         long millis = 0;
 288         int year = ldate.getNormalizedYear();
 289         int i;
 290         Era era = null;
 291         for (i = eras.length - 1; i >= 0; --i) {
 292             era = eras[i];
 293             if (era.isLocalTime()) {
 294                 CalendarDate sinceDate = era.getSinceDate();


 328                 long since = era.getSince(date.getZone());
 329                 if (millis >= since) {
 330                     break;
 331                 }
 332             }
 333         }
 334         if (i >= 0) {
 335             ldate.setLocalEra(era);
 336             int y = ldate.getNormalizedYear() - era.getSinceDate().getYear() + 1;
 337             ldate.setLocalYear(y);
 338         } else {
 339             // Set Gregorian year with no era
 340             ldate.setEra(null);
 341             ldate.setLocalYear(year);
 342             ldate.setNormalizedYear(year);
 343         }
 344         ldate.setNormalized(true);
 345         return true;
 346     }
 347 
 348     @Override
 349     void normalizeMonth(CalendarDate date) {
 350         normalizeYear(date);
 351         super.normalizeMonth(date);
 352     }
 353 
 354     void normalizeYear(CalendarDate date) {
 355         Date ldate = (Date) date;
 356         // Set the supposed-to-be-correct Gregorian year first
 357         // e.g., Showa 90 becomes 2015 (1926 + 90 - 1).
 358         Era era = ldate.getEra();
 359         if (era == null || !validateEra(era)) {
 360             ldate.setNormalizedYear(ldate.getYear());
 361         } else {
 362             ldate.setNormalizedYear(era.getSinceDate().getYear() + ldate.getYear() - 1);
 363         }
 364     }
 365 
 366     /**
 367      * Returns whether the specified Gregorian year is a leap year.
 368      * @see #isLeapYear(Era, int)
 369      */
 370     @Override
 371     public boolean isLeapYear(int gregorianYear) {
 372         return CalendarUtils.isGregorianLeapYear(gregorianYear);
 373     }
 374 
 375     public boolean isLeapYear(Era era, int year) {
 376         if (era == null) {
 377             return isLeapYear(year);
 378         }
 379         int gyear = era.getSinceDate().getYear() + year - 1;
 380         return isLeapYear(gyear);
 381     }
 382 
 383     @Override
 384     public void getCalendarDateFromFixedDate(CalendarDate date, long fixedDate) {
 385         Date ldate = (Date) date;
 386         super.getCalendarDateFromFixedDate(ldate, fixedDate);
 387         adjustYear(ldate, (fixedDate - EPOCH_OFFSET) * DAY_IN_MILLIS, 0);
 388     }
 389 }