jdk/src/share/classes/sun/util/calendar/LocalGregorianCalendar.java
changeset 25966 71ee1f15845e
parent 17474 8c100beabcc0
equal deleted inserted replaced
25851:cd6f4557e7fe 25966:71ee1f15845e
     1 /*
     1 /*
     2  * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 
    25 
    26 package sun.util.calendar;
    26 package sun.util.calendar;
    27 
    27 
    28 import java.io.IOException;
    28 import java.security.AccessController;
    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;
    29 import java.util.TimeZone;
    34 
    30 
    35 /**
    31 /**
    36  *
    32  *
    37  * @author Masayoshi Okutsu
    33  * @author Masayoshi Okutsu
    38  * @since 1.6
    34  * @since 1.6
    39  */
    35  */
    40 
    36 
    41 public class LocalGregorianCalendar extends BaseCalendar {
    37 public class LocalGregorianCalendar extends BaseCalendar {
       
    38     private static final Era[] JAPANESE_ERAS = {
       
    39         new Era("Meiji",  "M", -3218832000000L, true),
       
    40         new Era("Taisho", "T", -1812153600000L, true),
       
    41         new Era("Showa",  "S", -1357603200000L, true),
       
    42         new Era("Heisei", "H",   600220800000L, true),
       
    43     };
       
    44 
       
    45     private static boolean isValidEra(Era newEra, Era[] eras) {
       
    46         Era last = eras[eras.length - 1];
       
    47         if (last.getSinceDate().getYear() >= newEra.getSinceDate().getYear()) {
       
    48             return false;
       
    49         }
       
    50         // The new era name should be unique. Its abbr may not.
       
    51         String newName = newEra.getName();
       
    52         for (Era era : eras) {
       
    53             if (era.getName().equals(newName)) {
       
    54                 return false;
       
    55             }
       
    56         }
       
    57         return true;
       
    58     }
       
    59 
    42     private String name;
    60     private String name;
    43     private Era[] eras;
    61     private Era[] eras;
    44 
    62 
    45     public static class Date extends BaseCalendar.Date {
    63     public static class Date extends BaseCalendar.Date {
    46 
    64 
   116             return sb.toString();
   134             return sb.toString();
   117         }
   135         }
   118     }
   136     }
   119 
   137 
   120     static LocalGregorianCalendar getLocalGregorianCalendar(String name) {
   138     static LocalGregorianCalendar getLocalGregorianCalendar(String name) {
   121         Properties calendarProps;
   139         // Only the Japanese calendar is supported.
   122         try {
   140         if (!"japanese".equals(name)) {
   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;
   141             return null;
   131         }
   142         }
   132         List<Era> eras = new ArrayList<>();
   143 
   133         StringTokenizer eraTokens = new StringTokenizer(props, ";");
   144         // Append an era to the predefined eras if it's given by the property.
   134         while (eraTokens.hasMoreTokens()) {
   145         String prop = AccessController.doPrivileged(
   135             String items = eraTokens.nextToken().trim();
   146                 new sun.security.action.GetPropertyAction("jdk.calendar.japanese.supplemental.era"));
   136             StringTokenizer itemTokens = new StringTokenizer(items, ",");
   147         if (prop != null) {
   137             String eraName = null;
   148             Era era = parseEraEntry(prop);
   138             boolean localTime = true;
   149             if (era != null) {
   139             long since = 0;
   150                 if (isValidEra(era, JAPANESE_ERAS)) {
   140             String abbr = null;
   151                     int length = JAPANESE_ERAS.length;
   141 
   152                     Era[] eras = new Era[length + 1];
   142             while (itemTokens.hasMoreTokens()) {
   153                     System.arraycopy(JAPANESE_ERAS, 0, eras, 0, length);
   143                 String item = itemTokens.nextToken();
   154                     eras[length] = era;
   144                 int index = item.indexOf('=');
   155                     return new LocalGregorianCalendar(name, eras);
   145                 // it must be in the key=value form.
   156                 }
   146                 if (index == -1) {
   157             }
       
   158         }
       
   159         return new LocalGregorianCalendar(name, JAPANESE_ERAS);
       
   160     }
       
   161 
       
   162     private static Era parseEraEntry(String entry) {
       
   163         String[] keyValuePairs = entry.split(",");
       
   164         String eraName = null;
       
   165         boolean localTime = true;
       
   166         long since = 0;
       
   167         String abbr = null;
       
   168 
       
   169         for (String item : keyValuePairs) {
       
   170             String[] keyvalue = item.split("=");
       
   171             if (keyvalue.length != 2) {
       
   172                 return null;
       
   173             }
       
   174             String key = keyvalue[0].trim();
       
   175             String value = keyvalue[1].trim();
       
   176             switch (key) {
       
   177             case "name":
       
   178                 eraName = value;
       
   179                 break;
       
   180             case "since":
       
   181                 if (value.endsWith("u")) {
       
   182                     localTime = false;
       
   183                     value = value.substring(0, value.length() - 1);
       
   184                 }
       
   185                 try {
       
   186                     since = Long.parseLong(value);
       
   187                 } catch (NumberFormatException e) {
   147                     return null;
   188                     return null;
   148                 }
   189                 }
   149                 String key = item.substring(0, index);
   190                 break;
   150                 String value = item.substring(index + 1);
   191             case "abbr":
   151                 if ("name".equals(key)) {
   192                 abbr = value;
   152                     eraName = value;
   193                 break;
   153                 } else if ("since".equals(key)) {
   194             default:
   154                     if (value.endsWith("u")) {
   195                 return null;
   155                         localTime = false;
   196             }
   156                         since = Long.parseLong(value.substring(0, value.length() - 1));
   197         }
   157                     } else {
   198         if (eraName == null || eraName.isEmpty()
   158                         since = Long.parseLong(value);
   199                 || abbr == null || abbr.isEmpty()) {
   159                     }
   200             return null;
   160                 } else if ("abbr".equals(key)) {
   201         }
   161                     abbr = value;
   202         return new Era(eraName, abbr, since, localTime);
   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     }
   203     }
   174 
   204 
   175     private LocalGregorianCalendar(String name, Era[] eras) {
   205     private LocalGregorianCalendar(String name, Era[] eras) {
   176         this.name = name;
   206         this.name = name;
   177         this.eras = eras;
   207         this.eras = eras;
   260         }
   290         }
   261         return super.validate(ldate);
   291         return super.validate(ldate);
   262     }
   292     }
   263 
   293 
   264     private boolean validateEra(Era era) {
   294     private boolean validateEra(Era era) {
   265         // Validate the era
   295         for (Era era1 : eras) {
   266         for (int i = 0; i < eras.length; i++) {
   296             if (era == era1) {
   267             if (era == eras[i]) {
       
   268                 return true;
   297                 return true;
   269             }
   298             }
   270         }
   299         }
   271         return false;
   300         return false;
   272     }
   301     }
   331                 }
   360                 }
   332             }
   361             }
   333         }
   362         }
   334         if (i >= 0) {
   363         if (i >= 0) {
   335             ldate.setLocalEra(era);
   364             ldate.setLocalEra(era);
       
   365             @SuppressWarnings("null")
   336             int y = ldate.getNormalizedYear() - era.getSinceDate().getYear() + 1;
   366             int y = ldate.getNormalizedYear() - era.getSinceDate().getYear() + 1;
   337             ldate.setLocalYear(y);
   367             ldate.setLocalYear(y);
   338         } else {
   368         } else {
   339             // Set Gregorian year with no era
   369             // Set Gregorian year with no era
   340             ldate.setEra(null);
   370             ldate.setEra(null);