1. /*
  2. * @(#)Calendar.java 1.81 04/07/26
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. /*
  8. * (C) Copyright Taligent, Inc. 1996-1998 - All Rights Reserved
  9. * (C) Copyright IBM Corp. 1996-1998 - All Rights Reserved
  10. *
  11. * The original version of this source code and documentation is copyrighted
  12. * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
  13. * materials are provided under terms of a License Agreement between Taligent
  14. * and Sun. This technology is protected by multiple US and International
  15. * patents. This notice and attribution to Taligent may not be removed.
  16. * Taligent is a registered trademark of Taligent, Inc.
  17. *
  18. */
  19. package java.util;
  20. import java.io.IOException;
  21. import java.io.ObjectInputStream;
  22. import java.io.ObjectOutputStream;
  23. import java.io.Serializable;
  24. import java.security.AccessController;
  25. import java.security.PrivilegedExceptionAction;
  26. import java.text.DateFormat;
  27. import sun.text.resources.LocaleData;
  28. import sun.util.BuddhistCalendar;
  29. import sun.util.calendar.ZoneInfo;
  30. /**
  31. * The <code>Calendar</code> class is an abstract class that provides methods
  32. * for converting between a specific instant in time and a set of {@link
  33. * #fields calendar fields} such as <code>YEAR</code>, <code>MONTH</code>,
  34. * <code>DAY_OF_MONTH</code>, <code>HOUR</code>, and so on, and for
  35. * manipulating the calendar fields, such as getting the date of the next
  36. * week. An instant in time can be represented by a millisecond value that is
  37. * an offset from the <a name="Epoch"><em>Epoch</em></a>, January 1, 1970
  38. * 00:00:00.000 GMT (Gregorian).
  39. *
  40. * <p>The class also provides additional fields and methods for
  41. * implementing a concrete calendar system outside the package. Those
  42. * fields and methods are defined as <code>protected</code>.
  43. *
  44. * <p>
  45. * Like other locale-sensitive classes, <code>Calendar</code> provides a
  46. * class method, <code>getInstance</code>, for getting a generally useful
  47. * object of this type. <code>Calendar</code>'s <code>getInstance</code> method
  48. * returns a <code>Calendar</code> object whose
  49. * calendar fields have been initialized with the current date and time:
  50. * <blockquote>
  51. * <pre>
  52. * Calendar rightNow = Calendar.getInstance();
  53. * </pre>
  54. * </blockquote>
  55. *
  56. * <p>A <code>Calendar</code> object can produce all the calendar field values
  57. * needed to implement the date-time formatting for a particular language and
  58. * calendar style (for example, Japanese-Gregorian, Japanese-Traditional).
  59. * <code>Calendar</code> defines the range of values returned by
  60. * certain calendar fields, as well as their meaning. For example,
  61. * the first month of the calendar system has value <code>MONTH ==
  62. * JANUARY</code> for all calendars. Other values are defined by the
  63. * concrete subclass, such as <code>ERA</code>. See individual field
  64. * documentation and subclass documentation for details.
  65. *
  66. * <h4>Getting and Setting Calendar Field Values</h4>
  67. *
  68. * <p>The calendar field values can be set by calling the <code>set</code>
  69. * methods. Any field values set in a <code>Calendar</code> will not be
  70. * interpreted until it needs to calculate its time value (milliseconds from
  71. * the Epoch) or values of the calendar fields. Calling the
  72. * <code>get</code>, <code>getTimeInMillis</code>, <code>getTime</code>,
  73. * <code>add</code> and <code>roll</code> involves such calculation.
  74. *
  75. * <h4>Leniency</h4>
  76. *
  77. * <p><code>Calendar</code> has two modes for interpreting the calendar
  78. * fields, <em>lenient</em> and <em>non-lenient</em>. When a
  79. * <code>Calendar</code> is in lenient mode, it accepts a wider range of
  80. * calendar field values than it produces. When a <code>Calendar</code>
  81. * recomputes calendar field values for return by <code>get()</code>, all of
  82. * the calendar fields are normalized. For example, a lenient
  83. * <code>GregorianCalendar</code> interprets <code>MONTH == JANUARY</code>,
  84. * <code>DAY_OF_MONTH == 32</code> as February 1.
  85. * <p>When a <code>Calendar</code> is in non-lenient mode, it throws an
  86. * exception if there is any inconsistency in its calendar fields. For
  87. * example, a <code>GregorianCalendar</code> always produces
  88. * <code>DAY_OF_MONTH</code> values between 1 and the length of the month. A
  89. * non-lenient <code>GregorianCalendar</code> throws an exception upon
  90. * calculating its time or calendar field values if any out-of-range field
  91. * value has been set.
  92. *
  93. * <h4>First Week</h4>
  94. *
  95. * <code>Calendar</code> defines a locale-specific seven day week using two
  96. * parameters: the first day of the week and the minimal days in first week
  97. * (from 1 to 7). These numbers are taken from the locale resource data when a
  98. * <code>Calendar</code> is constructed. They may also be specified explicitly
  99. * through the methods for setting their values.
  100. *
  101. * <p>When setting or getting the <code>WEEK_OF_MONTH</code> or
  102. * <code>WEEK_OF_YEAR</code> fields, <code>Calendar</code> must determine the
  103. * first week of the month or year as a reference point. The first week of a
  104. * month or year is defined as the earliest seven day period beginning on
  105. * <code>getFirstDayOfWeek()</code> and containing at least
  106. * <code>getMinimalDaysInFirstWeek()</code> days of that month or year. Weeks
  107. * numbered ..., -1, 0 precede the first week; weeks numbered 2, 3,... follow
  108. * it. Note that the normalized numbering returned by <code>get()</code> may be
  109. * different. For example, a specific <code>Calendar</code> subclass may
  110. * designate the week before week 1 of a year as week <code><i>n</i></code> of
  111. * the previous year.
  112. *
  113. * <h4>Calendar Fields Resolution</h4>
  114. *
  115. * When computing a date and time from the calendar fields, there
  116. * may be insufficient information for the computation (such as only
  117. * year and month with no day of month), or there may be inconsistent
  118. * information (such as Tuesday, July 15, 1996 (Gregorian) -- July 15,
  119. * 1996 is actually a Monday). <code>Calendar</code> will resolve
  120. * calendar field values to determine the date and time in the
  121. * following way.
  122. *
  123. * <p>If there is any conflict in calendar field values,
  124. * <code>Calendar</code> gives priorities to calendar fields that have been set
  125. * more recently. The following are the default combinations of the
  126. * calendar fields. The most recent combination, as determined by the
  127. * most recently set single field, will be used.
  128. *
  129. * <p><a name="date_resolution">For the date fields</a>:
  130. * <blockquote>
  131. * <pre>
  132. * YEAR + MONTH + DAY_OF_MONTH
  133. * YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
  134. * YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
  135. * YEAR + DAY_OF_YEAR
  136. * YEAR + DAY_OF_WEEK + WEEK_OF_YEAR
  137. * </pre></blockquote>
  138. *
  139. * <a name="time_resolution">For the time of day fields</a>:
  140. * <blockquote>
  141. * <pre>
  142. * HOUR_OF_DAY
  143. * AM_PM + HOUR
  144. * </pre></blockquote>
  145. *
  146. * <p>If there are any calendar fields whose values haven't been set in the selected
  147. * field combination, <code>Calendar</code> uses their default values. The default
  148. * value of each field may vary by concrete calendar systems. For example, in
  149. * <code>GregorianCalendar</code>, the default of a field is the same as that
  150. * of the start of the Epoch: i.e., <code>YEAR = 1970</code>, <code>MONTH =
  151. * JANUARY</code>, <code>DAY_OF_MONTH = 1</code>, etc.
  152. *
  153. * <p>
  154. * <strong>Note:</strong> There are certain possible ambiguities in
  155. * interpretation of certain singular times, which are resolved in the
  156. * following ways:
  157. * <ol>
  158. * <li> 23:59 is the last minute of the day and 00:00 is the first
  159. * minute of the next day. Thus, 23:59 on Dec 31, 1999 < 00:00 on
  160. * Jan 1, 2000 < 00:01 on Jan 1, 2000.
  161. *
  162. * <li> Although historically not precise, midnight also belongs to "am",
  163. * and noon belongs to "pm", so on the same day,
  164. * 12:00 am (midnight) < 12:01 am, and 12:00 pm (noon) < 12:01 pm
  165. * </ol>
  166. *
  167. * <p>
  168. * The date or time format strings are not part of the definition of a
  169. * calendar, as those must be modifiable or overridable by the user at
  170. * runtime. Use {@link DateFormat}
  171. * to format dates.
  172. *
  173. * <h4>Field Manipulation</h4>
  174. *
  175. * The calendar fields can be changed using three methods:
  176. * <code>set()</code>, <code>add()</code>, and <code>roll()</code>.</p>
  177. *
  178. * <p><strong><code>set(f, value)</code></strong> changes calendar field
  179. * <code>f</code> to <code>value</code>. In addition, it sets an
  180. * internal member variable to indicate that calendar field <code>f</code> has
  181. * been changed. Although calendar field <code>f</code> is changed immediately,
  182. * the calendar's time value in milliseconds is not recomputed until the next call to
  183. * <code>get()</code>, <code>getTime()</code>, <code>getTimeInMillis()</code>,
  184. * <code>add()</code>, or <code>roll()</code> is made. Thus, multiple calls to
  185. * <code>set()</code> do not trigger multiple, unnecessary
  186. * computations. As a result of changing a calendar field using
  187. * <code>set()</code>, other calendar fields may also change, depending on the
  188. * calendar field, the calendar field value, and the calendar system. In addition,
  189. * <code>get(f)</code> will not necessarily return <code>value</code> set by
  190. * the call to the <code>set</code> method
  191. * after the calendar fields have been recomputed. The specifics are determined by
  192. * the concrete calendar class.</p>
  193. *
  194. * <p><em>Example</em>: Consider a <code>GregorianCalendar</code>
  195. * originally set to August 31, 1999. Calling <code>set(Calendar.MONTH,
  196. * Calendar.SEPTEMBER)</code> sets the date to September 31,
  197. * 1999. This is a temporary internal representation that resolves to
  198. * October 1, 1999 if <code>getTime()</code>is then called. However, a
  199. * call to <code>set(Calendar.DAY_OF_MONTH, 30)</code> before the call to
  200. * <code>getTime()</code> sets the date to September 30, 1999, since
  201. * no recomputation occurs after <code>set()</code> itself.</p>
  202. *
  203. * <p><strong><code>add(f, delta)</code></strong> adds <code>delta</code>
  204. * to field <code>f</code>. This is equivalent to calling <code>set(f,
  205. * get(f) + delta)</code> with two adjustments:</p>
  206. *
  207. * <blockquote>
  208. * <p><strong>Add rule 1</strong>. The value of field <code>f</code>
  209. * after the call minus the value of field <code>f</code> before the
  210. * call is <code>delta</code>, modulo any overflow that has occurred in
  211. * field <code>f</code>. Overflow occurs when a field value exceeds its
  212. * range and, as a result, the next larger field is incremented or
  213. * decremented and the field value is adjusted back into its range.</p>
  214. *
  215. * <p><strong>Add rule 2</strong>. If a smaller field is expected to be
  216. * invariant, but it is impossible for it to be equal to its
  217. * prior value because of changes in its minimum or maximum after field
  218. * <code>f</code> is changed or other constraints, such as time zone
  219. * offset changes, then its value is adjusted to be as close
  220. * as possible to its expected value. A smaller field represents a
  221. * smaller unit of time. <code>HOUR</code> is a smaller field than
  222. * <code>DAY_OF_MONTH</code>. No adjustment is made to smaller fields
  223. * that are not expected to be invariant. The calendar system
  224. * determines what fields are expected to be invariant.</p>
  225. * </blockquote>
  226. *
  227. * <p>In addition, unlike <code>set()</code>, <code>add()</code> forces
  228. * an immediate recomputation of the calendar's milliseconds and all
  229. * fields.</p>
  230. *
  231. * <p><em>Example</em>: Consider a <code>GregorianCalendar</code>
  232. * originally set to August 31, 1999. Calling <code>add(Calendar.MONTH,
  233. * 13)</code> sets the calendar to September 30, 2000. <strong>Add rule
  234. * 1</strong> sets the <code>MONTH</code> field to September, since
  235. * adding 13 months to August gives September of the next year. Since
  236. * <code>DAY_OF_MONTH</code> cannot be 31 in September in a
  237. * <code>GregorianCalendar</code>, <strong>add rule 2</strong> sets the
  238. * <code>DAY_OF_MONTH</code> to 30, the closest possible value. Although
  239. * it is a smaller field, <code>DAY_OF_WEEK</code> is not adjusted by
  240. * rule 2, since it is expected to change when the month changes in a
  241. * <code>GregorianCalendar</code>.</p>
  242. *
  243. * <p><strong><code>roll(f, delta)</code></strong> adds
  244. * <code>delta</code> to field <code>f</code> without changing larger
  245. * fields. This is equivalent to calling <code>add(f, delta)</code> with
  246. * the following adjustment:</p>
  247. *
  248. * <blockquote>
  249. * <p><strong>Roll rule</strong>. Larger fields are unchanged after the
  250. * call. A larger field represents a larger unit of
  251. * time. <code>DAY_OF_MONTH</code> is a larger field than
  252. * <code>HOUR</code>.</p>
  253. * </blockquote>
  254. *
  255. * <p><em>Example</em>: See {@link java.util.GregorianCalendar#roll(int, int)}.
  256. *
  257. * <p><strong>Usage model</strong>. To motivate the behavior of
  258. * <code>add()</code> and <code>roll()</code>, consider a user interface
  259. * component with increment and decrement buttons for the month, day, and
  260. * year, and an underlying <code>GregorianCalendar</code>. If the
  261. * interface reads January 31, 1999 and the user presses the month
  262. * increment button, what should it read? If the underlying
  263. * implementation uses <code>set()</code>, it might read March 3, 1999. A
  264. * better result would be February 28, 1999. Furthermore, if the user
  265. * presses the month increment button again, it should read March 31,
  266. * 1999, not March 28, 1999. By saving the original date and using either
  267. * <code>add()</code> or <code>roll()</code>, depending on whether larger
  268. * fields should be affected, the user interface can behave as most users
  269. * will intuitively expect.</p>
  270. *
  271. * @see java.lang.System#currentTimeMillis()
  272. * @see Date
  273. * @see GregorianCalendar
  274. * @see TimeZone
  275. * @see java.text.DateFormat
  276. * @version 1.81, 07/26/04
  277. * @author Mark Davis, David Goldsmith, Chen-Lieh Huang, Alan Liu
  278. * @since JDK1.1
  279. */
  280. public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar> {
  281. // Data flow in Calendar
  282. // ---------------------
  283. // The current time is represented in two ways by Calendar: as UTC
  284. // milliseconds from the epoch (1 January 1970 0:00 UTC), and as local
  285. // fields such as MONTH, HOUR, AM_PM, etc. It is possible to compute the
  286. // millis from the fields, and vice versa. The data needed to do this
  287. // conversion is encapsulated by a TimeZone object owned by the Calendar.
  288. // The data provided by the TimeZone object may also be overridden if the
  289. // user sets the ZONE_OFFSET and/or DST_OFFSET fields directly. The class
  290. // keeps track of what information was most recently set by the caller, and
  291. // uses that to compute any other information as needed.
  292. // If the user sets the fields using set(), the data flow is as follows.
  293. // This is implemented by the Calendar subclass's computeTime() method.
  294. // During this process, certain fields may be ignored. The disambiguation
  295. // algorithm for resolving which fields to pay attention to is described
  296. // in the class documentation.
  297. // local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)
  298. // |
  299. // | Using Calendar-specific algorithm
  300. // V
  301. // local standard millis
  302. // |
  303. // | Using TimeZone or user-set ZONE_OFFSET / DST_OFFSET
  304. // V
  305. // UTC millis (in time data member)
  306. // If the user sets the UTC millis using setTime() or setTimeInMillis(),
  307. // the data flow is as follows. This is implemented by the Calendar
  308. // subclass's computeFields() method.
  309. // UTC millis (in time data member)
  310. // |
  311. // | Using TimeZone getOffset()
  312. // V
  313. // local standard millis
  314. // |
  315. // | Using Calendar-specific algorithm
  316. // V
  317. // local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)
  318. // In general, a round trip from fields, through local and UTC millis, and
  319. // back out to fields is made when necessary. This is implemented by the
  320. // complete() method. Resolving a partial set of fields into a UTC millis
  321. // value allows all remaining fields to be generated from that value. If
  322. // the Calendar is lenient, the fields are also renormalized to standard
  323. // ranges when they are regenerated.
  324. /**
  325. * Field number for <code>get</code> and <code>set</code> indicating the
  326. * era, e.g., AD or BC in the Julian calendar. This is a calendar-specific
  327. * value; see subclass documentation.
  328. *
  329. * @see GregorianCalendar#AD
  330. * @see GregorianCalendar#BC
  331. */
  332. public final static int ERA = 0;
  333. /**
  334. * Field number for <code>get</code> and <code>set</code> indicating the
  335. * year. This is a calendar-specific value; see subclass documentation.
  336. */
  337. public final static int YEAR = 1;
  338. /**
  339. * Field number for <code>get</code> and <code>set</code> indicating the
  340. * month. This is a calendar-specific value. The first month of the year is
  341. * <code>JANUARY</code> which is 0; the last depends on the number of months in a year.
  342. *
  343. * @see #JANUARY
  344. * @see #FEBRUARY
  345. * @see #MARCH
  346. * @see #APRIL
  347. * @see #MAY
  348. * @see #JUNE
  349. * @see #JULY
  350. * @see #AUGUST
  351. * @see #SEPTEMBER
  352. * @see #OCTOBER
  353. * @see #NOVEMBER
  354. * @see #DECEMBER
  355. * @see #UNDECIMBER
  356. */
  357. public final static int MONTH = 2;
  358. /**
  359. * Field number for <code>get</code> and <code>set</code> indicating the
  360. * week number within the current year. The first week of the year, as
  361. * defined by <code>getFirstDayOfWeek()</code> and
  362. * <code>getMinimalDaysInFirstWeek()</code>, has value 1. Subclasses define
  363. * the value of <code>WEEK_OF_YEAR</code> for days before the first week of
  364. * the year.
  365. *
  366. * @see #getFirstDayOfWeek
  367. * @see #getMinimalDaysInFirstWeek
  368. */
  369. public final static int WEEK_OF_YEAR = 3;
  370. /**
  371. * Field number for <code>get</code> and <code>set</code> indicating the
  372. * week number within the current month. The first week of the month, as
  373. * defined by <code>getFirstDayOfWeek()</code> and
  374. * <code>getMinimalDaysInFirstWeek()</code>, has value 1. Subclasses define
  375. * the value of <code>WEEK_OF_MONTH</code> for days before the first week of
  376. * the month.
  377. *
  378. * @see #getFirstDayOfWeek
  379. * @see #getMinimalDaysInFirstWeek
  380. */
  381. public final static int WEEK_OF_MONTH = 4;
  382. /**
  383. * Field number for <code>get</code> and <code>set</code> indicating the
  384. * day of the month. This is a synonym for <code>DAY_OF_MONTH</code>.
  385. * The first day of the month has value 1.
  386. *
  387. * @see #DAY_OF_MONTH
  388. */
  389. public final static int DATE = 5;
  390. /**
  391. * Field number for <code>get</code> and <code>set</code> indicating the
  392. * day of the month. This is a synonym for <code>DATE</code>.
  393. * The first day of the month has value 1.
  394. *
  395. * @see #DATE
  396. */
  397. public final static int DAY_OF_MONTH = 5;
  398. /**
  399. * Field number for <code>get</code> and <code>set</code> indicating the day
  400. * number within the current year. The first day of the year has value 1.
  401. */
  402. public final static int DAY_OF_YEAR = 6;
  403. /**
  404. * Field number for <code>get</code> and <code>set</code> indicating the day
  405. * of the week. This field takes values <code>SUNDAY</code>,
  406. * <code>MONDAY</code>, <code>TUESDAY</code>, <code>WEDNESDAY</code>,
  407. * <code>THURSDAY</code>, <code>FRIDAY</code>, and <code>SATURDAY</code>.
  408. *
  409. * @see #SUNDAY
  410. * @see #MONDAY
  411. * @see #TUESDAY
  412. * @see #WEDNESDAY
  413. * @see #THURSDAY
  414. * @see #FRIDAY
  415. * @see #SATURDAY
  416. */
  417. public final static int DAY_OF_WEEK = 7;
  418. /**
  419. * Field number for <code>get</code> and <code>set</code> indicating the
  420. * ordinal number of the day of the week within the current month. Together
  421. * with the <code>DAY_OF_WEEK</code> field, this uniquely specifies a day
  422. * within a month. Unlike <code>WEEK_OF_MONTH</code> and
  423. * <code>WEEK_OF_YEAR</code>, this field's value does <em>not</em> depend on
  424. * <code>getFirstDayOfWeek()</code> or
  425. * <code>getMinimalDaysInFirstWeek()</code>. <code>DAY_OF_MONTH 1</code>
  426. * through <code>7</code> always correspond to <code>DAY_OF_WEEK_IN_MONTH
  427. * 1</code> <code>8</code> through <code>14</code> correspond to
  428. * <code>DAY_OF_WEEK_IN_MONTH 2</code>, and so on.
  429. * <code>DAY_OF_WEEK_IN_MONTH 0</code> indicates the week before
  430. * <code>DAY_OF_WEEK_IN_MONTH 1</code>. Negative values count back from the
  431. * end of the month, so the last Sunday of a month is specified as
  432. * <code>DAY_OF_WEEK = SUNDAY, DAY_OF_WEEK_IN_MONTH = -1</code>. Because
  433. * negative values count backward they will usually be aligned differently
  434. * within the month than positive values. For example, if a month has 31
  435. * days, <code>DAY_OF_WEEK_IN_MONTH -1</code> will overlap
  436. * <code>DAY_OF_WEEK_IN_MONTH 5</code> and the end of <code>4</code>.
  437. *
  438. * @see #DAY_OF_WEEK
  439. * @see #WEEK_OF_MONTH
  440. */
  441. public final static int DAY_OF_WEEK_IN_MONTH = 8;
  442. /**
  443. * Field number for <code>get</code> and <code>set</code> indicating
  444. * whether the <code>HOUR</code> is before or after noon.
  445. * E.g., at 10:04:15.250 PM the <code>AM_PM</code> is <code>PM</code>.
  446. *
  447. * @see #AM
  448. * @see #PM
  449. * @see #HOUR
  450. */
  451. public final static int AM_PM = 9;
  452. /**
  453. * Field number for <code>get</code> and <code>set</code> indicating the
  454. * hour of the morning or afternoon. <code>HOUR</code> is used for the
  455. * 12-hour clock (0 - 11). Noon and midnight are represented by 0, not by 12.
  456. * E.g., at 10:04:15.250 PM the <code>HOUR</code> is 10.
  457. *
  458. * @see #AM_PM
  459. * @see #HOUR_OF_DAY
  460. */
  461. public final static int HOUR = 10;
  462. /**
  463. * Field number for <code>get</code> and <code>set</code> indicating the
  464. * hour of the day. <code>HOUR_OF_DAY</code> is used for the 24-hour clock.
  465. * E.g., at 10:04:15.250 PM the <code>HOUR_OF_DAY</code> is 22.
  466. *
  467. * @see #HOUR
  468. */
  469. public final static int HOUR_OF_DAY = 11;
  470. /**
  471. * Field number for <code>get</code> and <code>set</code> indicating the
  472. * minute within the hour.
  473. * E.g., at 10:04:15.250 PM the <code>MINUTE</code> is 4.
  474. */
  475. public final static int MINUTE = 12;
  476. /**
  477. * Field number for <code>get</code> and <code>set</code> indicating the
  478. * second within the minute.
  479. * E.g., at 10:04:15.250 PM the <code>SECOND</code> is 15.
  480. */
  481. public final static int SECOND = 13;
  482. /**
  483. * Field number for <code>get</code> and <code>set</code> indicating the
  484. * millisecond within the second.
  485. * E.g., at 10:04:15.250 PM the <code>MILLISECOND</code> is 250.
  486. */
  487. public final static int MILLISECOND = 14;
  488. /**
  489. * Field number for <code>get</code> and <code>set</code>
  490. * indicating the raw offset from GMT in milliseconds.
  491. * <p>
  492. * This field reflects the correct GMT offset value of the time
  493. * zone of this <code>Calendar</code> if the
  494. * <code>TimeZone</code> implementation subclass supports
  495. * historical GMT offset changes.
  496. */
  497. public final static int ZONE_OFFSET = 15;
  498. /**
  499. * Field number for <code>get</code> and <code>set</code> indicating the
  500. * daylight savings offset in milliseconds.
  501. * <p>
  502. * This field reflects the correct daylight saving offset value of
  503. * the time zone of this <code>Calendar</code> if the
  504. * <code>TimeZone</code> implementation subclass supports
  505. * historical Daylight Saving Time schedule changes.
  506. */
  507. public final static int DST_OFFSET = 16;
  508. /**
  509. * The number of distinct fields recognized by <code>get</code> and <code>set</code>.
  510. * Field numbers range from <code>0..FIELD_COUNT-1</code>.
  511. */
  512. public final static int FIELD_COUNT = 17;
  513. /**
  514. * Value of the {@link #DAY_OF_WEEK} field indicating
  515. * Sunday.
  516. */
  517. public final static int SUNDAY = 1;
  518. /**
  519. * Value of the {@link #DAY_OF_WEEK} field indicating
  520. * Monday.
  521. */
  522. public final static int MONDAY = 2;
  523. /**
  524. * Value of the {@link #DAY_OF_WEEK} field indicating
  525. * Tuesday.
  526. */
  527. public final static int TUESDAY = 3;
  528. /**
  529. * Value of the {@link #DAY_OF_WEEK} field indicating
  530. * Wednesday.
  531. */
  532. public final static int WEDNESDAY = 4;
  533. /**
  534. * Value of the {@link #DAY_OF_WEEK} field indicating
  535. * Thursday.
  536. */
  537. public final static int THURSDAY = 5;
  538. /**
  539. * Value of the {@link #DAY_OF_WEEK} field indicating
  540. * Friday.
  541. */
  542. public final static int FRIDAY = 6;
  543. /**
  544. * Value of the {@link #DAY_OF_WEEK} field indicating
  545. * Saturday.
  546. */
  547. public final static int SATURDAY = 7;
  548. /**
  549. * Value of the {@link #MONTH} field indicating the
  550. * first month of the year.
  551. */
  552. public final static int JANUARY = 0;
  553. /**
  554. * Value of the {@link #MONTH} field indicating the
  555. * second month of the year.
  556. */
  557. public final static int FEBRUARY = 1;
  558. /**
  559. * Value of the {@link #MONTH} field indicating the
  560. * third month of the year.
  561. */
  562. public final static int MARCH = 2;
  563. /**
  564. * Value of the {@link #MONTH} field indicating the
  565. * fourth month of the year.
  566. */
  567. public final static int APRIL = 3;
  568. /**
  569. * Value of the {@link #MONTH} field indicating the
  570. * fifth month of the year.
  571. */
  572. public final static int MAY = 4;
  573. /**
  574. * Value of the {@link #MONTH} field indicating the
  575. * sixth month of the year.
  576. */
  577. public final static int JUNE = 5;
  578. /**
  579. * Value of the {@link #MONTH} field indicating the
  580. * seventh month of the year.
  581. */
  582. public final static int JULY = 6;
  583. /**
  584. * Value of the {@link #MONTH} field indicating the
  585. * eighth month of the year.
  586. */
  587. public final static int AUGUST = 7;
  588. /**
  589. * Value of the {@link #MONTH} field indicating the
  590. * ninth month of the year.
  591. */
  592. public final static int SEPTEMBER = 8;
  593. /**
  594. * Value of the {@link #MONTH} field indicating the
  595. * tenth month of the year.
  596. */
  597. public final static int OCTOBER = 9;
  598. /**
  599. * Value of the {@link #MONTH} field indicating the
  600. * eleventh month of the year.
  601. */
  602. public final static int NOVEMBER = 10;
  603. /**
  604. * Value of the {@link #MONTH} field indicating the
  605. * twelfth month of the year.
  606. */
  607. public final static int DECEMBER = 11;
  608. /**
  609. * Value of the {@link #MONTH} field indicating the
  610. * thirteenth month of the year. Although <code>GregorianCalendar</code>
  611. * does not use this value, lunar calendars do.
  612. */
  613. public final static int UNDECIMBER = 12;
  614. /**
  615. * Value of the {@link #AM_PM} field indicating the
  616. * period of the day from midnight to just before noon.
  617. */
  618. public final static int AM = 0;
  619. /**
  620. * Value of the {@link #AM_PM} field indicating the
  621. * period of the day from noon to just before midnight.
  622. */
  623. public final static int PM = 1;
  624. // Internal notes:
  625. // Calendar contains two kinds of time representations: current "time" in
  626. // milliseconds, and a set of calendar "fields" representing the current time.
  627. // The two representations are usually in sync, but can get out of sync
  628. // as follows.
  629. // 1. Initially, no fields are set, and the time is invalid.
  630. // 2. If the time is set, all fields are computed and in sync.
  631. // 3. If a single field is set, the time is invalid.
  632. // Recomputation of the time and fields happens when the object needs
  633. // to return a result to the user, or use a result for a computation.
  634. /**
  635. * The calendar field values for the currently set time for this calendar.
  636. * This is an array of <code>FIELD_COUNT</code> integers, with index values
  637. * <code>ERA</code> through <code>DST_OFFSET</code>.
  638. * @serial
  639. */
  640. protected int fields[];
  641. /**
  642. * The flags which tell if a specified calendar field for the calendar is set.
  643. * A new object has no fields set. After the first call to a method
  644. * which generates the fields, they all remain set after that.
  645. * This is an array of <code>FIELD_COUNT</code> booleans, with index values
  646. * <code>ERA</code> through <code>DST_OFFSET</code>.
  647. * @serial
  648. */
  649. protected boolean isSet[];
  650. /**
  651. * Pseudo-time-stamps which specify when each field was set. There
  652. * are two special values, UNSET and COMPUTED. Values from
  653. * MINIMUM_USER_SET to Integer.MAX_VALUE are legal user set values.
  654. */
  655. transient private int stamp[];
  656. /**
  657. * The currently set time for this calendar, expressed in milliseconds after
  658. * January 1, 1970, 0:00:00 GMT.
  659. * @see #isTimeSet
  660. * @serial
  661. */
  662. protected long time;
  663. /**
  664. * True if then the value of <code>time</code> is valid.
  665. * The time is made invalid by a change to an item of <code>field[]</code>.
  666. * @see #time
  667. * @serial
  668. */
  669. protected boolean isTimeSet;
  670. /**
  671. * True if <code>fields[]</code> are in sync with the currently set time.
  672. * If false, then the next attempt to get the value of a field will
  673. * force a recomputation of all fields from the current value of
  674. * <code>time</code>.
  675. * @serial
  676. */
  677. protected boolean areFieldsSet;
  678. /**
  679. * True if all fields have been set.
  680. * @serial
  681. */
  682. transient boolean areAllFieldsSet;
  683. /**
  684. * <code>True</code> if this calendar allows out-of-range field values during computation
  685. * of <code>time</code> from <code>fields[]</code>.
  686. * @see #setLenient
  687. * @see #isLenient
  688. * @serial
  689. */
  690. private boolean lenient = true;
  691. /**
  692. * The <code>TimeZone</code> used by this calendar. <code>Calendar</code>
  693. * uses the time zone data to translate between locale and GMT time.
  694. * @serial
  695. */
  696. private TimeZone zone;
  697. /**
  698. * <code>True</code> if zone references to a shared TimeZone object.
  699. */
  700. transient private boolean sharedZone = false;
  701. /**
  702. * The first day of the week, with possible values <code>SUNDAY</code>,
  703. * <code>MONDAY</code>, etc. This is a locale-dependent value.
  704. * @serial
  705. */
  706. private int firstDayOfWeek;
  707. /**
  708. * The number of days required for the first week in a month or year,
  709. * with possible values from 1 to 7. This is a locale-dependent value.
  710. * @serial
  711. */
  712. private int minimalDaysInFirstWeek;
  713. /**
  714. * Cache to hold the firstDayOfWeek and minimalDaysInFirstWeek
  715. * of a Locale.
  716. */
  717. private static Hashtable<Locale, int[]> cachedLocaleData = new Hashtable<Locale, int[]>(3);
  718. // Special values of stamp[]
  719. /**
  720. * The corresponding fields[] has no value.
  721. */
  722. private static final int UNSET = 0;
  723. /**
  724. * The value of the corresponding fields[] has been calculated internally.
  725. */
  726. private static final int COMPUTED = 1;
  727. /**
  728. * The value of the corresponding fields[] has been set externally. Stamp
  729. * values which are greater than 1 represents the (pseudo) time when the
  730. * corresponding fields[] value was set.
  731. */
  732. private static final int MINIMUM_USER_STAMP = 2;
  733. /**
  734. * The mask value that represents all of the fields.
  735. */
  736. static final int ALL_FIELDS = (1 << FIELD_COUNT) - 1;
  737. /**
  738. * The next available value for <code>stamp[]</code>, an internal array.
  739. * This actually should not be written out to the stream, and will probably
  740. * be removed from the stream in the near future. In the meantime,
  741. * a value of <code>MINIMUM_USER_STAMP</code> should be used.
  742. * @serial
  743. */
  744. private int nextStamp = MINIMUM_USER_STAMP;
  745. // the internal serial version which says which version was written
  746. // - 0 (default) for version up to JDK 1.1.5
  747. // - 1 for version from JDK 1.1.6, which writes a correct 'time' value
  748. // as well as compatible values for other fields. This is a
  749. // transitional format.
  750. // - 2 (not implemented yet) a future version, in which fields[],
  751. // areFieldsSet, and isTimeSet become transient, and isSet[] is
  752. // removed. In JDK 1.1.6 we write a format compatible with version 2.
  753. static final int currentSerialVersion = 1;
  754. /**
  755. * The version of the serialized data on the stream. Possible values:
  756. * <dl>
  757. * <dt><b>0</b> or not present on stream</dt>
  758. * <dd>
  759. * JDK 1.1.5 or earlier.
  760. * </dd>
  761. * <dt><b>1</b></dt>
  762. * <dd>
  763. * JDK 1.1.6 or later. Writes a correct 'time' value
  764. * as well as compatible values for other fields. This is a
  765. * transitional format.
  766. * </dd>
  767. * </dl>
  768. * When streaming out this class, the most recent format
  769. * and the highest allowable <code>serialVersionOnStream</code>
  770. * is written.
  771. * @serial
  772. * @since JDK1.1.6
  773. */
  774. private int serialVersionOnStream = currentSerialVersion;
  775. // Proclaim serialization compatibility with JDK 1.1
  776. static final long serialVersionUID = -1807547505821590642L;
  777. // Mask values for calendar fields
  778. final static int ERA_MASK = (1 << ERA);
  779. final static int YEAR_MASK = (1 << YEAR);
  780. final static int MONTH_MASK = (1 << MONTH);
  781. final static int WEEK_OF_YEAR_MASK = (1 << WEEK_OF_YEAR);
  782. final static int WEEK_OF_MONTH_MASK = (1 << WEEK_OF_MONTH);
  783. final static int DAY_OF_MONTH_MASK = (1 << DAY_OF_MONTH);
  784. final static int DATE_MASK = DAY_OF_MONTH_MASK;
  785. final static int DAY_OF_YEAR_MASK = (1 << DAY_OF_YEAR);
  786. final static int DAY_OF_WEEK_MASK = (1 << DAY_OF_WEEK);
  787. final static int DAY_OF_WEEK_IN_MONTH_MASK = (1 << DAY_OF_WEEK_IN_MONTH);
  788. final static int AM_PM_MASK = (1 << AM_PM);
  789. final static int HOUR_MASK = (1 << HOUR);
  790. final static int HOUR_OF_DAY_MASK = (1 << HOUR_OF_DAY);
  791. final static int MINUTE_MASK = (1 << MINUTE);
  792. final static int SECOND_MASK = (1 << SECOND);
  793. final static int MILLISECOND_MASK = (1 << MILLISECOND);
  794. final static int ZONE_OFFSET_MASK = (1 << ZONE_OFFSET);
  795. final static int DST_OFFSET_MASK = (1 << DST_OFFSET);
  796. /**
  797. * Constructs a Calendar with the default time zone
  798. * and locale.
  799. * @see TimeZone#getDefault
  800. */
  801. protected Calendar()
  802. {
  803. this(TimeZone.getDefaultRef(), Locale.getDefault());
  804. sharedZone = true;
  805. }
  806. /**
  807. * Constructs a calendar with the specified time zone and locale.
  808. *
  809. * @param zone the time zone to use
  810. * @param aLocale the locale for the week data
  811. */
  812. protected Calendar(TimeZone zone, Locale aLocale)
  813. {
  814. fields = new int[FIELD_COUNT];
  815. isSet = new boolean[FIELD_COUNT];
  816. stamp = new int[FIELD_COUNT];
  817. this.zone = zone;
  818. setWeekCountData(aLocale);
  819. }
  820. /**
  821. * Gets a calendar using the default time zone and locale. The
  822. * <code>Calendar</code> returned is based on the current time
  823. * in the default time zone with the default locale.
  824. *
  825. * @return a Calendar.
  826. */
  827. public static Calendar getInstance()
  828. {
  829. Calendar cal = createCalendar(TimeZone.getDefaultRef(), Locale.getDefault());
  830. cal.sharedZone = true;
  831. return cal;
  832. }
  833. /**
  834. * Gets a calendar using the specified time zone and default locale.
  835. * The <code>Calendar</code> returned is based on the current time
  836. * in the given time zone with the default locale.
  837. *
  838. * @param zone the time zone to use
  839. * @return a Calendar.
  840. */
  841. public static Calendar getInstance(TimeZone zone)
  842. {
  843. return createCalendar(zone, Locale.getDefault());
  844. }
  845. /**
  846. * Gets a calendar using the default time zone and specified locale.
  847. * The <code>Calendar</code> returned is based on the current time
  848. * in the default time zone with the given locale.
  849. *
  850. * @param aLocale the locale for the week data
  851. * @return a Calendar.
  852. */
  853. public static Calendar getInstance(Locale aLocale)
  854. {
  855. Calendar cal = createCalendar(TimeZone.getDefaultRef(), aLocale);
  856. cal.sharedZone = true;
  857. return cal;
  858. }
  859. /**
  860. * Gets a calendar with the specified time zone and locale.
  861. * The <code>Calendar</code> returned is based on the current time
  862. * in the given time zone with the given locale.
  863. *
  864. * @param zone the time zone to use
  865. * @param aLocale the locale for the week data
  866. * @return a Calendar.
  867. */
  868. public static Calendar getInstance(TimeZone zone,
  869. Locale aLocale)
  870. {
  871. return createCalendar(zone, aLocale);
  872. }
  873. private static Calendar createCalendar(TimeZone zone,
  874. Locale aLocale)
  875. {
  876. // If the specified locale is a Thai locale, returns a BuddhistCalendar
  877. // instance.
  878. if ("th".equals(aLocale.getLanguage())
  879. && ("TH".equals(aLocale.getCountry()))) {
  880. return new sun.util.BuddhistCalendar(zone, aLocale);
  881. }
  882. // else create the default calendar
  883. return new GregorianCalendar(zone, aLocale);
  884. }
  885. /**
  886. * Returns an array of all locales for which the <code>getInstance</code>
  887. * methods of this class can return localized instances.
  888. * The array returned must contain at least a <code>Locale</code>
  889. * instance equal to {@link java.util.Locale#US Locale.US}.
  890. *
  891. * @return An array of locales for which localized
  892. * <code>Calendar</code> instances are available.
  893. */
  894. public static synchronized Locale[] getAvailableLocales()
  895. {
  896. return DateFormat.getAvailableLocales();
  897. }
  898. /**
  899. * Converts the current calendar field values in {@link #fields fields[]}
  900. * to the millisecond time value
  901. * {@link #time}.
  902. *
  903. * @see #complete()
  904. * @see #computeFields()
  905. */
  906. protected abstract void computeTime();
  907. /**
  908. * Converts the current millisecond time value {@link #time}
  909. * to calendar field values in {@link #fields fields[]}.
  910. * This allows you to sync up the calendar field values with
  911. * a new time that is set for the calendar. The time is <em>not</em>
  912. * recomputed first; to recompute the time, then the fields, call the
  913. * {@link #complete()} method.
  914. *
  915. * @see #computeTime()
  916. */
  917. protected abstract void computeFields();
  918. /**
  919. * Returns a <code>Date</code> object representing this
  920. * <code>Calendar</code>'s time value (millisecond offset from the <a
  921. * href="#Epoch">Epoch</a>").
  922. *
  923. * @return a <code>Date</code> representing the time value.
  924. * @see #setTime(Date)
  925. * @see #getTimeInMillis()
  926. */
  927. public final Date getTime() {
  928. return new Date(getTimeInMillis());
  929. }
  930. /**
  931. * Sets this Calendar's time with the given <code>Date</code>.
  932. * <p>
  933. * Note: Calling <code>setTime()</code> with
  934. * <code>Date(Long.MAX_VALUE)</code> or <code>Date(Long.MIN_VALUE)</code>
  935. * may yield incorrect field values from <code>get()</code>.
  936. *
  937. * @param date the given Date.
  938. * @see #getTime()
  939. * @see #setTimeInMillis(long)
  940. */
  941. public final void setTime(Date date) {
  942. setTimeInMillis(date.getTime());
  943. }
  944. /**
  945. * Returns this Calendar's time value in milliseconds.
  946. *
  947. * @return the current time as UTC milliseconds from the epoch.
  948. * @see #getTime()
  949. * @see #setTimeInMillis(long)
  950. */
  951. public long getTimeInMillis() {
  952. if (!isTimeSet) {
  953. updateTime();
  954. }
  955. return time;
  956. }
  957. /**
  958. * Sets this Calendar's current time from the given long value.
  959. *
  960. * @param millis the new time in UTC milliseconds from the epoch.
  961. * @see #setTime(Date)
  962. * @see #getTimeInMillis()
  963. */
  964. public void setTimeInMillis(long millis) {
  965. // If we don't need to recalculate the calendar field values,
  966. // do nothing.
  967. if (time == millis && isTimeSet && areFieldsSet && areAllFieldsSet
  968. && (zone instanceof ZoneInfo) && !((ZoneInfo)zone).isDirty()) {
  969. return;
  970. }
  971. time = millis;
  972. isTimeSet = true;
  973. areFieldsSet = false;
  974. computeFields();
  975. areAllFieldsSet = areFieldsSet = true;
  976. }
  977. /**
  978. * Returns the value of the given calendar field. In lenient mode,
  979. * all calendar fields are normalized. In non-lenient mode, all
  980. * calendar fields are validated and this method throws an
  981. * exception if any calendar fields have out-of-range values. The
  982. * normalization and validation are handled by the
  983. * {@link #complete()} method, which process is calendar
  984. * system dependent.
  985. *
  986. * @param field the given calendar field.
  987. * @return the value for the given calendar field.
  988. * @throws ArrayIndexOutOfBoundsException if the specified field is out of range
  989. * (<code>field < 0 || field >= FIELD_COUNT</code>).
  990. * @see #set(int,int)
  991. * @see #complete()
  992. */
  993. public int get(int field)
  994. {
  995. complete();
  996. return internalGet(field);
  997. }
  998. /**
  999. * Returns the value of the given calendar field. This method does
  1000. * not involve normalization or validation of the field value.
  1001. *
  1002. * @param field the given calendar field.
  1003. * @return the value for the given calendar field.
  1004. * @see #get(int)
  1005. */
  1006. protected final int internalGet(int field)
  1007. {
  1008. return fields[field];
  1009. }
  1010. /**
  1011. * Sets the value of the given calendar field. This method does
  1012. * not affect any setting state of the field in this
  1013. * <code>Calendar</code> instance.
  1014. *
  1015. * @throws IndexOutOfBoundsException if the specified field is out of range
  1016. * (<code>field < 0 || field >= FIELD_COUNT</code>).
  1017. * @see #areFieldsSet
  1018. * @see #isTimeSet
  1019. * @see #areAllFieldsSet
  1020. * @see #set(int,int)
  1021. */
  1022. final void internalSet(int field, int value)
  1023. {
  1024. fields[field] = value;
  1025. }
  1026. /**
  1027. * Sets the given calendar field to the given value. The value is not
  1028. * interpreted by this method regardless of the leniency mode.
  1029. *
  1030. * @param field the given calendar field.
  1031. * @param value the value to be set for the given calendar field.
  1032. * @throws ArrayIndexOutOfBoundsException if the specified field is out of range
  1033. * (<code>field < 0 || field >= FIELD_COUNT</code>).
  1034. * in non-lenient mode.
  1035. * @see #set(int,int,int)
  1036. * @see #set(int,int,int,int,int)
  1037. * @see #set(int,int,int,int,int,int)
  1038. * @see #get(int)
  1039. */
  1040. public void set(int field, int value)
  1041. {
  1042. if (isLenient() && areFieldsSet && !areAllFieldsSet) {
  1043. computeFields();
  1044. }
  1045. internalSet(field, value);
  1046. isTimeSet = false;
  1047. areFieldsSet = false;
  1048. isSet[field] = true;
  1049. stamp[field] = nextStamp++;
  1050. if (nextStamp == Integer.MAX_VALUE) {
  1051. adjustStamp();
  1052. }
  1053. }
  1054. /**
  1055. * Sets the values for the calendar fields <code>YEAR</code>,
  1056. * <code>MONTH</code>, and <code>DAY_OF_MONTH</code>.
  1057. * Previous values of other calendar fields are retained. If this is not desired,
  1058. * call {@link #clear()} first.
  1059. *
  1060. * @param year the value used to set the <code>YEAR</code> calendar field.
  1061. * @param month the value used to set the <code>MONTH</code> calendar field.
  1062. * Month value is 0-based. e.g., 0 for January.
  1063. * @param date the value used to set the <code>DAY_OF_MONTH</code> calendar field.
  1064. * @see #set(int,int)
  1065. * @see #set(int,int,int,int,int)
  1066. * @see #set(int,int,int,int,int,int)
  1067. */
  1068. public final void set(int year, int month, int date)
  1069. {
  1070. set(YEAR, year);
  1071. set(MONTH, month);
  1072. set(DATE, date);
  1073. }
  1074. /**
  1075. * Sets the values for the calendar fields <code>YEAR</code>,
  1076. * <code>MONTH</code>, <code>DAY_OF_MONTH</code>,
  1077. * <code>HOUR_OF_DAY</code>, and <code>MINUTE</code>.
  1078. * Previous values of other fields are retained. If this is not desired,
  1079. * call {@link #clear()} first.
  1080. *
  1081. * @param year the value used to set the <code>YEAR</code> calendar field.
  1082. * @param month the value used to set the <code>MONTH</code> calendar field.
  1083. * Month value is 0-based. e.g., 0 for January.
  1084. * @param date the value used to set the <code>DAY_OF_MONTH</code> calendar field.
  1085. * @param hourOfDay the value used to set the <code>HOUR_OF_DAY</code> calendar field.
  1086. * @param minute the value used to set the <code>MINUTE</code> calendar field.
  1087. * @see #set(int,int)
  1088. * @see #set(int,int,int)
  1089. * @see #set(int,int,int,int,int,int)
  1090. */
  1091. public final void set(int year, int month, int date, int hourOfDay, int minute)
  1092. {
  1093. set(YEAR, year);
  1094. set(MONTH, month);
  1095. set(DATE, date);
  1096. set(HOUR_OF_DAY, hourOfDay);
  1097. set(MINUTE, minute);
  1098. }
  1099. /**
  1100. * Sets the values for the fields <code>YEAR</code>, <code>MONTH</code>,
  1101. * <code>DAY_OF_MONTH</code>, <code>HOUR</code>, <code>MINUTE</code>, and
  1102. * <code>SECOND</code>.
  1103. * Previous values of other fields are retained. If this is not desired,
  1104. * call {@link #clear()} first.
  1105. *
  1106. * @param year the value used to set the <code>YEAR</code> calendar field.
  1107. * @param month the value used to set the <code>MONTH</code> calendar field.
  1108. * Month value is 0-based. e.g., 0 for January.
  1109. * @param date the value used to set the <code>DAY_OF_MONTH</code> calendar field.
  1110. * @param hourOfDay the value used to set the <code>HOUR_OF_DAY</code> calendar field.
  1111. * @param minute the value used to set the <code>MINUTE</code> calendar field.
  1112. * @param second the value used to set the <code>SECOND</code> calendar field.
  1113. * @see #set(int,int)
  1114. * @see #set(int,int,int)
  1115. * @see #set(int,int,int,int,int)
  1116. */
  1117. public final void set(int year, int month, int date, int hourOfDay, int minute,
  1118. int second)
  1119. {
  1120. set(YEAR, year);
  1121. set(MONTH, month);
  1122. set(DATE, date);
  1123. set(HOUR_OF_DAY, hourOfDay);
  1124. set(MINUTE, minute);
  1125. set(SECOND, second);
  1126. }
  1127. /**
  1128. * Sets all the calendar field values and the time value
  1129. * (millisecond offset from the <a href="#Epoch">Epoch</a>) of
  1130. * this <code>Calendar</code> undefined. This means that {@link
  1131. * #isSet(int) isSet()} will return <code>false</code> for all the
  1132. * calendar fields, and the date and time calculations will treat
  1133. * the fields as if they had never been set. A
  1134. * <code>Calendar</code> implementation class may use its specific
  1135. * default field values for date/time calculations. For example,
  1136. * <code>GregorianCalendar</code> uses 1970 if the
  1137. * <code>YEAR</code> field value is undefined.
  1138. *
  1139. * @see #clear(int)
  1140. */
  1141. public final void clear()
  1142. {
  1143. for (int i = 0; i < fields.length; ) {
  1144. stamp[i] = fields[i] = 0; // UNSET == 0
  1145. isSet[i++] = false;
  1146. }
  1147. areAllFieldsSet = areFieldsSet = false;
  1148. isTimeSet = false;
  1149. }
  1150. /**
  1151. * Sets the given calendar field value and the time value
  1152. * (millisecond offset from the <a href="#Epoch">Epoch</a>) of
  1153. * this <code>Calendar</code> undefined. This means that {@link
  1154. * #isSet(int) isSet(field)} will return <code>false</code>, and
  1155. * the date and time calculations will treat the field as if it
  1156. * had never been set. A <code>Calendar</code> implementation
  1157. * class may use the field's specific default value for date and
  1158. * time calculations.
  1159. *
  1160. * <p>The {@link #HOUR_OF_DAY}, {@link #HOUR} and {@link #AM_PM}
  1161. * fields are handled independently and the <a
  1162. * href="#time_resolution">the resolution rule for the time of
  1163. * day</a> is applied. Clearing one of the fields doesn't reset
  1164. * the hour of day value of this <code>Calendar</code>. Use {@link
  1165. * #set(int,int) set(Calendar.HOUR_OF_DAY, 0)} to reset the hour
  1166. * value.
  1167. *
  1168. * @param field the calendar field to be cleared.
  1169. * @see #clear()
  1170. */
  1171. public final void clear(int field)
  1172. {
  1173. fields[field] = 0;
  1174. stamp[field] = UNSET;
  1175. isSet[field] = false;
  1176. areAllFieldsSet = areFieldsSet = false;
  1177. isTimeSet = false;
  1178. }
  1179. /**
  1180. * Determines if the given calendar field has a value set,
  1181. * including cases that the value has been set by internal fields
  1182. * calculations triggered by a <code>get</code> method call.
  1183. *
  1184. * @return <code>true</code> if the given calendar field has a value set;
  1185. * <code>false</code> otherwise.
  1186. */
  1187. public final boolean isSet(int field)
  1188. {
  1189. return stamp[field] != UNSET;
  1190. }
  1191. /**
  1192. * Fills in any unset fields in the calendar fields. First, the {@link
  1193. * #computeTime()} method is called if the time value (millisecond offset
  1194. * from the <a href="#Epoch">Epoch</a>) has not been calculated from
  1195. * calendar field values. Then, the {@link #computeFields()} method is
  1196. * called to calculate all calendar field values.
  1197. */
  1198. protected void complete()
  1199. {
  1200. if (!isTimeSet)
  1201. updateTime();
  1202. if (!areFieldsSet || !areAllFieldsSet) {
  1203. computeFields(); // fills in unset fields
  1204. areAllFieldsSet = areFieldsSet = true;
  1205. } else {
  1206. // When a computeTime() call happens to calculate all the
  1207. // fields, stamp[] are not modified to preserve what the
  1208. // application has set. We need to normalize all stamp
  1209. // elements to COMPUTED here. (5078053)
  1210. setFieldsComputed(ALL_FIELDS);
  1211. }
  1212. }
  1213. /**
  1214. * Returns whether the value of the specified calendar field has been set
  1215. * externally by calling one of the setter methods rather than by the
  1216. * internal time calculation.
  1217. *
  1218. * @return <code>true</code> if the field has been set externally,
  1219. * <code>false</code> otherwise.
  1220. * @exception IndexOutOfBoundsException if the specified
  1221. * <code>field</code> is out of range
  1222. * (<code>field < 0 || field >= FIELD_COUNT</code>).
  1223. * @see #selectFields()
  1224. * @see #setFieldsComputed(int)
  1225. */
  1226. final boolean isExternallySet(int field) {
  1227. return stamp[field] >= MINIMUM_USER_STAMP;
  1228. }
  1229. /**
  1230. * Returns a field mask (bit mask) indicating all calendar fields that
  1231. * have the state of externally or internally set.
  1232. *
  1233. * @return a bit mask indicating set state fields
  1234. */
  1235. final int getSetStateFields() {
  1236. int mask = 0;
  1237. for (int i = 0; i < fields.length; i++) {
  1238. if (stamp[i] != UNSET) {
  1239. mask |= 1 << i;
  1240. }
  1241. }
  1242. return mask;
  1243. }
  1244. /**
  1245. * Sets the state of the specified calendar fields to
  1246. * <em>computed</em>. This state means that the specified calendar fields
  1247. * have valid values that have been set by internal time calculation
  1248. * rather than by calling one of the setter methods.
  1249. *
  1250. * @param fieldMask the field to be marked as computed.
  1251. * @exception IndexOutOfBoundsException if the specified
  1252. * <code>field</code> is out of range
  1253. * (<code>field < 0 || field >= FIELD_COUNT</code>).
  1254. * @see #isExternallySet(int)
  1255. * @see #selectFields()
  1256. */
  1257. final void setFieldsComputed(int fieldMask) {
  1258. if (fieldMask == ALL_FIELDS) {
  1259. for (int i = 0; i < fields.length; i++) {
  1260. stamp[i] = COMPUTED;
  1261. isSet[i] = true;
  1262. }
  1263. areFieldsSet = areAllFieldsSet = true;
  1264. } else {
  1265. for (int i = 0; i < fields.length; i++) {
  1266. if ((fieldMask & 1) == 1) {
  1267. stamp[i] = COMPUTED;
  1268. isSet[i] = true;
  1269. } else {
  1270. if (areAllFieldsSet && !isSet[i]) {
  1271. areAllFieldsSet = false;
  1272. }
  1273. }
  1274. fieldMask >>>= 1;
  1275. }
  1276. }
  1277. }
  1278. /**
  1279. * Sets the state of the calendar fields that are <em>not</em> specified
  1280. * by <code>fieldMask</code> to <em>unset</em>. If <code>fieldMask</code>
  1281. * specifies all the calendar fields, then the state of this
  1282. * <code>Calendar</code> becomes that all the calendar fields are in sync
  1283. * with the time value (millisecond offset from the Epoch).
  1284. *
  1285. * @param fieldMask the field mask indicating which calendar fields are in
  1286. * sync with the time value.
  1287. * @exception IndexOutOfBoundsException if the specified
  1288. * <code>field</code> is out of range
  1289. * (<code>field < 0 || field >= FIELD_COUNT</code>).
  1290. * @see #isExternallySet(int)
  1291. * @see #selectFields()
  1292. */
  1293. final void setFieldsNormalized(int fieldMask) {
  1294. if (fieldMask == ALL_FIELDS) {
  1295. // all calendar fields are in sync with the time value
  1296. areFieldsSet = areAllFieldsSet = true;
  1297. return;
  1298. }
  1299. for (int i = 0; i < fields.length; i++) {
  1300. if ((fieldMask & 1) == 0) {
  1301. stamp[i] = fields[i] = 0; // UNSET == 0
  1302. isSet[i] = false;
  1303. }
  1304. fieldMask >>= 1;
  1305. }
  1306. // Some fields are in sync with the milliseconds, but not all
  1307. // fields have been calculated.
  1308. areFieldsSet = true;
  1309. areAllFieldsSet = false;
  1310. }
  1311. /**
  1312. * Returns whether the calendar fields are partially in sync with the time
  1313. * value.
  1314. */
  1315. final boolean isPartiallyNormalized() {
  1316. return areFieldsSet && !areAllFieldsSet;
  1317. }
  1318. /**
  1319. * Returns whether the calendar fields are fully in sync with the time
  1320. * value.
  1321. */
  1322. final boolean isFullyNormalized() {
  1323. return areFieldsSet && areAllFieldsSet;
  1324. }
  1325. /**
  1326. * Marks this Calendar as not sync'd.
  1327. */
  1328. final void setUnnormalized() {
  1329. areFieldsSet = areAllFieldsSet = false;
  1330. }
  1331. /**
  1332. * Returns whether the specified <code>field</code> is on in the
  1333. * <code>fieldMask</code>.
  1334. */
  1335. static final boolean isFieldSet(int fieldMask, int field) {
  1336. return (fieldMask & (1 << field)) != 0;
  1337. }
  1338. /**
  1339. * Returns a field mask indicating which calendar field values
  1340. * to be used to calculate the time value. The calendar fields are
  1341. * returned as a bit mask, each bit of which corresponds to a field, i.e.,
  1342. * the mask value of <code>field</code> is <code>(1 <<
  1343. * field)</code>. For example, 0x26 represents the <code>YEAR</code>,
  1344. * <code>MONTH</code>, and <code>DAY_OF_MONTH</code> fields (i.e., 0x26 is
  1345. * equal to
  1346. * <code>(1<<YEAR)|(1<<MONTH)|(1<<DAY_OF_MONTH))</code>.
  1347. *
  1348. * <p>This method supports the calendar fields resolution as described in
  1349. * the class description. If the bit mask for a given field is on and its
  1350. * field has not been set (i.e., <code>isSet(field)</code> is
  1351. * <code>false</code>), then the default value of the field has to be
  1352. * used, which case means that the field has been selected because the
  1353. * selected combination involves the field.
  1354. *
  1355. * @return a bit mask of selected fields
  1356. * @see #isExternallySet(int)
  1357. * @see #setInternallySetState(int)
  1358. */
  1359. final int selectFields() {
  1360. // This implementation has been taken from the GregorianCalendar class.
  1361. // The YEAR field must always be used regardless of its SET
  1362. // state because YEAR is a mandatory field to determine the date
  1363. // and the default value (EPOCH_YEAR) may change through the
  1364. // normalization process.
  1365. int fieldMask = YEAR_MASK;
  1366. if (stamp[ERA] != UNSET) {
  1367. fieldMask |= ERA_MASK;
  1368. }
  1369. // Find the most recent group of fields specifying the day within
  1370. // the year. These may be any of the following combinations:
  1371. // MONTH + DAY_OF_MONTH
  1372. // MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
  1373. // MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
  1374. // DAY_OF_YEAR
  1375. // WEEK_OF_YEAR + DAY_OF_WEEK
  1376. // We look for the most recent of the fields in each group to determine
  1377. // the age of the group. For groups involving a week-related field such
  1378. // as WEEK_OF_MONTH, DAY_OF_WEEK_IN_MONTH, or WEEK_OF_YEAR, both the
  1379. // week-related field and the DAY_OF_WEEK must be set for the group as a
  1380. // whole to be considered. (See bug 4153860 - liu 7/24/98.)
  1381. int dowStamp = stamp[DAY_OF_WEEK];
  1382. int monthStamp = stamp[MONTH];
  1383. int domStamp = stamp[DAY_OF_MONTH];
  1384. int womStamp = aggregateStamp(stamp[WEEK_OF_MONTH], dowStamp);
  1385. int dowimStamp = aggregateStamp(stamp[DAY_OF_WEEK_IN_MONTH], dowStamp);
  1386. int doyStamp = stamp[DAY_OF_YEAR];
  1387. int woyStamp = aggregateStamp(stamp[WEEK_OF_YEAR], dowStamp);
  1388. int bestStamp = domStamp;
  1389. if (womStamp > bestStamp) {
  1390. bestStamp = womStamp;
  1391. }
  1392. if (dowimStamp > bestStamp) {
  1393. bestStamp = dowimStamp;
  1394. }
  1395. if (doyStamp > bestStamp) {
  1396. bestStamp = doyStamp;
  1397. }
  1398. if (woyStamp > bestStamp) {
  1399. bestStamp = woyStamp;
  1400. }
  1401. /* No complete combination exists. Look for WEEK_OF_MONTH,
  1402. * DAY_OF_WEEK_IN_MONTH, or WEEK_OF_YEAR alone. Treat DAY_OF_WEEK alone
  1403. * as DAY_OF_WEEK_IN_MONTH.
  1404. */
  1405. if (bestStamp == UNSET) {
  1406. womStamp = stamp[WEEK_OF_MONTH];
  1407. dowimStamp = Math.max(stamp[DAY_OF_WEEK_IN_MONTH], dowStamp);
  1408. woyStamp = stamp[WEEK_OF_YEAR];
  1409. bestStamp = Math.max(Math.max(womStamp, dowimStamp), woyStamp);
  1410. /* Treat MONTH alone or no fields at all as DAY_OF_MONTH. This may
  1411. * result in bestStamp = domStamp = UNSET if no fields are set,
  1412. * which indicates DAY_OF_MONTH.
  1413. */
  1414. if (bestStamp == UNSET) {
  1415. bestStamp = domStamp = monthStamp;
  1416. }
  1417. }
  1418. if (bestStamp == domStamp ||
  1419. (bestStamp == womStamp && stamp[WEEK_OF_MONTH] >= stamp[WEEK_OF_YEAR]) ||
  1420. (bestStamp == dowimStamp && stamp[DAY_OF_WEEK_IN_MONTH] >= stamp[WEEK_OF_YEAR])) {
  1421. fieldMask |= MONTH_MASK;
  1422. if (bestStamp == domStamp) {
  1423. fieldMask |= DAY_OF_MONTH_MASK;
  1424. } else {
  1425. assert (bestStamp == womStamp || bestStamp == dowimStamp);
  1426. if (dowStamp != UNSET) {
  1427. fieldMask |= DAY_OF_WEEK_MASK;
  1428. }
  1429. if (bestStamp == womStamp) {
  1430. fieldMask |= WEEK_OF_MONTH_MASK;
  1431. } else {
  1432. assert (bestStamp == dowimStamp);
  1433. if (stamp[DAY_OF_WEEK_IN_MONTH] != UNSET) {
  1434. fieldMask |= DAY_OF_WEEK_IN_MONTH_MASK;
  1435. }
  1436. }
  1437. }
  1438. } else {
  1439. assert (bestStamp == doyStamp || bestStamp == woyStamp ||
  1440. bestStamp == UNSET);
  1441. if (bestStamp == doyStamp) {
  1442. fieldMask |= DAY_OF_YEAR_MASK;
  1443. } else {
  1444. assert (bestStamp == woyStamp);
  1445. if (dowStamp != UNSET) {
  1446. fieldMask |= DAY_OF_WEEK_MASK;
  1447. }
  1448. fieldMask |= WEEK_OF_YEAR_MASK;
  1449. }
  1450. }
  1451. // Find the best set of fields specifying the time of day. There
  1452. // are only two possibilities here; the HOUR_OF_DAY or the
  1453. // AM_PM and the HOUR.
  1454. int hourOfDayStamp = stamp[HOUR_OF_DAY];
  1455. int hourStamp = aggregateStamp(stamp[HOUR], stamp[AM_PM]);
  1456. bestStamp = (hourStamp > hourOfDayStamp) ? hourStamp : hourOfDayStamp;
  1457. // if bestStamp is still UNSET, then take HOUR or AM_PM. (See 4846659)
  1458. if (bestStamp == UNSET) {
  1459. bestStamp = Math.max(stamp[HOUR], stamp[AM_PM]);
  1460. }
  1461. // Hours
  1462. if (bestStamp != UNSET) {
  1463. if (bestStamp == hourOfDayStamp) {
  1464. fieldMask |= HOUR_OF_DAY_MASK;
  1465. } else {
  1466. fieldMask |= HOUR_MASK;
  1467. if (stamp[AM_PM] != UNSET) {
  1468. fieldMask |= AM_PM_MASK;
  1469. }
  1470. }
  1471. }
  1472. if (stamp[MINUTE] != UNSET) {
  1473. fieldMask |= MINUTE_MASK;
  1474. }
  1475. if (stamp[SECOND] != UNSET) {
  1476. fieldMask |= SECOND_MASK;
  1477. }
  1478. if (stamp[MILLISECOND] != UNSET) {
  1479. fieldMask |= MILLISECOND_MASK;
  1480. }
  1481. if (stamp[ZONE_OFFSET] >= MINIMUM_USER_STAMP) {
  1482. fieldMask |= ZONE_OFFSET_MASK;
  1483. }
  1484. if (stamp[DST_OFFSET] >= MINIMUM_USER_STAMP) {
  1485. fieldMask |= DST_OFFSET_MASK;
  1486. }
  1487. return fieldMask;
  1488. }
  1489. /**
  1490. * Returns the pseudo-time-stamp for two fields, given their
  1491. * individual pseudo-time-stamps. If either of the fields
  1492. * is unset, then the aggregate is unset. Otherwise, the
  1493. * aggregate is the later of the two stamps.
  1494. */
  1495. private static final int aggregateStamp(int stamp_a, int stamp_b) {
  1496. if (stamp_a == UNSET || stamp_b == UNSET) {
  1497. return UNSET;
  1498. }
  1499. return (stamp_a > stamp_b) ? stamp_a : stamp_b;
  1500. }
  1501. /**
  1502. * Compares this <code>Calendar</code> to the specified
  1503. * <code>Object</code>. The result is <code>true</code> if and only if
  1504. * the argument is a <code>Calendar</code> object of the same calendar
  1505. * system that represents the same time value (millisecond offset from the
  1506. * <a href="#Epoch">Epoch</a>) under the same
  1507. * <code>Calendar</code> parameters as this object.
  1508. *
  1509. * <p>The <code>Calendar</code> parameters are the values represented
  1510. * by the <code>isLenient</code>, <code>getFirstDayOfWeek</code>,
  1511. * <code>getMinimalDaysInFirstWeek</code> and <code>getTimeZone</code>
  1512. * methods. If there is any difference in those parameters
  1513. * between the two <code>Calendar</code>s, this method returns
  1514. * <code>false</code>.
  1515. *
  1516. * <p>Use the {@link #compareTo(Calendar) compareTo} method to
  1517. * compare only the time values.
  1518. *
  1519. * @param obj the object to compare with.
  1520. * @return <code>true</code> if this object is equal to <code>obj</code>
  1521. * <code>false</code> otherwise.
  1522. */
  1523. public boolean equals(Object obj) {
  1524. if (this == obj)
  1525. return true;
  1526. try {
  1527. Calendar that = (Calendar)obj;
  1528. return compareTo(getMillisOf(that)) == 0 &&
  1529. lenient == that.lenient &&
  1530. firstDayOfWeek == that.firstDayOfWeek &&
  1531. minimalDaysInFirstWeek == that.minimalDaysInFirstWeek &&
  1532. zone.equals(that.zone);
  1533. } catch (Exception e) {
  1534. // Note: GregorianCalendar.computeTime throws
  1535. // IllegalArgumentException if the ERA value is invalid
  1536. // even it's in lenient mode.
  1537. }
  1538. return false;
  1539. }
  1540. /**
  1541. * Returns a hash code for this calendar.
  1542. *
  1543. * @return a hash code value for this object.
  1544. * @since 1.2
  1545. */
  1546. public int hashCode() {
  1547. // 'otheritems' represents the hash code for the previous versions.
  1548. int otheritems = (lenient ? 1 : 0)
  1549. | (firstDayOfWeek << 1)
  1550. | (minimalDaysInFirstWeek << 4)
  1551. | (zone.hashCode() << 7);
  1552. long t = getMillisOf(this);
  1553. return (int) t ^ (int)(t >> 32) ^ otheritems;
  1554. }
  1555. /**
  1556. * Returns whether this <code>Calendar</code> represents a time
  1557. * before the time represented by the specified
  1558. * <code>Object</code>. This method is equivalent to:
  1559. * <pre><blockquote>
  1560. * compareTo(when) < 0
  1561. * </blockquote></pre>
  1562. * if and only if <code>when</code> is a <code>Calendar</code>
  1563. * instance. Otherwise, the method returns <code>false</code>.
  1564. *
  1565. * @param when the <code>Object</code> to be compared
  1566. * @return <code>true</code> if the time of this
  1567. * <code>Calendar</code> is before the time represented by
  1568. * <code>when</code> <code>false</code> otherwise.
  1569. * @see #compareTo(Calendar)
  1570. */
  1571. public boolean before(Object when) {
  1572. return when instanceof Calendar
  1573. && compareTo((Calendar)when) < 0;
  1574. }
  1575. /**
  1576. * Returns whether this <code>Calendar</code> represents a time
  1577. * after the time represented by the specified
  1578. * <code>Object</code>. This method is equivalent to:
  1579. * <pre><blockquote>
  1580. * compareTo(when) > 0
  1581. * </blockquote></pre>
  1582. * if and only if <code>when</code> is a <code>Calendar</code>
  1583. * instance. Otherwise, the method returns <code>false</code>.
  1584. *
  1585. * @param when the <code>Object</code> to be compared
  1586. * @return <code>true</code> if the time of this <code>Calendar</code> is
  1587. * after the time represented by <code>when</code> <code>false</code>
  1588. * otherwise.
  1589. * @see #compareTo(Calendar)
  1590. */
  1591. public boolean after(Object when) {
  1592. return when instanceof Calendar
  1593. && compareTo((Calendar)when) > 0;
  1594. }
  1595. /**
  1596. * Compares the time values (millisecond offsets from the <a
  1597. * href="#Epoch">Epoch</a>) represented by two
  1598. * <code>Calendar</code> objects.
  1599. *
  1600. * @param anotherCalendar the <code>Calendar</code> to be compared.
  1601. * @return the value <code>0</code> if the time represented by the argument
  1602. * is equal to the time represented by this <code>Calendar</code> a value
  1603. * less than <code>0</code> if the time of this <code>Calendar</code> is
  1604. * before the time represented by the argument; and a value greater than
  1605. * <code>0</code> if the time of this <code>Calendar</code> is after the
  1606. * time represented by the argument.
  1607. * @exception NullPointerException if the specified <code>Calendar</code> is
  1608. * <code>null</code>.
  1609. * @exception IllegalArgumentException if the time value of the
  1610. * specified <code>Calendar</code> object can't be obtained due to
  1611. * any invalid calendar values.
  1612. * @since 1.5
  1613. */
  1614. public int compareTo(Calendar anotherCalendar) {
  1615. return compareTo(getMillisOf(anotherCalendar));
  1616. }
  1617. /**
  1618. * Adds or subtracts the specified amount of time to the given calendar field,
  1619. * based on the calendar's rules. For example, to subtract 5 days from
  1620. * the current time of the calendar, you can achieve it by calling:
  1621. * <p><code>add(Calendar.DAY_OF_MONTH, -5)</code>.
  1622. *
  1623. * @param field the calendar field.
  1624. * @param amount the amount of date or time to be added to the field.
  1625. * @see #roll(int,int)
  1626. * @see #set(int,int)
  1627. */
  1628. abstract public void add(int field, int amount);
  1629. /**
  1630. * Adds or subtracts (up/down) a single unit of time on the given time
  1631. * field without changing larger fields. For example, to roll the current
  1632. * date up by one day, you can achieve it by calling:
  1633. * <p>roll(Calendar.DATE, true).
  1634. * When rolling on the year or Calendar.YEAR field, it will roll the year
  1635. * value in the range between 1 and the value returned by calling
  1636. * <code>getMaximum(Calendar.YEAR)</code>.
  1637. * When rolling on the month or Calendar.MONTH field, other fields like
  1638. * date might conflict and, need to be changed. For instance,
  1639. * rolling the month on the date 01/31/96 will result in 02/29/96.
  1640. * When rolling on the hour-in-day or Calendar.HOUR_OF_DAY field, it will
  1641. * roll the hour value in the range between 0 and 23, which is zero-based.
  1642. *
  1643. * @param field the time field.
  1644. * @param up indicates if the value of the specified time field is to be
  1645. * rolled up or rolled down. Use true if rolling up, false otherwise.
  1646. * @see Calendar#add(int,int)
  1647. * @see Calendar#set(int,int)
  1648. */
  1649. abstract public void roll(int field, boolean up);
  1650. /**
  1651. * Adds the specified (signed) amount to the specified calendar field
  1652. * without changing larger fields. A negative amount means to roll
  1653. * down.
  1654. *
  1655. * <p>NOTE: This default implementation on <code>Calendar</code> just repeatedly calls the
  1656. * version of {@link #roll(int,boolean) roll()} that rolls by one unit. This may not
  1657. * always do the right thing. For example, if the <code>DAY_OF_MONTH</code> field is 31,
  1658. * rolling through February will leave it set to 28. The <code>GregorianCalendar</code>
  1659. * version of this function takes care of this problem. Other subclasses
  1660. * should also provide overrides of this function that do the right thing.
  1661. *
  1662. * @param field the calendar field.
  1663. * @param amount the signed amount to add to the calendar <code>field</code>.
  1664. * @since 1.2
  1665. * @see #roll(int,boolean)
  1666. * @see #add(int,int)
  1667. * @see #set(int,int)
  1668. */
  1669. public void roll(int field, int amount)
  1670. {
  1671. while (amount > 0) {
  1672. roll(field, true);
  1673. amount--;
  1674. }
  1675. while (amount < 0) {
  1676. roll(field, false);
  1677. amount++;
  1678. }
  1679. }
  1680. /**
  1681. * Sets the time zone with the given time zone value.
  1682. *
  1683. * @param value the given time zone.
  1684. */
  1685. public void setTimeZone(TimeZone value)
  1686. {
  1687. zone = value;
  1688. sharedZone = false;
  1689. /* Recompute the fields from the time using the new zone. This also
  1690. * works if isTimeSet is false (after a call to set()). In that case
  1691. * the time will be computed from the fields using the new zone, then
  1692. * the fields will get recomputed from that. Consider the sequence of
  1693. * calls: cal.setTimeZone(EST); cal.set(HOUR, 1); cal.setTimeZone(PST).
  1694. * Is cal set to 1 o'clock EST or 1 o'clock PST? Answer: PST. More
  1695. * generally, a call to setTimeZone() affects calls to set() BEFORE AND
  1696. * AFTER it up to the next call to complete().
  1697. */
  1698. areAllFieldsSet = areFieldsSet = false;
  1699. }
  1700. /**
  1701. * Gets the time zone.
  1702. *
  1703. * @return the time zone object associated with this calendar.
  1704. */
  1705. public TimeZone getTimeZone()
  1706. {
  1707. // If the TimeZone object is shared by other Calendar instances, then
  1708. // create a clone.
  1709. if (sharedZone) {
  1710. zone = (TimeZone) zone.clone();
  1711. sharedZone = false;
  1712. }
  1713. return zone;
  1714. }
  1715. /**
  1716. * Returns the time zone (without cloning).
  1717. */
  1718. TimeZone getZone() {
  1719. return zone;
  1720. }
  1721. /**
  1722. * Sets the sharedZone flag to <code>shared</code>.
  1723. */
  1724. void setZoneShared(boolean shared) {
  1725. sharedZone = shared;
  1726. }
  1727. /**
  1728. * Specifies whether or not date/time interpretation is to be lenient. With
  1729. * lenient interpretation, a date such as "February 942, 1996" will be
  1730. * treated as being equivalent to the 941st day after February 1, 1996.
  1731. * With strict (non-lenient) interpretation, such dates will cause an exception to be
  1732. * thrown. The default is lenient.
  1733. *
  1734. * @param lenient <code>true</code> if the lenient mode is to be turned
  1735. * on; <code>false</code> if it is to be turned off.
  1736. * @see #isLenient()
  1737. * @see java.text.DateFormat#setLenient
  1738. */
  1739. public void setLenient(boolean lenient)
  1740. {
  1741. this.lenient = lenient;
  1742. }
  1743. /**
  1744. * Tells whether date/time interpretation is to be lenient.
  1745. *
  1746. * @return <code>true</code> if the interpretation mode of this calendar is lenient;
  1747. * <code>false</code> otherwise.
  1748. * @see #setLenient(boolean)
  1749. */
  1750. public boolean isLenient()
  1751. {
  1752. return lenient;
  1753. }
  1754. /**
  1755. * Sets what the first day of the week is; e.g., <code>SUNDAY</code> in the U.S.,
  1756. * <code>MONDAY</code> in France.
  1757. *
  1758. * @param value the given first day of the week.
  1759. * @see #getFirstDayOfWeek()
  1760. * @see #getMinimalDaysInFirstWeek()
  1761. */
  1762. public void setFirstDayOfWeek(int value)
  1763. {
  1764. if (firstDayOfWeek == value) {
  1765. return;
  1766. }
  1767. firstDayOfWeek = value;
  1768. invalidateWeekFields();
  1769. }
  1770. /**
  1771. * Gets what the first day of the week is; e.g., <code>SUNDAY</code> in the U.S.,
  1772. * <code>MONDAY</code> in France.
  1773. *
  1774. * @return the first day of the week.
  1775. * @see #setFirstDayOfWeek(int)
  1776. * @see #getMinimalDaysInFirstWeek()
  1777. */
  1778. public int getFirstDayOfWeek()
  1779. {
  1780. return firstDayOfWeek;
  1781. }
  1782. /**
  1783. * Sets what the minimal days required in the first week of the year are;
  1784. * For example, if the first week is defined as one that contains the first
  1785. * day of the first month of a year, call this method with value 1. If it
  1786. * must be a full week, use value 7.
  1787. *
  1788. * @param value the given minimal days required in the first week
  1789. * of the year.
  1790. * @see #getMinimalDaysInFirstWeek()
  1791. */
  1792. public void setMinimalDaysInFirstWeek(int value)
  1793. {
  1794. if (minimalDaysInFirstWeek == value) {
  1795. return;
  1796. }
  1797. minimalDaysInFirstWeek = value;
  1798. invalidateWeekFields();
  1799. }
  1800. /**
  1801. * Gets what the minimal days required in the first week of the year are;
  1802. * e.g., if the first week is defined as one that contains the first day
  1803. * of the first month of a year, this method returns 1. If
  1804. * the minimal days required must be a full week, this method
  1805. * returns 7.
  1806. *
  1807. * @return the minimal days required in the first week of the year.
  1808. * @see #setMinimalDaysInFirstWeek(int)
  1809. */
  1810. public int getMinimalDaysInFirstWeek()
  1811. {
  1812. return minimalDaysInFirstWeek;
  1813. }
  1814. /**
  1815. * Returns the minimum value for the given calendar field of this
  1816. * <code>Calendar</code> instance. The minimum value is defined as
  1817. * the smallest value returned by the {@link #get(int) get} method
  1818. * for any possible time value. The minimum value depends on
  1819. * calendar system specific parameters of the instance.
  1820. *
  1821. * @param field the calendar field.
  1822. * @return the minimum value for the given calendar field.
  1823. * @see #getMaximum(int)
  1824. * @see #getGreatestMinimum(int)
  1825. * @see #getLeastMaximum(int)
  1826. * @see #getActualMinimum(int)
  1827. * @see #getActualMaximum(int)
  1828. */
  1829. abstract public int getMinimum(int field);
  1830. /**
  1831. * Returns the maximum value for the given calendar field of this
  1832. * <code>Calendar</code> instance. The maximum value is defined as
  1833. * the largest value returned by the {@link #get(int) get} method
  1834. * for any possible time value. The maximum value depends on
  1835. * calendar system specific parameters of the instance.
  1836. *
  1837. * @param field the calendar field.
  1838. * @return the maximum value for the given calendar field.
  1839. * @see #getMinimum(int)
  1840. * @see #getGreatestMinimum(int)
  1841. * @see #getLeastMaximum(int)
  1842. * @see #getActualMinimum(int)
  1843. * @see #getActualMaximum(int)
  1844. */
  1845. abstract public int getMaximum(int field);
  1846. /**
  1847. * Returns the highest minimum value for the given calendar field
  1848. * of this <code>Calendar</code> instance. The highest minimum
  1849. * value is defined as the largest value returned by {@link
  1850. * #getActualMinimum(int)} for any possible time value. The
  1851. * greatest minimum value depends on calendar system specific
  1852. * parameters of the instance.
  1853. *
  1854. * @param field the calendar field.
  1855. * @return the highest minimum value for the given calendar field.
  1856. * @see #getMinimum(int)
  1857. * @see #getMaximum(int)
  1858. * @see #getLeastMaximum(int)
  1859. * @see #getActualMinimum(int)
  1860. * @see #getActualMaximum(int)
  1861. */
  1862. abstract public int getGreatestMinimum(int field);
  1863. /**
  1864. * Returns the lowest maximum value for the given calendar field
  1865. * of this <code>Calendar</code> instance. The lowest maximum
  1866. * value is defined as the smallest value returned by {@link
  1867. * #getActualMaximum(int)} for any possible time value. The least
  1868. * maximum value depends on calendar system specific parameters of
  1869. * the instance. For example, a <code>Calendar</code> for the
  1870. * Gregorian calendar system returns 28 for the
  1871. * <code>DAY_OF_MONTH</code> field, because the 28th is the last
  1872. * day of the shortest month of this calendar, February in a
  1873. * common year.
  1874. *
  1875. * @param field the calendar field.
  1876. * @return the lowest maximum value for the given calendar field.
  1877. * @see #getMinimum(int)
  1878. * @see #getMaximum(int)
  1879. * @see #getGreatestMinimum(int)
  1880. * @see #getActualMinimum(int)
  1881. * @see #getActualMaximum(int)
  1882. */
  1883. abstract public int getLeastMaximum(int field);
  1884. /**
  1885. * Returns the minimum value that the specified calendar field
  1886. * could have, given the time value of this <code>Calendar</code>.
  1887. *
  1888. * <p>The default implementation of this method uses an iterative
  1889. * algorithm to determine the actual minimum value for the
  1890. * calendar field. Subclasses should, if possible, override this
  1891. * with a more efficient implementation - in many cases, they can
  1892. * simply return <code>getMinimum()</code>.
  1893. *
  1894. * @param field the calendar field
  1895. * @return the minimum of the given calendar field for the time
  1896. * value of this <code>Calendar</code>
  1897. * @see #getMinimum(int)
  1898. * @see #getMaximum(int)
  1899. * @see #getGreatestMinimum(int)
  1900. * @see #getLeastMaximum(int)
  1901. * @see #getActualMaximum(int)
  1902. * @since 1.2
  1903. */
  1904. public int getActualMinimum(int field) {
  1905. int fieldValue = getGreatestMinimum(field);
  1906. int endValue = getMinimum(field);
  1907. // if we know that the minimum value is always the same, just return it
  1908. if (fieldValue == endValue) {
  1909. return fieldValue;
  1910. }
  1911. // clone the calendar so we don't mess with the real one, and set it to
  1912. // accept anything for the field values
  1913. Calendar work = (Calendar)this.clone();
  1914. work.setLenient(true);
  1915. // now try each value from getLeastMaximum() to getMaximum() one by one until
  1916. // we get a value that normalizes to another value. The last value that
  1917. // normalizes to itself is the actual minimum for the current date
  1918. int result = fieldValue;
  1919. do {
  1920. work.set(field, fieldValue);
  1921. if (work.get(field) != fieldValue) {
  1922. break;
  1923. } else {
  1924. result = fieldValue;
  1925. fieldValue--;
  1926. }
  1927. } while (fieldValue >= endValue);
  1928. return result;
  1929. }
  1930. /**
  1931. * Returns the maximum value that the specified calendar field
  1932. * could have, given the time value of this
  1933. * <code>Calendar</code>. For example, the actual maximum value of
  1934. * the <code>MONTH</code> field is 12 in some years, and 13 in
  1935. * other years in the Hebrew calendar system.
  1936. *
  1937. * <p>The default implementation of this method uses an iterative
  1938. * algorithm to determine the actual maximum value for the
  1939. * calendar field. Subclasses should, if possible, override this
  1940. * with a more efficient implementation.
  1941. *
  1942. * @param field the calendar field
  1943. * @return the maximum of the given calendar field for the time
  1944. * value of this <code>Calendar</code>
  1945. * @see #getMinimum(int)
  1946. * @see #getMaximum(int)
  1947. * @see #getGreatestMinimum(int)
  1948. * @see #getLeastMaximum(int)
  1949. * @see #getActualMinimum(int)
  1950. * @since 1.2
  1951. */
  1952. public int getActualMaximum(int field) {
  1953. int fieldValue = getLeastMaximum(field);
  1954. int endValue = getMaximum(field);
  1955. // if we know that the maximum value is always the same, just return it.
  1956. if (fieldValue == endValue) {
  1957. return fieldValue;
  1958. }
  1959. // clone the calendar so we don't mess with the real one, and set it to
  1960. // accept anything for the field values.
  1961. Calendar work = (Calendar)this.clone();
  1962. work.setLenient(true);
  1963. // if we're counting weeks, set the day of the week to Sunday. We know the
  1964. // last week of a month or year will contain the first day of the week.
  1965. if (field == WEEK_OF_YEAR || field == WEEK_OF_MONTH)
  1966. work.set(DAY_OF_WEEK, firstDayOfWeek);
  1967. // now try each value from getLeastMaximum() to getMaximum() one by one until
  1968. // we get a value that normalizes to another value. The last value that
  1969. // normalizes to itself is the actual maximum for the current date
  1970. int result = fieldValue;
  1971. do {
  1972. work.set(field, fieldValue);
  1973. if (work.get(field) != fieldValue) {
  1974. break;
  1975. } else {
  1976. result = fieldValue;
  1977. fieldValue++;
  1978. }
  1979. } while (fieldValue <= endValue);
  1980. return result;
  1981. }
  1982. /**
  1983. * Creates and returns a copy of this object.
  1984. *
  1985. * @return a copy of this object.
  1986. */
  1987. public Object clone()
  1988. {
  1989. try {
  1990. Calendar other = (Calendar) super.clone();
  1991. other.fields = new int[FIELD_COUNT];
  1992. other.isSet = new boolean[FIELD_COUNT];
  1993. other.stamp = new int[FIELD_COUNT];
  1994. for (int i = 0; i < FIELD_COUNT; i++) {
  1995. other.fields[i] = fields[i];
  1996. other.stamp[i] = stamp[i];
  1997. other.isSet[i] = isSet[i];
  1998. }
  1999. other.zone = (TimeZone) zone.clone();
  2000. return other;
  2001. }
  2002. catch (CloneNotSupportedException e) {
  2003. // this shouldn't happen, since we are Cloneable
  2004. throw new InternalError();
  2005. }
  2006. }
  2007. private static final String[] FIELD_NAME = {
  2008. "ERA", "YEAR", "MONTH", "WEEK_OF_YEAR", "WEEK_OF_MONTH", "DAY_OF_MONTH",
  2009. "DAY_OF_YEAR", "DAY_OF_WEEK", "DAY_OF_WEEK_IN_MONTH", "AM_PM", "HOUR",
  2010. "HOUR_OF_DAY", "MINUTE", "SECOND", "MILLISECOND", "ZONE_OFFSET",
  2011. "DST_OFFSET"
  2012. };
  2013. /**
  2014. * Returns the name of the specified calendar field.
  2015. *
  2016. * @param field the calendar field
  2017. * @return the calendar field name
  2018. * @exception IndexOutOfBoundsException if <code>field</code> is negative,
  2019. * equal to or greater then <code>FIELD_COUNT</code>.
  2020. */
  2021. static final String getFieldName(int field) {
  2022. return FIELD_NAME[field];
  2023. }
  2024. /**
  2025. * Return a string representation of this calendar. This method
  2026. * is intended to be used only for debugging purposes, and the
  2027. * format of the returned string may vary between implementations.
  2028. * The returned string may be empty but may not be <code>null</code>.
  2029. *
  2030. * @return a string representation of this calendar.
  2031. */
  2032. public String toString() {
  2033. // NOTE: BuddhistCalendar.toString() interprets the string
  2034. // produced by this method so that the Gregorian year number
  2035. // is substituted by its B.E. year value. It relies on
  2036. // "...,YEAR=<year>,..." or "...,YEAR=?,...".
  2037. StringBuilder buffer = new StringBuilder(800);
  2038. buffer.append(getClass().getName()).append('[');
  2039. appendValue(buffer, "time", isTimeSet, time);
  2040. buffer.append(",areFieldsSet=").append(areFieldsSet);
  2041. buffer.append(",areAllFieldsSet=").append(areAllFieldsSet);
  2042. buffer.append(",lenient=").append(lenient);
  2043. buffer.append(",zone=").append(zone);
  2044. appendValue(buffer, ",firstDayOfWeek", true, (long) firstDayOfWeek);
  2045. appendValue(buffer, ",minimalDaysInFirstWeek", true, (long) minimalDaysInFirstWeek);
  2046. for (int i = 0; i < FIELD_COUNT; ++i) {
  2047. buffer.append(',');
  2048. appendValue(buffer, FIELD_NAME[i], isSet(i), (long) fields[i]);
  2049. }
  2050. buffer.append(']');
  2051. return buffer.toString();
  2052. }
  2053. // =======================privates===============================
  2054. private static final void appendValue(StringBuilder sb, String item, boolean valid, long value) {
  2055. sb.append(item).append('=');
  2056. if (valid) {
  2057. sb.append(value);
  2058. } else {
  2059. sb.append('?');
  2060. }
  2061. }
  2062. /**
  2063. * Both firstDayOfWeek and minimalDaysInFirstWeek are locale-dependent.
  2064. * They are used to figure out the week count for a specific date for
  2065. * a given locale. These must be set when a Calendar is constructed.
  2066. * @param desiredLocale the given locale.
  2067. */
  2068. private void setWeekCountData(Locale desiredLocale)
  2069. {
  2070. /* try to get the Locale data from the cache */
  2071. int[] data = cachedLocaleData.get(desiredLocale);
  2072. if (data == null) { /* cache miss */
  2073. ResourceBundle resource = LocaleData.getLocaleElements(desiredLocale);
  2074. String[] dateTimePatterns =
  2075. resource.getStringArray("DateTimeElements");
  2076. data = new int[2];
  2077. data[0] = Integer.parseInt(dateTimePatterns[0]);
  2078. data[1] = Integer.parseInt(dateTimePatterns[1]);
  2079. cachedLocaleData.put(desiredLocale, data);
  2080. }
  2081. firstDayOfWeek = data[0];
  2082. minimalDaysInFirstWeek = data[1];
  2083. }
  2084. /**
  2085. * Recomputes the time and updates the status fields isTimeSet
  2086. * and areFieldsSet. Callers should check isTimeSet and only
  2087. * call this method if isTimeSet is false.
  2088. */
  2089. private void updateTime() {
  2090. computeTime();
  2091. // The areFieldsSet and areAllFieldsSet values are no longer
  2092. // controlled here (as of 1.5).
  2093. isTimeSet = true;
  2094. }
  2095. private int compareTo(long t) {
  2096. long thisTime = getMillisOf(this);
  2097. return (thisTime > t) ? 1 : (thisTime == t) ? 0 : -1;
  2098. }
  2099. private static final long getMillisOf(Calendar calendar) {
  2100. if (calendar.isTimeSet) {
  2101. return calendar.time;
  2102. }
  2103. Calendar cal = (Calendar) calendar.clone();
  2104. cal.setLenient(true);
  2105. return cal.getTimeInMillis();
  2106. }
  2107. /**
  2108. * Adjusts the stamp[] values before nextStamp overflow. nextStamp
  2109. * is set to the next stamp value upon the return.
  2110. */
  2111. private final void adjustStamp() {
  2112. int max = MINIMUM_USER_STAMP;
  2113. int newStamp = MINIMUM_USER_STAMP;
  2114. for (;;) {
  2115. int min = Integer.MAX_VALUE;
  2116. for (int i = 0; i < stamp.length; i++) {
  2117. int v = stamp[i];
  2118. if (v >= newStamp && min > v) {
  2119. min = v;
  2120. }
  2121. if (max < v) {
  2122. max = v;
  2123. }
  2124. }
  2125. if (max != min && min == Integer.MAX_VALUE) {
  2126. break;
  2127. }
  2128. for (int i = 0; i < stamp.length; i++) {
  2129. if (stamp[i] == min) {
  2130. stamp[i] = newStamp;
  2131. }
  2132. }
  2133. newStamp++;
  2134. if (min == max) {
  2135. break;
  2136. }
  2137. }
  2138. nextStamp = newStamp;
  2139. }
  2140. /**
  2141. * Sets the WEEK_OF_MONTH and WEEK_OF_YEAR fields to new values with the
  2142. * new parameter value if they have been calculated internally.
  2143. */
  2144. private void invalidateWeekFields()
  2145. {
  2146. if (stamp[WEEK_OF_MONTH] != COMPUTED &&
  2147. stamp[WEEK_OF_YEAR] != COMPUTED) {
  2148. return;
  2149. }
  2150. // We have to check the new values of these fields after changing
  2151. // firstDayOfWeek and/or minimalDaysInFirstWeek. If the field values
  2152. // have been changed, then set the new values. (4822110)
  2153. Calendar cal = (Calendar) clone();
  2154. cal.setLenient(true);
  2155. cal.clear(WEEK_OF_MONTH);
  2156. cal.clear(WEEK_OF_YEAR);
  2157. if (stamp[WEEK_OF_MONTH] == COMPUTED) {
  2158. int weekOfMonth = cal.get(WEEK_OF_MONTH);
  2159. if (fields[WEEK_OF_MONTH] != weekOfMonth) {
  2160. fields[WEEK_OF_MONTH] = weekOfMonth;
  2161. }
  2162. }
  2163. if (stamp[WEEK_OF_YEAR] == COMPUTED) {
  2164. int weekOfYear = cal.get(WEEK_OF_YEAR);
  2165. if (fields[WEEK_OF_YEAR] != weekOfYear) {
  2166. fields[WEEK_OF_YEAR] = weekOfYear;
  2167. }
  2168. }
  2169. }
  2170. /**
  2171. * Save the state of this object to a stream (i.e., serialize it).
  2172. *
  2173. * Ideally, <code>Calendar</code> would only write out its state data and
  2174. * the current time, and not write any field data out, such as
  2175. * <code>fields[]</code>, <code>isTimeSet</code>, <code>areFieldsSet</code>,
  2176. * and <code>isSet[]</code>. <code>nextStamp</code> also should not be part
  2177. * of the persistent state. Unfortunately, this didn't happen before JDK 1.1
  2178. * shipped. To be compatible with JDK 1.1, we will always have to write out
  2179. * the field values and state flags. However, <code>nextStamp</code> can be
  2180. * removed from the serialization stream; this will probably happen in the
  2181. * near future.
  2182. */
  2183. private void writeObject(ObjectOutputStream stream)
  2184. throws IOException
  2185. {
  2186. // Try to compute the time correctly, for the future (stream
  2187. // version 2) in which we don't write out fields[] or isSet[].
  2188. if (!isTimeSet) {
  2189. try {
  2190. updateTime();
  2191. }
  2192. catch (IllegalArgumentException e) {}
  2193. }
  2194. // If this Calendar has a ZoneInfo, save it and set a
  2195. // SimpleTimeZone equivalent (as a single DST schedule) for
  2196. // backward compatibility.
  2197. TimeZone savedZone = null;
  2198. if (zone instanceof ZoneInfo) {
  2199. SimpleTimeZone stz = ((ZoneInfo)zone).getLastRuleInstance();
  2200. if (stz == null) {
  2201. stz = new SimpleTimeZone(zone.getRawOffset(), zone.getID());
  2202. }
  2203. savedZone = zone;
  2204. zone = stz;
  2205. }
  2206. // Write out the 1.1 FCS object.
  2207. stream.defaultWriteObject();
  2208. // Write out the ZoneInfo object
  2209. // 4802409: we write out even if it is null, a temporary workaround
  2210. // the real fix for bug 4844924 in corba-iiop
  2211. stream.writeObject(savedZone);
  2212. if (savedZone != null) {
  2213. zone = savedZone;
  2214. }
  2215. }
  2216. /**
  2217. * Reconstitutes this object from a stream (i.e., deserialize it).
  2218. */
  2219. private void readObject(ObjectInputStream stream)
  2220. throws IOException, ClassNotFoundException
  2221. {
  2222. final ObjectInputStream input = stream;
  2223. input.defaultReadObject();
  2224. stamp = new int[FIELD_COUNT];
  2225. // Starting with version 2 (not implemented yet), we expect that
  2226. // fields[], isSet[], isTimeSet, and areFieldsSet may not be
  2227. // streamed out anymore. We expect 'time' to be correct.
  2228. if (serialVersionOnStream >= 2)
  2229. {
  2230. isTimeSet = true;
  2231. if (fields == null) fields = new int[FIELD_COUNT];
  2232. if (isSet == null) isSet = new boolean[FIELD_COUNT];
  2233. }
  2234. else if (serialVersionOnStream >= 0)
  2235. {
  2236. for (int i=0; i<FIELD_COUNT; ++i)
  2237. stamp[i] = isSet[i] ? COMPUTED : UNSET;
  2238. }
  2239. serialVersionOnStream = currentSerialVersion;
  2240. // If there's a ZoneInfo object, use it for zone.
  2241. try {
  2242. ZoneInfo zi = (ZoneInfo) AccessController.doPrivileged(
  2243. new PrivilegedExceptionAction() {
  2244. public Object run() throws Exception {
  2245. return input.readObject();
  2246. }
  2247. });
  2248. if (zi != null) {
  2249. zone = zi;
  2250. }
  2251. } catch (Exception e) {
  2252. }
  2253. // If the deserialized object has a SimpleTimeZone, try to
  2254. // replace it with a ZoneInfo equivalent (as of 1.4) in order
  2255. // to be compatible with the SimpleTimeZone-based
  2256. // implementation as much as possible.
  2257. if (zone instanceof SimpleTimeZone) {
  2258. String id = zone.getID();
  2259. TimeZone zi = TimeZone.getTimeZone(id);
  2260. if (zi != null && zi.hasSameRules(zone) && zi.getID().equals(id)) {
  2261. zone = zi;
  2262. }
  2263. }
  2264. }
  2265. }