Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/util/calendar/CalendarSystem.java
38918 views
1
/*
2
* Copyright (c) 2000, 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.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.Properties;
35
import java.util.TimeZone;
36
import java.util.concurrent.ConcurrentHashMap;
37
import java.util.concurrent.ConcurrentMap;
38
39
/**
40
* <code>CalendarSystem</code> is an abstract class that defines the
41
* programming interface to deal with calendar date and time.
42
*
43
* <p><code>CalendarSystem</code> instances are singletons. For
44
* example, there exists only one Gregorian calendar instance in the
45
* Java runtime environment. A singleton instance can be obtained
46
* calling one of the static factory methods.
47
*
48
* <h4>CalendarDate</h4>
49
*
50
* <p>For the methods in a <code>CalendarSystem</code> that manipulate
51
* a <code>CalendarDate</code>, <code>CalendarDate</code>s that have
52
* been created by the <code>CalendarSystem</code> must be
53
* specified. Otherwise, the methods throw an exception. This is
54
* because, for example, a Chinese calendar date can't be understood
55
* by the Hebrew calendar system.
56
*
57
* <h4>Calendar names</h4>
58
*
59
* Each calendar system has a unique name to be identified. The Java
60
* runtime in this release supports the following calendar systems.
61
*
62
* <pre>
63
* Name Calendar System
64
* ---------------------------------------
65
* gregorian Gregorian Calendar
66
* julian Julian Calendar
67
* japanese Japanese Imperial Calendar
68
* </pre>
69
*
70
* @see CalendarDate
71
* @author Masayoshi Okutsu
72
* @since 1.5
73
*/
74
75
public abstract class CalendarSystem {
76
77
/////////////////////// Calendar Factory Methods /////////////////////////
78
79
private volatile static boolean initialized = false;
80
81
// Map of calendar names and calendar class names
82
private static ConcurrentMap<String, String> names;
83
84
// Map of calendar names and CalendarSystem instances
85
private static ConcurrentMap<String,CalendarSystem> calendars;
86
87
private static final String PACKAGE_NAME = "sun.util.calendar.";
88
89
private static final String[] namePairs = {
90
"gregorian", "Gregorian",
91
"japanese", "LocalGregorianCalendar",
92
"julian", "JulianCalendar",
93
/*
94
"hebrew", "HebrewCalendar",
95
"iso8601", "ISOCalendar",
96
"taiwanese", "LocalGregorianCalendar",
97
"thaibuddhist", "LocalGregorianCalendar",
98
*/
99
};
100
101
private static void initNames() {
102
ConcurrentMap<String,String> nameMap = new ConcurrentHashMap<>();
103
104
// Associate a calendar name with its class name and the
105
// calendar class name with its date class name.
106
StringBuilder clName = new StringBuilder();
107
for (int i = 0; i < namePairs.length; i += 2) {
108
clName.setLength(0);
109
String cl = clName.append(PACKAGE_NAME).append(namePairs[i+1]).toString();
110
nameMap.put(namePairs[i], cl);
111
}
112
synchronized (CalendarSystem.class) {
113
if (!initialized) {
114
names = nameMap;
115
calendars = new ConcurrentHashMap<>();
116
initialized = true;
117
}
118
}
119
}
120
121
private final static Gregorian GREGORIAN_INSTANCE = new Gregorian();
122
123
/**
124
* Returns the singleton instance of the <code>Gregorian</code>
125
* calendar system.
126
*
127
* @return the <code>Gregorian</code> instance
128
*/
129
public static Gregorian getGregorianCalendar() {
130
return GREGORIAN_INSTANCE;
131
}
132
133
/**
134
* Returns a <code>CalendarSystem</code> specified by the calendar
135
* name. The calendar name has to be one of the supported calendar
136
* names.
137
*
138
* @param calendarName the calendar name
139
* @return the <code>CalendarSystem</code> specified by
140
* <code>calendarName</code>, or null if there is no
141
* <code>CalendarSystem</code> associated with the given calendar name.
142
*/
143
public static CalendarSystem forName(String calendarName) {
144
if ("gregorian".equals(calendarName)) {
145
return GREGORIAN_INSTANCE;
146
}
147
148
if (!initialized) {
149
initNames();
150
}
151
152
CalendarSystem cal = calendars.get(calendarName);
153
if (cal != null) {
154
return cal;
155
}
156
157
String className = names.get(calendarName);
158
if (className == null) {
159
return null; // Unknown calendar name
160
}
161
162
if (className.endsWith("LocalGregorianCalendar")) {
163
// Create the specific kind of local Gregorian calendar system
164
cal = LocalGregorianCalendar.getLocalGregorianCalendar(calendarName);
165
} else {
166
try {
167
Class<?> cl = Class.forName(className);
168
cal = (CalendarSystem) cl.newInstance();
169
} catch (Exception e) {
170
throw new InternalError(e);
171
}
172
}
173
if (cal == null) {
174
return null;
175
}
176
CalendarSystem cs = calendars.putIfAbsent(calendarName, cal);
177
return (cs == null) ? cal : cs;
178
}
179
180
/**
181
* Returns a {@link Properties} loaded from lib/calendars.properties.
182
*
183
* @return a {@link Properties} loaded from lib/calendars.properties
184
* @throws IOException if an error occurred when reading from the input stream
185
* @throws IllegalArgumentException if the input stream contains any malformed
186
* Unicode escape sequences
187
*/
188
public static Properties getCalendarProperties() throws IOException {
189
Properties calendarProps = null;
190
try {
191
String homeDir = AccessController.doPrivileged(
192
new sun.security.action.GetPropertyAction("java.home"));
193
final String fname = homeDir + File.separator + "lib" + File.separator
194
+ "calendars.properties";
195
calendarProps = AccessController.doPrivileged(new PrivilegedExceptionAction<Properties>() {
196
@Override
197
public Properties run() throws IOException {
198
Properties props = new Properties();
199
try (FileInputStream fis = new FileInputStream(fname)) {
200
props.load(fis);
201
}
202
return props;
203
}
204
});
205
} catch (PrivilegedActionException e) {
206
Throwable cause = e.getCause();
207
if (cause instanceof IOException) {
208
throw (IOException) cause;
209
} else if (cause instanceof IllegalArgumentException) {
210
throw (IllegalArgumentException) cause;
211
}
212
// Should not happen
213
throw new InternalError(cause);
214
}
215
return calendarProps;
216
}
217
218
//////////////////////////////// Calendar API //////////////////////////////////
219
220
/**
221
* Returns the name of this calendar system.
222
*/
223
public abstract String getName();
224
225
public abstract CalendarDate getCalendarDate();
226
227
/**
228
* Calculates calendar fields from the specified number of
229
* milliseconds since the Epoch, January 1, 1970 00:00:00 UTC
230
* (Gregorian). This method doesn't check overflow or underflow
231
* when adjusting the millisecond value (representing UTC) with
232
* the time zone offsets (i.e., the GMT offset and amount of
233
* daylight saving).
234
*
235
* @param millis the offset value in milliseconds from January 1,
236
* 1970 00:00:00 UTC (Gregorian).
237
* @return a <code>CalendarDate</code> instance that contains the
238
* calculated calendar field values.
239
*/
240
public abstract CalendarDate getCalendarDate(long millis);
241
242
public abstract CalendarDate getCalendarDate(long millis, CalendarDate date);
243
244
public abstract CalendarDate getCalendarDate(long millis, TimeZone zone);
245
246
/**
247
* Constructs a <code>CalendarDate</code> that is specific to this
248
* calendar system. All calendar fields have their initial
249
* values. The {@link TimeZone#getDefault() default time zone} is
250
* set to the instance.
251
*
252
* @return a <code>CalendarDate</code> instance that contains the initial
253
* calendar field values.
254
*/
255
public abstract CalendarDate newCalendarDate();
256
257
public abstract CalendarDate newCalendarDate(TimeZone zone);
258
259
/**
260
* Returns the number of milliseconds since the Epoch, January 1,
261
* 1970 00:00:00 UTC (Gregorian), represented by the specified
262
* <code>CalendarDate</code>.
263
*
264
* @param date the <code>CalendarDate</code> from which the time
265
* value is calculated
266
* @return the number of milliseconds since the Epoch.
267
*/
268
public abstract long getTime(CalendarDate date);
269
270
/**
271
* Returns the length in days of the specified year by
272
* <code>date</code>. This method does not perform the
273
* normalization with the specified <code>CalendarDate</code>. The
274
* <code>CalendarDate</code> must be normalized to get a correct
275
* value.
276
*/
277
public abstract int getYearLength(CalendarDate date);
278
279
/**
280
* Returns the number of months of the specified year. This method
281
* does not perform the normalization with the specified
282
* <code>CalendarDate</code>. The <code>CalendarDate</code> must
283
* be normalized to get a correct value.
284
*/
285
public abstract int getYearLengthInMonths(CalendarDate date);
286
287
/**
288
* Returns the length in days of the month specified by the calendar
289
* date. This method does not perform the normalization with the
290
* specified calendar date. The <code>CalendarDate</code> must
291
* be normalized to get a correct value.
292
*
293
* @param date the date from which the month value is obtained
294
* @return the number of days in the month
295
* @exception IllegalArgumentException if the specified calendar date
296
* doesn't have a valid month value in this calendar system.
297
*/
298
public abstract int getMonthLength(CalendarDate date); // no setter
299
300
/**
301
* Returns the length in days of a week in this calendar
302
* system. If this calendar system has multiple radix weeks, this
303
* method returns only one of them.
304
*/
305
public abstract int getWeekLength();
306
307
/**
308
* Returns the <code>Era</code> designated by the era name that
309
* has to be known to this calendar system. If no Era is
310
* applicable to this calendar system, null is returned.
311
*
312
* @param eraName the name of the era
313
* @return the <code>Era</code> designated by
314
* <code>eraName</code>, or <code>null</code> if no Era is
315
* applicable to this calendar system or the specified era name is
316
* not known to this calendar system.
317
*/
318
public abstract Era getEra(String eraName);
319
320
/**
321
* Returns valid <code>Era</code>s of this calendar system. The
322
* return value is sorted in the descendant order. (i.e., the first
323
* element of the returned array is the oldest era.) If no era is
324
* applicable to this calendar system, <code>null</code> is returned.
325
*
326
* @return an array of valid <code>Era</code>s, or
327
* <code>null</code> if no era is applicable to this calendar
328
* system.
329
*/
330
public abstract Era[] getEras();
331
332
/**
333
* @throws IllegalArgumentException if the specified era name is
334
* unknown to this calendar system.
335
* @see Era
336
*/
337
public abstract void setEra(CalendarDate date, String eraName);
338
339
/**
340
* Returns a <code>CalendarDate</code> of the n-th day of week
341
* which is on, after or before the specified date. For example, the
342
* first Sunday in April 2002 (Gregorian) can be obtained as
343
* below:
344
*
345
* <pre><code>
346
* Gregorian cal = CalendarSystem.getGregorianCalendar();
347
* CalendarDate date = cal.newCalendarDate();
348
* date.setDate(2004, cal.APRIL, 1);
349
* CalendarDate firstSun = cal.getNthDayOfWeek(1, cal.SUNDAY, date);
350
* // firstSun represents April 4, 2004.
351
* </code></pre>
352
*
353
* This method returns a new <code>CalendarDate</code> instance
354
* and doesn't modify the original date.
355
*
356
* @param nth specifies the n-th one. A positive number specifies
357
* <em>on or after</em> the <code>date</code>. A non-positive number
358
* specifies <em>on or before</em> the <code>date</code>.
359
* @param dayOfWeek the day of week
360
* @param date the date
361
* @return the date of the nth <code>dayOfWeek</code> after
362
* or before the specified <code>CalendarDate</code>
363
*/
364
public abstract CalendarDate getNthDayOfWeek(int nth, int dayOfWeek,
365
CalendarDate date);
366
367
public abstract CalendarDate setTimeOfDay(CalendarDate date, int timeOfDay);
368
369
/**
370
* Checks whether the calendar fields specified by <code>date</code>
371
* represents a valid date and time in this calendar system. If the
372
* given date is valid, <code>date</code> is marked as <em>normalized</em>.
373
*
374
* @param date the <code>CalendarDate</code> to be validated
375
* @return <code>true</code> if all the calendar fields are consistent,
376
* otherwise, <code>false</code> is returned.
377
* @exception NullPointerException if the specified
378
* <code>date</code> is <code>null</code>
379
*/
380
public abstract boolean validate(CalendarDate date);
381
382
/**
383
* Normalizes calendar fields in the specified
384
* <code>date</code>. Also all {@link CalendarDate#FIELD_UNDEFINED
385
* undefined} fields are set to correct values. The actual
386
* normalization process is calendar system dependent.
387
*
388
* @param date the calendar date to be validated
389
* @return <code>true</code> if all fields have been normalized;
390
* <code>false</code> otherwise.
391
* @exception NullPointerException if the specified
392
* <code>date</code> is <code>null</code>
393
*/
394
public abstract boolean normalize(CalendarDate date);
395
}
396
397