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