1. /*
  2. * @(#)Calendar.java 1.73 03/04/23
  3. *
  4. * Copyright 2003 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.text.DateFormat;
  25. import sun.text.resources.LocaleData;
  26. import sun.util.BuddhistCalendar;
  27. import sun.util.calendar.ZoneInfo;
  28. /**
  29. * <code>Calendar</code> is an abstract base class for converting between
  30. * a <code>Date</code> object and a set of integer fields such as
  31. * <code>YEAR</code>, <code>MONTH</code>, <code>DAY</code>, <code>HOUR</code>,
  32. * and so on. (A <code>Date</code> object represents a specific instant in
  33. * time with millisecond precision. See
  34. * {@link Date}
  35. * for information about the <code>Date</code> class.)
  36. *
  37. * <p>
  38. * Subclasses of <code>Calendar</code> interpret a <code>Date</code>
  39. * according to the rules of a specific calendar system. The platform
  40. * provides one concrete subclass of <code>Calendar</code>:
  41. * <code>GregorianCalendar</code>. Future subclasses could represent
  42. * the various types of lunar calendars in use in many parts of the world.
  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. * time 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 time 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 certain fields,
  60. * as well as their meaning. For example, the first month of the year has value
  61. * <code>MONTH</code> == <code>JANUARY</code> for all calendars. Other values
  62. * are defined by the concrete subclass, such as <code>ERA</code> and
  63. * <code>YEAR</code>. See individual field documentation and subclass
  64. * documentation for details.
  65. *
  66. * <p>When a <code>Calendar</code> is <em>lenient</em>, it accepts a wider range
  67. * of field values than it produces. For example, a lenient
  68. * <code>GregorianCalendar</code> interprets <code>MONTH</code> ==
  69. * <code>JANUARY</code>, <code>DAY_OF_MONTH</code> == 32 as February 1. A
  70. * non-lenient <code>GregorianCalendar</code> throws an exception when given
  71. * out-of-range field settings. When calendars recompute field values for
  72. * return by <code>get()</code>, they normalize them. For example, a
  73. * <code>GregorianCalendar</code> always produces <code>DAY_OF_MONTH</code>
  74. * values between 1 and the length of the month.
  75. *
  76. * <p><code>Calendar</code> defines a locale-specific seven day week using two
  77. * parameters: the first day of the week and the minimal days in first week
  78. * (from 1 to 7). These numbers are taken from the locale resource data when a
  79. * <code>Calendar</code> is constructed. They may also be specified explicitly
  80. * through the API.
  81. *
  82. * <p>When setting or getting the <code>WEEK_OF_MONTH</code> or
  83. * <code>WEEK_OF_YEAR</code> fields, <code>Calendar</code> must determine the
  84. * first week of the month or year as a reference point. The first week of a
  85. * month or year is defined as the earliest seven day period beginning on
  86. * <code>getFirstDayOfWeek()</code> and containing at least
  87. * <code>getMinimalDaysInFirstWeek()</code> days of that month or year. Weeks
  88. * numbered ..., -1, 0 precede the first week; weeks numbered 2, 3,... follow
  89. * it. Note that the normalized numbering returned by <code>get()</code> may be
  90. * different. For example, a specific <code>Calendar</code> subclass may
  91. * designate the week before week 1 of a year as week <em>n</em> of the previous
  92. * year.
  93. *
  94. * <p> When computing a <code>Date</code> from time fields, two special
  95. * circumstances may arise: there may be insufficient information to compute the
  96. * <code>Date</code> (such as only year and month but no day in the month), or
  97. * there may be inconsistent information (such as "Tuesday, July 15, 1996" --
  98. * July 15, 1996 is actually a Monday).
  99. *
  100. * <p>
  101. * <strong>Insufficient information.</strong> The calendar will use default
  102. * information to specify the missing fields. This may vary by calendar; for
  103. * the Gregorian calendar, the default for a field is the same as that of the
  104. * start of the epoch: i.e., YEAR = 1970, MONTH = JANUARY, DATE = 1, etc.
  105. *
  106. * <p>
  107. * <strong>Inconsistent information.</strong> If fields conflict, the calendar
  108. * will give preference to fields set more recently. For example, when
  109. * determining the day, the calendar will look for one of the following
  110. * combinations of fields. The most recent combination, as determined by the
  111. * most recently set single field, will be used.
  112. *
  113. * <blockquote>
  114. * <pre>
  115. * MONTH + DAY_OF_MONTH
  116. * MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
  117. * MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
  118. * DAY_OF_YEAR
  119. * DAY_OF_WEEK + WEEK_OF_YEAR
  120. * </pre>
  121. * </blockquote>
  122. *
  123. * For the time of day:
  124. *
  125. * <blockquote>
  126. * <pre>
  127. * HOUR_OF_DAY
  128. * AM_PM + HOUR
  129. * </pre>
  130. * </blockquote>
  131. *
  132. * <p>
  133. * <strong>Note:</strong> for some non-Gregorian calendars, different
  134. * fields may be necessary for complete disambiguation. For example, a full
  135. * specification of the historical Arabic astronomical calendar requires year,
  136. * month, day-of-month <em>and</em> day-of-week in some cases.
  137. *
  138. * <p>
  139. * <strong>Note:</strong> There are certain possible ambiguities in
  140. * interpretation of certain singular times, which are resolved in the
  141. * following ways:
  142. * <ol>
  143. * <li> 23:59 is the last minute of the day and 00:00 is the first minute of the
  144. * next day. Thus, 23:59 on Dec 31, 1999 < 00:00 on Jan 1, 2000 < 00:01 on
  145. * Jan 1, 2000.
  146. *
  147. * <li> Although historically not precise, midnight also belongs to "am",
  148. * and noon belongs to "pm", so on the same day,
  149. * 12:00 am (midnight) < 12:01 am, and 12:00 pm (noon) < 12:01 pm
  150. * </ol>
  151. *
  152. * <p>
  153. * The date or time format strings are not part of the definition of a
  154. * calendar, as those must be modifiable or overridable by the user at
  155. * runtime. Use {@link DateFormat}
  156. * to format dates.
  157. *
  158. * <p><strong>Field manipulation methods</strong></p>
  159. *
  160. * <p><code>Calendar</code> fields can be changed using three methods:
  161. * <code>set()</code>, <code>add()</code>, and <code>roll()</code>.</p>
  162. *
  163. * <p><strong><code>set(f, value)</code></strong> changes field
  164. * <code>f</code> to <code>value</code>. In addition, it sets an
  165. * internal member variable to indicate that field <code>f</code> has
  166. * been changed. Although field <code>f</code> is changed immediately,
  167. * the calendar's milliseconds is not recomputed until the next call to
  168. * <code>get()</code>, <code>getTime()</code>, or
  169. * <code>getTimeInMillis()</code> is made. Thus, multiple calls to
  170. * <code>set()</code> do not trigger multiple, unnecessary
  171. * computations. As a result of changing a field using
  172. * <code>set()</code>, other fields may also change, depending on the
  173. * field, the field value, and the calendar system. In addition,
  174. * <code>get(f)</code> will not necessarily return <code>value</code>
  175. * after the fields have been recomputed. The specifics are determined by
  176. * the concrete calendar class.</p>
  177. *
  178. * <p><em>Example</em>: Consider a <code>GregorianCalendar</code>
  179. * originally set to August 31, 1999. Calling <code>set(Calendar.MONTH,
  180. * Calendar.SEPTEMBER)</code> sets the calendar to September 31,
  181. * 1999. This is a temporary internal representation that resolves to
  182. * October 1, 1999 if <code>getTime()</code>is then called. However, a
  183. * call to <code>set(Calendar.DAY_OF_MONTH, 30)</code> before the call to
  184. * <code>getTime()</code> sets the calendar to September 30, 1999, since
  185. * no recomputation occurs after <code>set()</code> itself.</p>
  186. *
  187. * <p><strong><code>add(f, delta)</code></strong> adds <code>delta</code>
  188. * to field <code>f</code>. This is equivalent to calling <code>set(f,
  189. * get(f) + delta)</code> with two adjustments:</p>
  190. *
  191. * <blockquote>
  192. * <p><strong>Add rule 1</strong>. The value of field <code>f</code>
  193. * after the call minus the value of field <code>f</code> before the
  194. * call is <code>delta</code>, modulo any overflow that has occurred in
  195. * field <code>f</code>. Overflow occurs when a field value exceeds its
  196. * range and, as a result, the next larger field is incremented or
  197. * decremented and the field value is adjusted back into its range.</p>
  198. *
  199. * <p><strong>Add rule 2</strong>. If a smaller field is expected to be
  200. * invariant, but   it is impossible for it to be equal to its
  201. * prior value because of changes in its minimum or maximum after field
  202. * <code>f</code> is changed, then its value is adjusted to be as close
  203. * as possible to its expected value. A smaller field represents a
  204. * smaller unit of time. <code>HOUR</code> is a smaller field than
  205. * <code>DAY_OF_MONTH</code>. No adjustment is made to smaller fields
  206. * that are not expected to be invariant. The calendar system
  207. * determines what fields are expected to be invariant.</p>
  208. * </blockquote>
  209. *
  210. * <p>In addition, unlike <code>set()</code>, <code>add()</code> forces
  211. * an immediate recomputation of the calendar's milliseconds and all
  212. * fields.</p>
  213. *
  214. * <p><em>Example</em>: Consider a <code>GregorianCalendar</code>
  215. * originally set to August 31, 1999. Calling <code>add(Calendar.MONTH,
  216. * 13)</code> sets the calendar to September 30, 2000. <strong>Add rule
  217. * 1</strong> sets the <code>MONTH</code> field to September, since
  218. * adding 13 months to August gives September of the next year. Since
  219. * <code>DAY_OF_MONTH</code> cannot be 31 in September in a
  220. * <code>GregorianCalendar</code>, <strong>add rule 2</strong> sets the
  221. * <code>DAY_OF_MONTH</code> to 30, the closest possible value. Although
  222. * it is a smaller field, <code>DAY_OF_WEEK</code> is not adjusted by
  223. * rule 2, since it is expected to change when the month changes in a
  224. * <code>GregorianCalendar</code>.</p>
  225. *
  226. * <p><strong><code>roll(f, delta)</code></strong> adds
  227. * <code>delta</code> to field <code>f</code> without changing larger
  228. * fields. This is equivalent to calling <code>add(f, delta)</code> with
  229. * the following adjustment:</p>
  230. *
  231. * <blockquote>
  232. * <p><strong>Roll rule</strong>. Larger fields are unchanged after the
  233. * call. A larger field represents a larger unit of
  234. * time. <code>DAY_OF_MONTH</code> is a larger field than
  235. * <code>HOUR</code>.</p>
  236. * </blockquote>
  237. *
  238. * <p><em>Example</em>: See {@link java.util.GregorianCalendar#roll(int, int)}.
  239. *
  240. * <p><strong>Usage model</strong>. To motivate the behavior of
  241. * <code>add()</code> and <code>roll()</code>, consider a user interface
  242. * component with increment and decrement buttons for the month, day, and
  243. * year, and an underlying <code>GregorianCalendar</code>. If the
  244. * interface reads January 31, 1999 and the user presses the month
  245. * increment button, what should it read? If the underlying
  246. * implementation uses <code>set()</code>, it might read March 3, 1999. A
  247. * better result would be February 28, 1999. Furthermore, if the user
  248. * presses the month increment button again, it should read March 31,
  249. * 1999, not March 28, 1999. By saving the original date and using either
  250. * <code>add()</code> or <code>roll()</code>, depending on whether larger
  251. * fields should be affected, the user interface can behave as most users
  252. * will intuitively expect.</p>
  253. *
  254. * @see Date
  255. * @see GregorianCalendar
  256. * @see TimeZone
  257. * @see java.text.DateFormat
  258. * @version 1.73, 04/23/03
  259. * @author Mark Davis, David Goldsmith, Chen-Lieh Huang, Alan Liu
  260. * @since JDK1.1
  261. */
  262. public abstract class Calendar implements Serializable, Cloneable {
  263. // Data flow in Calendar
  264. // ---------------------
  265. // The current time is represented in two ways by Calendar: as UTC
  266. // milliseconds from the epoch start (1 January 1970 0:00 UTC), and as local
  267. // fields such as MONTH, HOUR, AM_PM, etc. It is possible to compute the
  268. // millis from the fields, and vice versa. The data needed to do this
  269. // conversion is encapsulated by a TimeZone object owned by the Calendar.
  270. // The data provided by the TimeZone object may also be overridden if the
  271. // user sets the ZONE_OFFSET and/or DST_OFFSET fields directly. The class
  272. // keeps track of what information was most recently set by the caller, and
  273. // uses that to compute any other information as needed.
  274. // If the user sets the fields using set(), the data flow is as follows.
  275. // This is implemented by the Calendar subclass's computeTime() method.
  276. // During this process, certain fields may be ignored. The disambiguation
  277. // algorithm for resolving which fields to pay attention to is described
  278. // above.
  279. // local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)
  280. // |
  281. // | Using Calendar-specific algorithm
  282. // V
  283. // local standard millis
  284. // |
  285. // | Using TimeZone or user-set ZONE_OFFSET / DST_OFFSET
  286. // V
  287. // UTC millis (in time data member)
  288. // If the user sets the UTC millis using setTime(), the data flow is as
  289. // follows. This is implemented by the Calendar subclass's computeFields()
  290. // method.
  291. // UTC millis (in time data member)
  292. // |
  293. // | Using TimeZone getOffset()
  294. // V
  295. // local standard millis
  296. // |
  297. // | Using Calendar-specific algorithm
  298. // V
  299. // local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)
  300. // In general, a round trip from fields, through local and UTC millis, and
  301. // back out to fields is made when necessary. This is implemented by the
  302. // complete() method. Resolving a partial set of fields into a UTC millis
  303. // value allows all remaining fields to be generated from that value. If
  304. // the Calendar is lenient, the fields are also renormalized to standard
  305. // ranges when they are regenerated.
  306. /**
  307. * Field number for <code>get</code> and <code>set</code> indicating the
  308. * era, e.g., AD or BC in the Julian calendar. This is a calendar-specific
  309. * value; see subclass documentation.
  310. * @see GregorianCalendar#AD
  311. * @see GregorianCalendar#BC
  312. */
  313. public final static int ERA = 0;
  314. /**
  315. * Field number for <code>get</code> and <code>set</code> indicating the
  316. * year. This is a calendar-specific value; see subclass documentation.
  317. */
  318. public final static int YEAR = 1;
  319. /**
  320. * Field number for <code>get</code> and <code>set</code> indicating the
  321. * month. This is a calendar-specific value. The first month of the year is
  322. * <code>JANUARY</code> which is 0; the last depends on the number of months in a year.
  323. * @see #JANUARY
  324. * @see #FEBRUARY
  325. * @see #MARCH
  326. * @see #APRIL
  327. * @see #MAY
  328. * @see #JUNE
  329. * @see #JULY
  330. * @see #AUGUST
  331. * @see #SEPTEMBER
  332. * @see #OCTOBER
  333. * @see #NOVEMBER
  334. * @see #DECEMBER
  335. * @see #UNDECIMBER
  336. */
  337. public final static int MONTH = 2;
  338. /**
  339. * Field number for <code>get</code> and <code>set</code> indicating the
  340. * week number within the current year. The first week of the year, as
  341. * defined by <code>getFirstDayOfWeek()</code> and
  342. * <code>getMinimalDaysInFirstWeek()</code>, has value 1. Subclasses define
  343. * the value of <code>WEEK_OF_YEAR</code> for days before the first week of
  344. * the year.
  345. * @see #getFirstDayOfWeek
  346. * @see #getMinimalDaysInFirstWeek
  347. */
  348. public final static int WEEK_OF_YEAR = 3;
  349. /**
  350. * Field number for <code>get</code> and <code>set</code> indicating the
  351. * week number within the current month. The first week of the month, as
  352. * defined by <code>getFirstDayOfWeek()</code> and
  353. * <code>getMinimalDaysInFirstWeek()</code>, has value 1. Subclasses define
  354. * the value of <code>WEEK_OF_MONTH</code> for days before the first week of
  355. * the month.
  356. * @see #getFirstDayOfWeek
  357. * @see #getMinimalDaysInFirstWeek
  358. */
  359. public final static int WEEK_OF_MONTH = 4;
  360. /**
  361. * Field number for <code>get</code> and <code>set</code> indicating the
  362. * day of the month. This is a synonym for <code>DAY_OF_MONTH</code>.
  363. * The first day of the month has value 1.
  364. * @see #DAY_OF_MONTH
  365. */
  366. public final static int DATE = 5;
  367. /**
  368. * Field number for <code>get</code> and <code>set</code> indicating the
  369. * day of the month. This is a synonym for <code>DATE</code>.
  370. * The first day of the month has value 1.
  371. * @see #DATE
  372. */
  373. public final static int DAY_OF_MONTH = 5;
  374. /**
  375. * Field number for <code>get</code> and <code>set</code> indicating the day
  376. * number within the current year. The first day of the year has value 1.
  377. */
  378. public final static int DAY_OF_YEAR = 6;
  379. /**
  380. * Field number for <code>get</code> and <code>set</code> indicating the day
  381. * of the week. This field takes values <code>SUNDAY</code>,
  382. * <code>MONDAY</code>, <code>TUESDAY</code>, <code>WEDNESDAY</code>,
  383. * <code>THURSDAY</code>, <code>FRIDAY</code>, and <code>SATURDAY</code>.
  384. * @see #SUNDAY
  385. * @see #MONDAY
  386. * @see #TUESDAY
  387. * @see #WEDNESDAY
  388. * @see #THURSDAY
  389. * @see #FRIDAY
  390. * @see #SATURDAY
  391. */
  392. public final static int DAY_OF_WEEK = 7;
  393. /**
  394. * Field number for <code>get</code> and <code>set</code> indicating the
  395. * ordinal number of the day of the week within the current month. Together
  396. * with the <code>DAY_OF_WEEK</code> field, this uniquely specifies a day
  397. * within a month. Unlike <code>WEEK_OF_MONTH</code> and
  398. * <code>WEEK_OF_YEAR</code>, this field's value does <em>not</em> depend on
  399. * <code>getFirstDayOfWeek()</code> or
  400. * <code>getMinimalDaysInFirstWeek()</code>. <code>DAY_OF_MONTH 1</code>
  401. * through <code>7</code> always correspond to <code>DAY_OF_WEEK_IN_MONTH
  402. * 1</code> <code>8</code> through <code>14</code> correspond to
  403. * <code>DAY_OF_WEEK_IN_MONTH 2</code>, and so on.
  404. * <code>DAY_OF_WEEK_IN_MONTH 0</code> indicates the week before
  405. * <code>DAY_OF_WEEK_IN_MONTH 1</code>. Negative values count back from the
  406. * end of the month, so the last Sunday of a month is specified as
  407. * <code>DAY_OF_WEEK = SUNDAY, DAY_OF_WEEK_IN_MONTH = -1</code>. Because
  408. * negative values count backward they will usually be aligned differently
  409. * within the month than positive values. For example, if a month has 31
  410. * days, <code>DAY_OF_WEEK_IN_MONTH -1</code> will overlap
  411. * <code>DAY_OF_WEEK_IN_MONTH 5</code> and the end of <code>4</code>.
  412. * @see #DAY_OF_WEEK
  413. * @see #WEEK_OF_MONTH
  414. */
  415. public final static int DAY_OF_WEEK_IN_MONTH = 8;
  416. /**
  417. * Field number for <code>get</code> and <code>set</code> indicating
  418. * whether the <code>HOUR</code> is before or after noon.
  419. * E.g., at 10:04:15.250 PM the <code>AM_PM</code> is <code>PM</code>.
  420. * @see #AM
  421. * @see #PM
  422. * @see #HOUR
  423. */
  424. public final static int AM_PM = 9;
  425. /**
  426. * Field number for <code>get</code> and <code>set</code> indicating the
  427. * hour of the morning or afternoon. <code>HOUR</code> is used for the 12-hour
  428. * clock.
  429. * E.g., at 10:04:15.250 PM the <code>HOUR</code> is 10.
  430. * @see #AM_PM
  431. * @see #HOUR_OF_DAY
  432. */
  433. public final static int HOUR = 10;
  434. /**
  435. * Field number for <code>get</code> and <code>set</code> indicating the
  436. * hour of the day. <code>HOUR_OF_DAY</code> is used for the 24-hour clock.
  437. * E.g., at 10:04:15.250 PM the <code>HOUR_OF_DAY</code> is 22.
  438. * @see #HOUR
  439. */
  440. public final static int HOUR_OF_DAY = 11;
  441. /**
  442. * Field number for <code>get</code> and <code>set</code> indicating the
  443. * minute within the hour.
  444. * E.g., at 10:04:15.250 PM the <code>MINUTE</code> is 4.
  445. */
  446. public final static int MINUTE = 12;
  447. /**
  448. * Field number for <code>get</code> and <code>set</code> indicating the
  449. * second within the minute.
  450. * E.g., at 10:04:15.250 PM the <code>SECOND</code> is 15.
  451. */
  452. public final static int SECOND = 13;
  453. /**
  454. * Field number for <code>get</code> and <code>set</code> indicating the
  455. * millisecond within the second.
  456. * E.g., at 10:04:15.250 PM the <code>MILLISECOND</code> is 250.
  457. */
  458. public final static int MILLISECOND = 14;
  459. /**
  460. * Field number for <code>get</code> and <code>set</code>
  461. * indicating the raw offset from GMT in milliseconds.
  462. * <p>
  463. * This field reflects the correct GMT offset value of the time
  464. * zone of this <code>Calendar</code> if the
  465. * <code>TimeZone</code> implementation subclass supports
  466. * historical GMT offset changes.
  467. */
  468. public final static int ZONE_OFFSET = 15;
  469. /**
  470. * Field number for <code>get</code> and <code>set</code> indicating the
  471. * daylight savings offset in milliseconds.
  472. * <p>
  473. * This field reflects the correct daylight saving offset value of
  474. * the time zone of this <code>Calendar</code> if the
  475. * <code>TimeZone</code> implementation subclass supports
  476. * historical Daylight Saving Time schedule changes.
  477. */
  478. public final static int DST_OFFSET = 16;
  479. /**
  480. * The number of distinct fields recognized by <code>get</code> and <code>set</code>.
  481. * Field numbers range from <code>0..FIELD_COUNT-1</code>.
  482. */
  483. public final static int FIELD_COUNT = 17;
  484. /**
  485. * Value of the <code>DAY_OF_WEEK</code> field indicating
  486. * Sunday.
  487. */
  488. public final static int SUNDAY = 1;
  489. /**
  490. * Value of the <code>DAY_OF_WEEK</code> field indicating
  491. * Monday.
  492. */
  493. public final static int MONDAY = 2;
  494. /**
  495. * Value of the <code>DAY_OF_WEEK</code> field indicating
  496. * Tuesday.
  497. */
  498. public final static int TUESDAY = 3;
  499. /**
  500. * Value of the <code>DAY_OF_WEEK</code> field indicating
  501. * Wednesday.
  502. */
  503. public final static int WEDNESDAY = 4;
  504. /**
  505. * Value of the <code>DAY_OF_WEEK</code> field indicating
  506. * Thursday.
  507. */
  508. public final static int THURSDAY = 5;
  509. /**
  510. * Value of the <code>DAY_OF_WEEK</code> field indicating
  511. * Friday.
  512. */
  513. public final static int FRIDAY = 6;
  514. /**
  515. * Value of the <code>DAY_OF_WEEK</code> field indicating
  516. * Saturday.
  517. */
  518. public final static int SATURDAY = 7;
  519. /**
  520. * Value of the <code>MONTH</code> field indicating the
  521. * first month of the year.
  522. */
  523. public final static int JANUARY = 0;
  524. /**
  525. * Value of the <code>MONTH</code> field indicating the
  526. * second month of the year.
  527. */
  528. public final static int FEBRUARY = 1;
  529. /**
  530. * Value of the <code>MONTH</code> field indicating the
  531. * third month of the year.
  532. */
  533. public final static int MARCH = 2;
  534. /**
  535. * Value of the <code>MONTH</code> field indicating the
  536. * fourth month of the year.
  537. */
  538. public final static int APRIL = 3;
  539. /**
  540. * Value of the <code>MONTH</code> field indicating the
  541. * fifth month of the year.
  542. */
  543. public final static int MAY = 4;
  544. /**
  545. * Value of the <code>MONTH</code> field indicating the
  546. * sixth month of the year.
  547. */
  548. public final static int JUNE = 5;
  549. /**
  550. * Value of the <code>MONTH</code> field indicating the
  551. * seventh month of the year.
  552. */
  553. public final static int JULY = 6;
  554. /**
  555. * Value of the <code>MONTH</code> field indicating the
  556. * eighth month of the year.
  557. */
  558. public final static int AUGUST = 7;
  559. /**
  560. * Value of the <code>MONTH</code> field indicating the
  561. * ninth month of the year.
  562. */
  563. public final static int SEPTEMBER = 8;
  564. /**
  565. * Value of the <code>MONTH</code> field indicating the
  566. * tenth month of the year.
  567. */
  568. public final static int OCTOBER = 9;
  569. /**
  570. * Value of the <code>MONTH</code> field indicating the
  571. * eleventh month of the year.
  572. */
  573. public final static int NOVEMBER = 10;
  574. /**
  575. * Value of the <code>MONTH</code> field indicating the
  576. * twelfth month of the year.
  577. */
  578. public final static int DECEMBER = 11;
  579. /**
  580. * Value of the <code>MONTH</code> field indicating the
  581. * thirteenth month of the year. Although <code>GregorianCalendar</code>
  582. * does not use this value, lunar calendars do.
  583. */
  584. public final static int UNDECIMBER = 12;
  585. /**
  586. * Value of the <code>AM_PM</code> field indicating the
  587. * period of the day from midnight to just before noon.
  588. */
  589. public final static int AM = 0;
  590. /**
  591. * Value of the <code>AM_PM</code> field indicating the
  592. * period of the day from noon to just before midnight.
  593. */
  594. public final static int PM = 1;
  595. // Internal notes:
  596. // Calendar contains two kinds of time representations: current "time" in
  597. // milliseconds, and a set of time "fields" representing the current time.
  598. // The two representations are usually in sync, but can get out of sync
  599. // as follows.
  600. // 1. Initially, no fields are set, and the time is invalid.
  601. // 2. If the time is set, all fields are computed and in sync.
  602. // 3. If a single field is set, the time is invalid.
  603. // Recomputation of the time and fields happens when the object needs
  604. // to return a result to the user, or use a result for a computation.
  605. /**
  606. * The field values for the currently set time for this calendar.
  607. * This is an array of <code>FIELD_COUNT</code> integers, with index values
  608. * <code>ERA</code> through <code>DST_OFFSET</code>.
  609. * @serial
  610. */
  611. protected int fields[]; // NOTE: Make transient when possible
  612. /**
  613. * The flags which tell if a specified time field for the calendar is set.
  614. * A new object has no fields set. After the first call to a method
  615. * which generates the fields, they all remain set after that.
  616. * This is an array of <code>FIELD_COUNT</code> booleans, with index values
  617. * <code>ERA</code> through <code>DST_OFFSET</code>.
  618. * @serial
  619. */
  620. protected boolean isSet[]; // NOTE: Remove when possible
  621. /**
  622. * Pseudo-time-stamps which specify when each field was set. There
  623. * are two special values, UNSET and INTERNALLY_SET. Values from
  624. * MINIMUM_USER_SET to Integer.MAX_VALUE are legal user set values.
  625. */
  626. transient int stamp[];
  627. /**
  628. * The currently set time for this calendar, expressed in milliseconds after
  629. * January 1, 1970, 0:00:00 GMT.
  630. * @see #isTimeSet
  631. * @serial
  632. */
  633. protected long time;
  634. /**
  635. * True if then the value of <code>time</code> is valid.
  636. * The time is made invalid by a change to an item of <code>field[]</code>.
  637. * @see #time
  638. * @serial
  639. */
  640. protected boolean isTimeSet; // NOTE: Make transient when possible
  641. /**
  642. * True if <code>fields[]</code> are in sync with the currently set time.
  643. * If false, then the next attempt to get the value of a field will
  644. * force a recomputation of all fields from the current value of
  645. * <code>time</code>.
  646. * @serial
  647. */
  648. protected boolean areFieldsSet; // NOTE: Make transient when possible
  649. /**
  650. * True if all fields have been set.
  651. * @serial
  652. */
  653. transient boolean areAllFieldsSet;
  654. /**
  655. * True if this calendar allows out-of-range field values during computation
  656. * of <code>time</code> from <code>fields[]</code>.
  657. * @see #setLenient
  658. * @serial
  659. */
  660. private boolean lenient = true;
  661. /**
  662. * The <code>TimeZone</code> used by this calendar. </code>Calendar</code>
  663. * uses the time zone data to translate between locale and GMT time.
  664. * @serial
  665. */
  666. private TimeZone zone;
  667. /**
  668. * The first day of the week, with possible values <code>SUNDAY</code>,
  669. * <code>MONDAY</code>, etc. This is a locale-dependent value.
  670. * @serial
  671. */
  672. private int firstDayOfWeek;
  673. /**
  674. * The number of days required for the first week in a month or year,
  675. * with possible values from 1 to 7. This is a locale-dependent value.
  676. * @serial
  677. */
  678. private int minimalDaysInFirstWeek;
  679. /**
  680. * Cache to hold the firstDayOfWeek and minimalDaysInFirstWeek
  681. * of a Locale.
  682. */
  683. private static Hashtable cachedLocaleData = new Hashtable(3);
  684. // Special values of stamp[]
  685. static final int UNSET = 0;
  686. static final int INTERNALLY_SET = 1;
  687. static final int MINIMUM_USER_STAMP = 2;
  688. /**
  689. * The next available value for <code>stamp[]</code>, an internal array.
  690. * This actually should not be written out to the stream, and will probably
  691. * be removed from the stream in the near future. In the meantime,
  692. * a value of <code>MINIMUM_USER_STAMP</code> should be used.
  693. * @serial
  694. */
  695. private int nextStamp = MINIMUM_USER_STAMP;
  696. // the internal serial version which says which version was written
  697. // - 0 (default) for version up to JDK 1.1.5
  698. // - 1 for version from JDK 1.1.6, which writes a correct 'time' value
  699. // as well as compatible values for other fields. This is a
  700. // transitional format.
  701. // - 2 (not implemented yet) a future version, in which fields[],
  702. // areFieldsSet, and isTimeSet become transient, and isSet[] is
  703. // removed. In JDK 1.1.6 we write a format compatible with version 2.
  704. static final int currentSerialVersion = 1;
  705. /**
  706. * The version of the serialized data on the stream. Possible values:
  707. * <dl>
  708. * <dt><b>0</b> or not present on stream</dt>
  709. * <dd>
  710. * JDK 1.1.5 or earlier.
  711. * </dd>
  712. * <dt><b>1</b></dt>
  713. * <dd>
  714. * JDK 1.1.6 or later. Writes a correct 'time' value
  715. * as well as compatible values for other fields. This is a
  716. * transitional format.
  717. * </dd>
  718. * </dl>
  719. * When streaming out this class, the most recent format
  720. * and the highest allowable <code>serialVersionOnStream</code>
  721. * is written.
  722. * @serial
  723. * @since JDK1.1.6
  724. */
  725. private int serialVersionOnStream = currentSerialVersion;
  726. // Proclaim serialization compatibility with JDK 1.1
  727. static final long serialVersionUID = -1807547505821590642L;
  728. /**
  729. * Constructs a Calendar with the default time zone
  730. * and locale.
  731. * @see TimeZone#getDefault
  732. */
  733. protected Calendar()
  734. {
  735. this(TimeZone.getDefault(), Locale.getDefault());
  736. }
  737. /**
  738. * Constructs a calendar with the specified time zone and locale.
  739. * @param zone the time zone to use
  740. * @param aLocale the locale for the week data
  741. */
  742. protected Calendar(TimeZone zone, Locale aLocale)
  743. {
  744. fields = new int[FIELD_COUNT];
  745. isSet = new boolean[FIELD_COUNT];
  746. stamp = new int[FIELD_COUNT];
  747. this.zone = zone;
  748. setWeekCountData(aLocale);
  749. }
  750. /**
  751. * Gets a calendar using the default time zone and locale. The
  752. * <code>Calendar</code> returned is based on the current time
  753. * in the default time zone with the default locale.
  754. *
  755. * @return a Calendar.
  756. */
  757. public static Calendar getInstance()
  758. {
  759. return createCalendar(TimeZone.getDefault(), Locale.getDefault());
  760. }
  761. /**
  762. * Gets a calendar using the specified time zone and default locale.
  763. * The <code>Calendar</code> returned is based on the current time
  764. * in the given time zone with the default locale.
  765. *
  766. * @param zone the time zone to use
  767. * @return a Calendar.
  768. */
  769. public static Calendar getInstance(TimeZone zone)
  770. {
  771. return createCalendar(zone, Locale.getDefault());
  772. }
  773. /**
  774. * Gets a calendar using the default time zone and specified locale.
  775. * The <code>Calendar</code> returned is based on the current time
  776. * in the default time zone with the given locale.
  777. *
  778. * @param aLocale the locale for the week data
  779. * @return a Calendar.
  780. */
  781. public static Calendar getInstance(Locale aLocale)
  782. {
  783. return createCalendar(TimeZone.getDefault(), aLocale);
  784. }
  785. /**
  786. * Gets a calendar with the specified time zone and locale.
  787. * The <code>Calendar</code> returned is based on the current time
  788. * in the given time zone with the given locale.
  789. *
  790. * @param zone the time zone to use
  791. * @param aLocale the locale for the week data
  792. * @return a Calendar.
  793. */
  794. public static Calendar getInstance(TimeZone zone,
  795. Locale aLocale)
  796. {
  797. return createCalendar(zone, aLocale);
  798. }
  799. private static Calendar createCalendar(TimeZone zone,
  800. Locale aLocale)
  801. {
  802. if (aLocale.getLanguage().compareTo("th") == 0) {
  803. if (aLocale.getCountry().compareTo("TH") == 0) {
  804. return new sun.util.BuddhistCalendar(zone, aLocale);
  805. }
  806. }
  807. // else create the default calendar
  808. return new GregorianCalendar(zone, aLocale);
  809. }
  810. /**
  811. * Gets the list of locales for which Calendars are installed.
  812. * @return the list of locales for which Calendars are installed.
  813. */
  814. public static synchronized Locale[] getAvailableLocales()
  815. {
  816. return DateFormat.getAvailableLocales();
  817. }
  818. /**
  819. * Converts the current field values in <code>fields[]</code>
  820. * to the millisecond time value
  821. * <code>time</code>.
  822. */
  823. protected abstract void computeTime();
  824. /**
  825. * Converts
  826. * the current millisecond time value
  827. * <code>time</code>
  828. * to field values in <code>fields[]</code>.
  829. * This allows you to sync up the time field values with
  830. * a new time that is set for the calendar. The time is <em>not</em>
  831. * recomputed first; to recompute the time, then the fields, call the
  832. * <code>complete</code> method.
  833. * @see #complete
  834. */
  835. protected abstract void computeFields();
  836. /**
  837. * Gets this Calendar's current time.
  838. * @return the current time.
  839. * @see #setTime
  840. * @see #getTimeInMillis
  841. */
  842. public final Date getTime() {
  843. return new Date( getTimeInMillis() );
  844. }
  845. /**
  846. * Sets this Calendar's current time with the given Date.
  847. * <p>
  848. * Note: Calling <code>setTime()</code> with
  849. * <code>Date(Long.MAX_VALUE)</code> or <code>Date(Long.MIN_VALUE)</code>
  850. * may yield incorrect field values from <code>get()</code>.
  851. * @param date the given Date.
  852. * @see #getTime
  853. * @see #setTimeInMillis
  854. */
  855. public final void setTime(Date date) {
  856. setTimeInMillis( date.getTime() );
  857. }
  858. /**
  859. * Gets this Calendar's current time as a long.
  860. * @return the current time as UTC milliseconds from the epoch.
  861. * @see #getTime
  862. * @see #setTimeInMillis
  863. */
  864. public long getTimeInMillis() {
  865. if (!isTimeSet) updateTime();
  866. return time;
  867. }
  868. /**
  869. * Sets this Calendar's current time from the given long value.
  870. * @param millis the new time in UTC milliseconds from the epoch.
  871. * @see #setTime
  872. * @see #getTimeInMillis
  873. */
  874. public void setTimeInMillis(long millis) {
  875. isTimeSet = true;
  876. time = millis;
  877. areFieldsSet = false;
  878. if (!areFieldsSet) {
  879. computeFields();
  880. areFieldsSet = true;
  881. areAllFieldsSet = true;
  882. }
  883. }
  884. /**
  885. * Gets the value for a given time field.
  886. * @param field the given time field.
  887. * @return the value for the given time field.
  888. * @throws ArrayIndexOutOfBoundsException if specified field is out of range
  889. * (<tt>field < 0 || field >= FIELD_COUNT</tt>).
  890. */
  891. public int get(int field)
  892. {
  893. complete();
  894. return internalGet(field);
  895. //return fields[field];
  896. }
  897. /**
  898. * Gets the value for a given time field. This is an internal
  899. * fast time field value getter for the subclasses.
  900. * @param field the given time field.
  901. * @return the value for the given time field.
  902. */
  903. protected final int internalGet(int field)
  904. {
  905. return fields[field];
  906. }
  907. /**
  908. * Sets the value for the given time field. This is an internal
  909. * fast setter for subclasses. It does not affect the areFieldsSet, isTimeSet,
  910. * or areAllFieldsSet flags.
  911. */
  912. final void internalSet(int field, int value)
  913. {
  914. fields[field] = value;
  915. }
  916. /**
  917. * Clears the value of the given calendar field and resets the
  918. * field status flags only. The difference from clear(int) is that
  919. * this method doesn't reset isTimeSet.
  920. *
  921. * @param field the given calendar field.
  922. * @throws ArrayIndexOutOfBoundsException if specified field is out of range
  923. * (<tt>field < 0 || field >= FIELD_COUNT</tt>).
  924. */
  925. final void internalClear(int field) {
  926. fields[field] = 0;
  927. stamp[field] = UNSET;
  928. areFieldsSet = false;
  929. areAllFieldsSet = false;
  930. isSet[field] = false;
  931. }
  932. /**
  933. * Sets the time field with the given value.
  934. * @param field the given time field.
  935. * @param value the value to be set for the given time field.
  936. * @throws ArrayIndexOutOfBoundsException if specified field is out of range
  937. * (<tt>field < 0 || field >= FIELD_COUNT</tt>).
  938. */
  939. public void set(int field, int value)
  940. {
  941. isTimeSet = false;
  942. internalSet(field, value);
  943. //fields[field] = value;
  944. stamp[field] = nextStamp++;
  945. if (nextStamp == Integer.MAX_VALUE) {
  946. adjustStamp();
  947. }
  948. areFieldsSet = false;
  949. isSet[field] = true; // Remove later
  950. }
  951. /**
  952. * Sets the values for the fields year, month, and date.
  953. * Previous values of other fields are retained. If this is not desired,
  954. * call <code>clear</code> first.
  955. * @param year the value used to set the YEAR time field.
  956. * @param month the value used to set the MONTH time field.
  957. * Month value is 0-based. e.g., 0 for January.
  958. * @param date the value used to set the DATE time field.
  959. */
  960. public final void set(int year, int month, int date)
  961. {
  962. set(YEAR, year);
  963. set(MONTH, month);
  964. set(DATE, date);
  965. }
  966. /**
  967. * Sets the values for the fields year, month, date, hour, and minute.
  968. * Previous values of other fields are retained. If this is not desired,
  969. * call <code>clear</code> first.
  970. * @param year the value used to set the YEAR time field.
  971. * @param month the value used to set the MONTH time field.
  972. * Month value is 0-based. e.g., 0 for January.
  973. * @param date the value used to set the DATE time field.
  974. * @param hour the value used to set the HOUR_OF_DAY time field.
  975. * @param minute the value used to set the MINUTE time field.
  976. */
  977. public final void set(int year, int month, int date, int hour, int minute)
  978. {
  979. set(YEAR, year);
  980. set(MONTH, month);
  981. set(DATE, date);
  982. set(HOUR_OF_DAY, hour);
  983. set(MINUTE, minute);
  984. }
  985. /**
  986. * Sets the values for the fields year, month, date, hour, minute, and second.
  987. * Previous values of other fields are retained. If this is not desired,
  988. * call <code>clear</code> first.
  989. * @param year the value used to set the YEAR time field.
  990. * @param month the value used to set the MONTH time field.
  991. * Month value is 0-based. e.g., 0 for January.
  992. * @param date the value used to set the DATE time field.
  993. * @param hour the value used to set the HOUR_OF_DAY time field.
  994. * @param minute the value used to set the MINUTE time field.
  995. * @param second the value used to set the SECOND time field.
  996. */
  997. public final void set(int year, int month, int date, int hour, int minute,
  998. int second)
  999. {
  1000. set(YEAR, year);
  1001. set(MONTH, month);
  1002. set(DATE, date);
  1003. set(HOUR_OF_DAY, hour);
  1004. set(MINUTE, minute);
  1005. set(SECOND, second);
  1006. }
  1007. /**
  1008. * Clears the values of all the time fields.
  1009. */
  1010. public final void clear()
  1011. {
  1012. fields = new int[FIELD_COUNT];
  1013. stamp = new int[FIELD_COUNT];
  1014. areFieldsSet = false;
  1015. areAllFieldsSet = false;
  1016. isSet = new boolean[FIELD_COUNT]; // Remove later
  1017. isTimeSet = false;
  1018. }
  1019. /**
  1020. * Clears the value in the given time field.
  1021. * @param field the time field to be cleared.
  1022. */
  1023. public final void clear(int field)
  1024. {
  1025. fields[field] = 0;
  1026. stamp[field] = UNSET;
  1027. areFieldsSet = false;
  1028. areAllFieldsSet = false;
  1029. isSet[field] = false; // Remove later
  1030. isTimeSet = false;
  1031. }
  1032. /**
  1033. * Determines if the given time field has a value set.
  1034. * @return true if the given time field has a value set; false otherwise.
  1035. */
  1036. public final boolean isSet(int field)
  1037. {
  1038. return stamp[field] != UNSET;
  1039. // return isSet[field];
  1040. }
  1041. /**
  1042. * Fills in any unset fields in the time field list.
  1043. */
  1044. protected void complete()
  1045. {
  1046. if (!isTimeSet) updateTime();
  1047. if (!areFieldsSet) {
  1048. computeFields(); // fills in unset fields
  1049. areFieldsSet = true;
  1050. areAllFieldsSet = true;
  1051. }
  1052. }
  1053. /**
  1054. * Compares this calendar to the specified object.
  1055. * The result is <code>true</code> if and only if the argument is
  1056. * not <code>null</code> and is a <code>Calendar</code> object that
  1057. * represents the same calendar as this object.
  1058. * @param obj the object to compare with.
  1059. * @return <code>true</code> if the objects are the same;
  1060. * <code>false</code> otherwise.
  1061. */
  1062. public boolean equals(Object obj) {
  1063. if (this == obj)
  1064. return true;
  1065. if (!(obj instanceof Calendar))
  1066. return false;
  1067. Calendar that = (Calendar)obj;
  1068. return getTimeInMillis() == that.getTimeInMillis() &&
  1069. lenient == that.lenient &&
  1070. firstDayOfWeek == that.firstDayOfWeek &&
  1071. minimalDaysInFirstWeek == that.minimalDaysInFirstWeek &&
  1072. zone.equals(that.zone);
  1073. }
  1074. /**
  1075. * Returns a hash code for this calendar.
  1076. * @return a hash code value for this object.
  1077. * @since 1.2
  1078. */
  1079. public int hashCode() {
  1080. /* Don't include the time because (a) we don't want the hash value to
  1081. * move around just because a calendar is set to different times, and
  1082. * (b) we don't want to trigger a time computation just to get a hash.
  1083. * Note that it is not necessary for unequal objects to always have
  1084. * unequal hashes, but equal objects must have equal hashes. */
  1085. return (lenient ? 1 : 0)
  1086. | (firstDayOfWeek << 1)
  1087. | (minimalDaysInFirstWeek << 4)
  1088. | (zone.hashCode() << 7);
  1089. }
  1090. /**
  1091. * Compares the time field records.
  1092. * Equivalent to comparing result of conversion to UTC.
  1093. * @param when the Calendar to be compared with this Calendar.
  1094. * @return true if the current time of this Calendar is before
  1095. * the time of Calendar when; false otherwise.
  1096. */
  1097. public boolean before(Object when) {
  1098. return when instanceof Calendar &&
  1099. getTimeInMillis() < ((Calendar) when).getTimeInMillis();
  1100. }
  1101. /**
  1102. * Compares the time field records.
  1103. * Equivalent to comparing result of conversion to UTC.
  1104. * @param when the Calendar to be compared with this Calendar.
  1105. * @return true if the current time of this Calendar is after
  1106. * the time of Calendar when; false otherwise.
  1107. */
  1108. public boolean after(Object when) {
  1109. return when instanceof Calendar &&
  1110. getTimeInMillis() > ((Calendar) when).getTimeInMillis();
  1111. }
  1112. /**
  1113. * Date Arithmetic function.
  1114. * Adds the specified (signed) amount of time to the given time field,
  1115. * based on the calendar's rules. For example, to subtract 5 days from
  1116. * the current time of the calendar, you can achieve it by calling:
  1117. * <p>add(Calendar.DATE, -5).
  1118. * @param field the time field.
  1119. * @param amount the amount of date or time to be added to the field.
  1120. */
  1121. abstract public void add(int field, int amount);
  1122. /**
  1123. * Time Field Rolling function.
  1124. * Adds or subtracts (up/down) a single unit of time on the given time
  1125. * field without changing larger fields. For example, to roll the current
  1126. * date up by one day, you can achieve it by calling:
  1127. * <p>roll(Calendar.DATE, true).
  1128. * When rolling on the year or Calendar.YEAR field, it will roll the year
  1129. * value in the range between 1 and the value returned by calling
  1130. * getMaximum(Calendar.YEAR).
  1131. * When rolling on the month or Calendar.MONTH field, other fields like
  1132. * date might conflict and, need to be changed. For instance,
  1133. * rolling the month on the date 01/31/96 will result in 02/29/96.
  1134. * When rolling on the hour-in-day or Calendar.HOUR_OF_DAY field, it will
  1135. * roll the hour value in the range between 0 and 23, which is zero-based.
  1136. * @param field the time field.
  1137. * @param up indicates if the value of the specified time field is to be
  1138. * rolled up or rolled down. Use true if rolling up, false otherwise.
  1139. * @see Calendar#add
  1140. * @see Calendar#set
  1141. */
  1142. abstract public void roll(int field, boolean up);
  1143. /**
  1144. * Time Field Rolling function.
  1145. * Add to field a signed amount without changing larger fields.
  1146. * A negative roll amount means to roll down.
  1147. * [NOTE: This default implementation on Calendar just repeatedly calls the
  1148. * version of roll() that takes a boolean and rolls by one unit. This may not
  1149. * always do the right thing. For example, if the DAY_OF_MONTH field is 31,
  1150. * rolling through February will leave it set to 28. The GregorianCalendar
  1151. * version of this function takes care of this problem. Other subclasses
  1152. * should also provide overrides of this function that do the right thing.
  1153. * @param field the time field.
  1154. * @param amount the signed amount to add to <code>field</code>.
  1155. * @since 1.2
  1156. * @see Calendar#add
  1157. * @see Calendar#set
  1158. */
  1159. public void roll(int field, int amount)
  1160. {
  1161. while (amount > 0) {
  1162. roll(field, true);
  1163. amount--;
  1164. }
  1165. while (amount < 0) {
  1166. roll(field, false);
  1167. amount++;
  1168. }
  1169. }
  1170. /**
  1171. * Sets the time zone with the given time zone value.
  1172. * @param value the given time zone.
  1173. */
  1174. public void setTimeZone(TimeZone value)
  1175. {
  1176. zone = value;
  1177. /* Recompute the fields from the time using the new zone. This also
  1178. * works if isTimeSet is false (after a call to set()). In that case
  1179. * the time will be computed from the fields using the new zone, then
  1180. * the fields will get recomputed from that. Consider the sequence of
  1181. * calls: cal.setTimeZone(EST); cal.set(HOUR, 1); cal.setTimeZone(PST).
  1182. * Is cal set to 1 o'clock EST or 1 o'clock PST? Answer: PST. More
  1183. * generally, a call to setTimeZone() affects calls to set() BEFORE AND
  1184. * AFTER it up to the next call to complete().
  1185. */
  1186. areFieldsSet = false;
  1187. }
  1188. /**
  1189. * Gets the time zone.
  1190. * @return the time zone object associated with this calendar.
  1191. */
  1192. public TimeZone getTimeZone()
  1193. {
  1194. return zone;
  1195. }
  1196. /**
  1197. * Specify whether or not date/time interpretation is to be lenient. With
  1198. * lenient interpretation, a date such as "February 942, 1996" will be
  1199. * treated as being equivalent to the 941st day after February 1, 1996.
  1200. * With strict interpretation, such dates will cause an exception to be
  1201. * thrown.
  1202. *
  1203. * @see java.text.DateFormat#setLenient
  1204. */
  1205. public void setLenient(boolean lenient)
  1206. {
  1207. this.lenient = lenient;
  1208. }
  1209. /**
  1210. * Tell whether date/time interpretation is to be lenient.
  1211. */
  1212. public boolean isLenient()
  1213. {
  1214. return lenient;
  1215. }
  1216. /**
  1217. * Sets what the first day of the week is; e.g., Sunday in US,
  1218. * Monday in France.
  1219. * @param value the given first day of the week.
  1220. */
  1221. public void setFirstDayOfWeek(int value)
  1222. {
  1223. if (firstDayOfWeek == value) {
  1224. return;
  1225. }
  1226. firstDayOfWeek = value;
  1227. invalidateWeekFields();
  1228. }
  1229. /**
  1230. * Gets what the first day of the week is; e.g., Sunday in US,
  1231. * Monday in France.
  1232. * @return the first day of the week.
  1233. */
  1234. public int getFirstDayOfWeek()
  1235. {
  1236. return firstDayOfWeek;
  1237. }
  1238. /**
  1239. * Sets what the minimal days required in the first week of the year are;
  1240. * For example, if the first week is defined as one that contains the first
  1241. * day of the first month of a year, call the method with value 1. If it
  1242. * must be a full week, use value 7.
  1243. * @param value the given minimal days required in the first week
  1244. * of the year.
  1245. */
  1246. public void setMinimalDaysInFirstWeek(int value)
  1247. {
  1248. if (minimalDaysInFirstWeek == value) {
  1249. return;
  1250. }
  1251. minimalDaysInFirstWeek = value;
  1252. invalidateWeekFields();
  1253. }
  1254. /**
  1255. * Gets what the minimal days required in the first week of the year are;
  1256. * e.g., if the first week is defined as one that contains the first day
  1257. * of the first month of a year, getMinimalDaysInFirstWeek returns 1. If
  1258. * the minimal days required must be a full week, getMinimalDaysInFirstWeek
  1259. * returns 7.
  1260. * @return the minimal days required in the first week of the year.
  1261. */
  1262. public int getMinimalDaysInFirstWeek()
  1263. {
  1264. return minimalDaysInFirstWeek;
  1265. }
  1266. /**
  1267. * Gets the minimum value for the given time field.
  1268. * e.g., for Gregorian DAY_OF_MONTH, 1.
  1269. * @param field the given time field.
  1270. * @return the minimum value for the given time field.
  1271. */
  1272. abstract public int getMinimum(int field);
  1273. /**
  1274. * Gets the maximum value for the given time field.
  1275. * e.g. for Gregorian DAY_OF_MONTH, 31.
  1276. * @param field the given time field.
  1277. * @return the maximum value for the given time field.
  1278. */
  1279. abstract public int getMaximum(int field);
  1280. /**
  1281. * Gets the highest minimum value for the given field if varies.
  1282. * Otherwise same as getMinimum(). For Gregorian, no difference.
  1283. * @param field the given time field.
  1284. * @return the highest minimum value for the given time field.
  1285. */
  1286. abstract public int getGreatestMinimum(int field);
  1287. /**
  1288. * Gets the lowest maximum value for the given field if varies.
  1289. * Otherwise same as getMaximum(). e.g., for Gregorian DAY_OF_MONTH, 28.
  1290. * @param field the given time field.
  1291. * @return the lowest maximum value for the given time field.
  1292. */
  1293. abstract public int getLeastMaximum(int field);
  1294. /**
  1295. * Return the minimum value that this field could have, given the current date.
  1296. * For the Gregorian calendar, this is the same as getMinimum() and getGreatestMinimum().
  1297. *
  1298. * The version of this function on Calendar uses an iterative algorithm to determine the
  1299. * actual minimum value for the field. There is almost always a more efficient way to
  1300. * accomplish this (in most cases, you can simply return getMinimum()). GregorianCalendar
  1301. * overrides this function with a more efficient implementation.
  1302. *
  1303. * @param field the field to determine the minimum of
  1304. * @return the minimum of the given field for the current date of this Calendar
  1305. * @since 1.2
  1306. */
  1307. public int getActualMinimum(int field) {
  1308. int fieldValue = getGreatestMinimum(field);
  1309. int endValue = getMinimum(field);
  1310. // if we know that the minimum value is always the same, just return it
  1311. if (fieldValue == endValue) {
  1312. return fieldValue;
  1313. }
  1314. // clone the calendar so we don't mess with the real one, and set it to
  1315. // accept anything for the field values
  1316. Calendar work = (Calendar)this.clone();
  1317. work.setLenient(true);
  1318. // now try each value from getLeastMaximum() to getMaximum() one by one until
  1319. // we get a value that normalizes to another value. The last value that
  1320. // normalizes to itself is the actual minimum for the current date
  1321. int result = fieldValue;
  1322. do {
  1323. work.set(field, fieldValue);
  1324. if (work.get(field) != fieldValue) {
  1325. break;
  1326. } else {
  1327. result = fieldValue;
  1328. fieldValue--;
  1329. }
  1330. } while (fieldValue >= endValue);
  1331. return result;
  1332. }
  1333. /**
  1334. * Return the maximum value that this field could have, given the current date.
  1335. * For example, with the date "Feb 3, 1997" and the DAY_OF_MONTH field, the actual
  1336. * maximum would be 28; for "Feb 3, 1996" it s 29. Similarly for a Hebrew calendar,
  1337. * for some years the actual maximum for MONTH is 12, and for others 13.
  1338. *
  1339. * The version of this function on Calendar uses an iterative algorithm to determine the
  1340. * actual maximum value for the field. There is almost always a more efficient way to
  1341. * accomplish this (in most cases, you can simply return getMaximum()). GregorianCalendar
  1342. * overrides this function with a more efficient implementation.
  1343. *
  1344. * @param field the field to determine the maximum of
  1345. * @return the maximum of the given field for the current date of this Calendar
  1346. * @since 1.2
  1347. */
  1348. public int getActualMaximum(int field) {
  1349. int fieldValue = getLeastMaximum(field);
  1350. int endValue = getMaximum(field);
  1351. // if we know that the maximum value is always the same, just return it
  1352. if (fieldValue == endValue) {
  1353. return fieldValue;
  1354. }
  1355. // clone the calendar so we don't mess with the real one, and set it to
  1356. // accept anything for the field values
  1357. Calendar work = (Calendar)this.clone();
  1358. work.setLenient(true);
  1359. // if we're counting weeks, set the day of the week to Sunday. We know the
  1360. // last week of a month or year will contain the first day of the week.
  1361. if (field == WEEK_OF_YEAR || field == WEEK_OF_MONTH)
  1362. work.set(DAY_OF_WEEK, firstDayOfWeek);
  1363. // now try each value from getLeastMaximum() to getMaximum() one by one until
  1364. // we get a value that normalizes to another value. The last value that
  1365. // normalizes to itself is the actual maximum for the current date
  1366. int result = fieldValue;
  1367. do {
  1368. work.set(field, fieldValue);
  1369. if (work.get(field) != fieldValue) {
  1370. break;
  1371. } else {
  1372. result = fieldValue;
  1373. fieldValue++;
  1374. }
  1375. } while (fieldValue <= endValue);
  1376. return result;
  1377. }
  1378. /**
  1379. * Overrides Cloneable
  1380. */
  1381. public Object clone()
  1382. {
  1383. try {
  1384. Calendar other = (Calendar) super.clone();
  1385. other.fields = new int[FIELD_COUNT];
  1386. other.isSet = new boolean[FIELD_COUNT];
  1387. other.stamp = new int[FIELD_COUNT];
  1388. System.arraycopy(this.fields, 0, other.fields, 0, FIELD_COUNT);
  1389. System.arraycopy(this.isSet, 0, other.isSet, 0, FIELD_COUNT);
  1390. System.arraycopy(this.stamp, 0, other.stamp, 0, FIELD_COUNT);
  1391. other.zone = (TimeZone) zone.clone();
  1392. return other;
  1393. }
  1394. catch (CloneNotSupportedException e) {
  1395. // this shouldn't happen, since we are Cloneable
  1396. throw new InternalError();
  1397. }
  1398. }
  1399. private static final String[] FIELD_NAME = {
  1400. ",ERA=", ",YEAR=", ",MONTH=", ",WEEK_OF_YEAR=", ",WEEK_OF_MONTH=", ",DAY_OF_MONTH=",
  1401. ",DAY_OF_YEAR=", ",DAY_OF_WEEK=", ",DAY_OF_WEEK_IN_MONTH=", ",AM_PM=", ",HOUR=",
  1402. ",HOUR_OF_DAY=", ",MINUTE=", ",SECOND=", ",MILLISECOND=", ",ZONE_OFFSET=",
  1403. ",DST_OFFSET="
  1404. };
  1405. /**
  1406. * Return a string representation of this calendar. This method
  1407. * is intended to be used only for debugging purposes, and the
  1408. * format of the returned string may vary between implementations.
  1409. * The returned string may be empty but may not be <code>null</code>.
  1410. *
  1411. * @return a string representation of this calendar.
  1412. */
  1413. public String toString() {
  1414. StringBuffer buffer = new StringBuffer();
  1415. buffer.append(getClass().getName());
  1416. buffer.append("[time=");
  1417. buffer.append(isTimeSet ? String.valueOf(time) : "?");
  1418. buffer.append(",areFieldsSet=");
  1419. buffer.append(areFieldsSet);
  1420. buffer.append(",areAllFieldsSet=");
  1421. buffer.append(areAllFieldsSet);
  1422. buffer.append(",lenient=");
  1423. buffer.append(lenient);
  1424. buffer.append(",zone=");
  1425. buffer.append(zone);
  1426. buffer.append(",firstDayOfWeek=");
  1427. buffer.append(firstDayOfWeek);
  1428. buffer.append(",minimalDaysInFirstWeek=");
  1429. buffer.append(minimalDaysInFirstWeek);
  1430. for (int i=0; i<FIELD_COUNT; ++i) {
  1431. buffer.append(FIELD_NAME[i]);
  1432. buffer.append(isSet(i) ? String.valueOf(fields[i]) : "?");
  1433. }
  1434. buffer.append(']');
  1435. return buffer.toString();
  1436. }
  1437. // =======================privates===============================
  1438. /**
  1439. * Both firstDayOfWeek and minimalDaysInFirstWeek are locale-dependent.
  1440. * They are used to figure out the week count for a specific date for
  1441. * a given locale. These must be set when a Calendar is constructed.
  1442. * @param desiredLocale the given locale.
  1443. */
  1444. private void setWeekCountData(Locale desiredLocale)
  1445. {
  1446. /* try to get the Locale data from the cache */
  1447. int[] data = (int[]) cachedLocaleData.get(desiredLocale);
  1448. if (data == null) { /* cache miss */
  1449. ResourceBundle resource = LocaleData.getLocaleElements(desiredLocale);
  1450. String[] dateTimePatterns =
  1451. resource.getStringArray("DateTimeElements");
  1452. data = new int[2];
  1453. data[0] = Integer.parseInt(dateTimePatterns[0]);
  1454. data[1] = Integer.parseInt(dateTimePatterns[1]);
  1455. /* cache update */
  1456. cachedLocaleData.put(desiredLocale, data);
  1457. }
  1458. firstDayOfWeek = data[0];
  1459. minimalDaysInFirstWeek = data[1];
  1460. }
  1461. /**
  1462. * Recompute the time and update the status fields isTimeSet
  1463. * and areFieldsSet. Callers should check isTimeSet and only
  1464. * call this method if isTimeSet is false.
  1465. */
  1466. private void updateTime() {
  1467. computeTime();
  1468. // If we are lenient, we need to recompute the fields to normalize
  1469. // the values. Also, if we haven't set all the fields yet (i.e.,
  1470. // in a newly-created object), we need to fill in the fields. [LIU]
  1471. if (isLenient() || !areAllFieldsSet) areFieldsSet = false;
  1472. isTimeSet = true;
  1473. }
  1474. /**
  1475. * Adjusts the stamp[] values before nextStamp overflow. nextStamp
  1476. * is set to the next stamp value upon the return.
  1477. */
  1478. private final void adjustStamp() {
  1479. int max = MINIMUM_USER_STAMP;
  1480. int newStamp = MINIMUM_USER_STAMP;
  1481. for (;;) {
  1482. int min = Integer.MAX_VALUE;
  1483. for (int i = 0; i < stamp.length; i++) {
  1484. int v = stamp[i];
  1485. if (v >= newStamp && min > v) {
  1486. min = v;
  1487. }
  1488. if (max < v) {
  1489. max = v;
  1490. }
  1491. }
  1492. if (max != min && min == Integer.MAX_VALUE) {
  1493. break;
  1494. }
  1495. for (int i = 0; i < stamp.length; i++) {
  1496. if (stamp[i] == min) {
  1497. stamp[i] = newStamp;
  1498. }
  1499. }
  1500. newStamp++;
  1501. if (min == max) {
  1502. break;
  1503. }
  1504. }
  1505. nextStamp = newStamp;
  1506. }
  1507. /**
  1508. * Invalidates the WEEK_OF_MONTH and WEEK_OF_YEAR fields if they
  1509. * have been calculated internally.
  1510. */
  1511. private void invalidateWeekFields()
  1512. {
  1513. if (stamp[WEEK_OF_MONTH] == INTERNALLY_SET) {
  1514. stamp[WEEK_OF_MONTH] = UNSET;
  1515. isSet[WEEK_OF_MONTH] = false;
  1516. areFieldsSet = false;
  1517. }
  1518. if (stamp[WEEK_OF_YEAR] == INTERNALLY_SET) {
  1519. stamp[WEEK_OF_YEAR] = UNSET;
  1520. isSet[WEEK_OF_YEAR] = false;
  1521. areFieldsSet = false;
  1522. }
  1523. }
  1524. /**
  1525. * Save the state of this object to a stream (i.e., serialize it).
  1526. *
  1527. * Ideally, <code>Calendar</code> would only write out its state data and
  1528. * the current time, and not write any field data out, such as
  1529. * <code>fields[]</code>, <code>isTimeSet</code>, <code>areFieldsSet</code>,
  1530. * and <code>isSet[]</code>. <code>nextStamp</code> also should not be part
  1531. * of the persistent state. Unfortunately, this didn't happen before JDK 1.1
  1532. * shipped. To be compatible with JDK 1.1, we will always have to write out
  1533. * the field values and state flags. However, <code>nextStamp</code> can be
  1534. * removed from the serialization stream; this will probably happen in the
  1535. * near future.
  1536. */
  1537. private void writeObject(ObjectOutputStream stream)
  1538. throws IOException
  1539. {
  1540. // Try to compute the time correctly, for the future (stream
  1541. // version 2) in which we don't write out fields[] or isSet[].
  1542. if (!isTimeSet) {
  1543. try {
  1544. updateTime();
  1545. }
  1546. catch (IllegalArgumentException e) {}
  1547. }
  1548. // If this Calendar has a ZoneInfo, save it and set a
  1549. // SimpleTimeZone equvalent (as a single DST schedule) for
  1550. // backward compatibility.
  1551. TimeZone savedZone = null;
  1552. if (zone instanceof ZoneInfo) {
  1553. SimpleTimeZone stz = ((ZoneInfo)zone).getLastRuleInstance();
  1554. if (stz == null) {
  1555. stz = new SimpleTimeZone(zone.getRawOffset(), zone.getID());
  1556. }
  1557. savedZone = zone;
  1558. zone = stz;
  1559. }
  1560. // Write out the 1.1 FCS object.
  1561. stream.defaultWriteObject();
  1562. // Write out the ZoneInfo object
  1563. // 4802409: we write out even if it is null, a temporary workaround
  1564. // the real fix for bug 4844924 in corba-iiop
  1565. stream.writeObject(savedZone);
  1566. if (savedZone != null) {
  1567. zone = savedZone;
  1568. }
  1569. }
  1570. /**
  1571. * Reconstitute this object from a stream (i.e., deserialize it).
  1572. */
  1573. private void readObject(ObjectInputStream stream)
  1574. throws IOException, ClassNotFoundException
  1575. {
  1576. stream.defaultReadObject();
  1577. stamp = new int[FIELD_COUNT];
  1578. // Starting with version 2 (not implemented yet), we expect that
  1579. // fields[], isSet[], isTimeSet, and areFieldsSet may not be
  1580. // streamed out anymore. We expect 'time' to be correct.
  1581. if (serialVersionOnStream >= 2)
  1582. {
  1583. isTimeSet = true;
  1584. if (fields == null) fields = new int[FIELD_COUNT];
  1585. if (isSet == null) isSet = new boolean[FIELD_COUNT];
  1586. }
  1587. else if (serialVersionOnStream >= 0)
  1588. {
  1589. for (int i=0; i<FIELD_COUNT; ++i)
  1590. stamp[i] = isSet[i] ? INTERNALLY_SET : UNSET;
  1591. }
  1592. serialVersionOnStream = currentSerialVersion;
  1593. // If there's a ZoneInfo object, use it for zone.
  1594. try {
  1595. ZoneInfo zi = (ZoneInfo) stream.readObject();
  1596. if (zi != null) {
  1597. zone = zi;
  1598. }
  1599. } catch (Exception e) {
  1600. }
  1601. // If the deserialized object has a SimpleTimeZone, try to
  1602. // replace it with a ZoneInfo equivalent (as of 1.4) in order
  1603. // to be compatible with the SimpleTimeZone-based
  1604. // implementation as much as possible.
  1605. TimeZone tz = getTimeZone();
  1606. if (tz instanceof SimpleTimeZone) {
  1607. String id = tz.getID();
  1608. TimeZone zi = TimeZone.getTimeZone(id);
  1609. if (zi != null && zi.hasSameRules(tz) && zi.getID().equals(id)) {
  1610. setTimeZone(zi);
  1611. }
  1612. }
  1613. }
  1614. }