1 /* 2 * Copyright (C) 1996-2015, International Business Machines 3 * Corporation and others. All Rights Reserved. 4 */ 5 6 package com.ibm.icu.util; 7 8 import java.io.IOException; 9 import java.io.ObjectInputStream; 10 import java.io.ObjectOutputStream; 11 import java.io.Serializable; 12 import java.text.StringCharacterIterator; 13 import java.util.ArrayList; 14 import java.util.Date; 15 import java.util.Locale; 16 import java.util.MissingResourceException; 17 18 import com.ibm.icu.impl.CalendarData; 19 import com.ibm.icu.impl.CalendarUtil; 20 import com.ibm.icu.impl.ICUCache; 21 import com.ibm.icu.impl.ICUResourceBundle; 22 import com.ibm.icu.impl.SimpleCache; 23 import com.ibm.icu.impl.SoftCache; 24 import com.ibm.icu.text.DateFormat; 25 import com.ibm.icu.text.DateFormatSymbols; 26 import com.ibm.icu.text.MessageFormat; 27 import com.ibm.icu.text.SimpleDateFormat; 28 import com.ibm.icu.util.ULocale.Category; 29 30 /** 31 * {@icuenhanced java.util.Calendar}.{@icu _usage_} 32 * 33 * <p><code>Calendar</code> is an abstract base class for converting between 34 * a <code>Date</code> object and a set of integer fields such as 35 * <code>YEAR</code>, <code>MONTH</code>, <code>DAY</code>, <code>HOUR</code>, 36 * and so on. (A <code>Date</code> object represents a specific instant in 37 * time with millisecond precision. See 38 * {@link Date} 39 * for information about the <code>Date</code> class.) 40 * 41 * <p>Subclasses of <code>Calendar</code> interpret a <code>Date</code> 42 * according to the rules of a specific calendar system. ICU4J contains 43 * several subclasses implementing different international calendar systems. 44 * 45 * <p> 46 * Like other locale-sensitive classes, <code>Calendar</code> provides a 47 * class method, <code>getInstance</code>, for getting a generally useful 48 * object of this type. <code>Calendar</code>'s <code>getInstance</code> method 49 * returns a calendar of a type appropriate to the locale, whose 50 * time fields have been initialized with the current date and time: 51 * <blockquote> 52 * <pre>Calendar rightNow = Calendar.getInstance()</pre> 53 * </blockquote> 54 * 55 * <p>When a <code>ULocale</code> is used by <code>getInstance</code>, its 56 * '<code>calendar</code>' tag and value are retrieved if present. If a recognized 57 * value is supplied, a calendar is provided and configured as appropriate. 58 * Currently recognized tags are "buddhist", "chinese", "coptic", "ethiopic", 59 * "gregorian", "hebrew", "islamic", "islamic-civil", "japanese", and "roc". For 60 * example: <blockquote> 61 * <pre>Calendar cal = Calendar.getInstance(new ULocale("en_US@calendar=japanese"));</pre> 62 * </blockquote> will return an instance of JapaneseCalendar (using en_US conventions for 63 * minimum days in first week, start day of week, et cetera). 64 * 65 * <p>A <code>Calendar</code> object can produce all the time field values 66 * needed to implement the date-time formatting for a particular language and 67 * calendar style (for example, Japanese-Gregorian, Japanese-Traditional). 68 * <code>Calendar</code> defines the range of values returned by certain fields, 69 * as well as their meaning. For example, the first month of the year has value 70 * <code>MONTH</code> == <code>JANUARY</code> for all calendars. Other values 71 * are defined by the concrete subclass, such as <code>ERA</code> and 72 * <code>YEAR</code>. See individual field documentation and subclass 73 * documentation for details. 74 * 75 * <p>When a <code>Calendar</code> is <em>lenient</em>, it accepts a wider range 76 * of field values than it produces. For example, a lenient 77 * <code>GregorianCalendar</code> interprets <code>MONTH</code> == 78 * <code>JANUARY</code>, <code>DAY_OF_MONTH</code> == 32 as February 1. A 79 * non-lenient <code>GregorianCalendar</code> throws an exception when given 80 * out-of-range field settings. When calendars recompute field values for 81 * return by <code>get()</code>, they normalize them. For example, a 82 * <code>GregorianCalendar</code> always produces <code>DAY_OF_MONTH</code> 83 * values between 1 and the length of the month. 84 * 85 * <p><code>Calendar</code> defines a locale-specific seven day week using two 86 * parameters: the first day of the week and the minimal days in first week 87 * (from 1 to 7). These numbers are taken from the locale resource data when a 88 * <code>Calendar</code> is constructed. They may also be specified explicitly 89 * through the API. 90 * 91 * <p>When setting or getting the <code>WEEK_OF_MONTH</code> or 92 * <code>WEEK_OF_YEAR</code> fields, <code>Calendar</code> must determine the 93 * first week of the month or year as a reference point. The first week of a 94 * month or year is defined as the earliest seven day period beginning on 95 * <code>getFirstDayOfWeek()</code> and containing at least 96 * <code>getMinimalDaysInFirstWeek()</code> days of that month or year. Weeks 97 * numbered ..., -1, 0 precede the first week; weeks numbered 2, 3,... follow 98 * it. Note that the normalized numbering returned by <code>get()</code> may be 99 * different. For example, a specific <code>Calendar</code> subclass may 100 * designate the week before week 1 of a year as week <em>n</em> of the previous 101 * year. 102 * 103 * <p> When computing a <code>Date</code> from time fields, some special 104 * circumstances may arise: there may be insufficient information to compute the 105 * <code>Date</code> (such as only year and month but no day in the month), 106 * there may be inconsistent information (such as "Tuesday, July 15, 1996" -- 107 * July 15, 1996 is actually a Monday), or the input time might be ambiguous 108 * because of time zone transition. 109 * 110 * <p><strong>Insufficient information.</strong> The calendar will use default 111 * information to specify the missing fields. This may vary by calendar; for 112 * the Gregorian calendar, the default for a field is the same as that of the 113 * start of the epoch: i.e., YEAR = 1970, MONTH = JANUARY, DATE = 1, etc. 114 * 115 * <p><strong>Inconsistent information.</strong> If fields conflict, the calendar 116 * will give preference to fields set more recently. For example, when 117 * determining the day, the calendar will look for one of the following 118 * combinations of fields. The most recent combination, as determined by the 119 * most recently set single field, will be used. 120 * 121 * <blockquote> 122 * <pre> 123 * MONTH + DAY_OF_MONTH 124 * MONTH + WEEK_OF_MONTH + DAY_OF_WEEK 125 * MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK 126 * DAY_OF_YEAR 127 * DAY_OF_WEEK + WEEK_OF_YEAR</pre> 128 * </blockquote> 129 * 130 * For the time of day: 131 * 132 * <blockquote> 133 * <pre> 134 * HOUR_OF_DAY 135 * AM_PM + HOUR</pre> 136 * </blockquote> 137 * 138 * <p><strong>Ambiguous Wall Clock Time.</strong> When time offset from UTC has 139 * changed, it produces an ambiguous time slot around the transition. For example, 140 * many US locations observe daylight saving time. On the date switching to daylight 141 * saving time in US, wall clock time jumps from 12:59 AM (standard) to 2:00 AM 142 * (daylight). Therefore, wall clock time from 1:00 AM to 1:59 AM do not exist on 143 * the date. When the input wall time fall into this missing time slot, the ICU 144 * Calendar resolves the time using the UTC offset before the transition by default. 145 * In this example, 1:30 AM is interpreted as 1:30 AM standard time (non-exist), 146 * so the final result will be 2:30 AM daylight time. 147 * 148 * <p>On the date switching back to standard time, wall clock time is moved back one 149 * hour at 2:00 AM. So wall clock time from 1:00 AM to 1:59 AM occur twice. In this 150 * case, the ICU Calendar resolves the time using the UTC offset after the transition 151 * by default. For example, 1:30 AM on the date is resolved as 1:30 AM standard time. 152 * 153 * <p>Ambiguous wall clock time resolution behaviors can be customized by Calendar APIs 154 * {@link #setRepeatedWallTimeOption(int)} and {@link #setSkippedWallTimeOption(int)}. 155 * These methods are available in ICU 49 or later versions. 156 * 157 * <p><strong>Note:</strong> for some non-Gregorian calendars, different 158 * fields may be necessary for complete disambiguation. For example, a full 159 * specification of the historial Arabic astronomical calendar requires year, 160 * month, day-of-month <em>and</em> day-of-week in some cases. 161 * 162 * <p><strong>Note:</strong> There are certain possible ambiguities in 163 * interpretation of certain singular times, which are resolved in the 164 * following ways: 165 * <ol> 166 * <li> 24:00:00 "belongs" to the following day. That is, 167 * 23:59 on Dec 31, 1969 < 24:00 on Jan 1, 1970 < 24:01:00 on Jan 1, 1970 168 * 169 * <li> Although historically not precise, midnight also belongs to "am", 170 * and noon belongs to "pm", so on the same day, 171 * 12:00 am (midnight) < 12:01 am, and 12:00 pm (noon) < 12:01 pm 172 * </ol> 173 * 174 * <p>The date or time format strings are not part of the definition of a 175 * calendar, as those must be modifiable or overridable by the user at 176 * runtime. Use {@link DateFormat} 177 * to format dates. 178 * 179 * <p><strong>Field manipulation methods</strong></p> 180 * 181 * <p><code>Calendar</code> fields can be changed using three methods: 182 * <code>set()</code>, <code>add()</code>, and <code>roll()</code>.</p> 183 * 184 * <p><strong><code>set(f, value)</code></strong> changes field 185 * <code>f</code> to <code>value</code>. In addition, it sets an 186 * internal member variable to indicate that field <code>f</code> has 187 * been changed. Although field <code>f</code> is changed immediately, 188 * the calendar's milliseconds is not recomputed until the next call to 189 * <code>get()</code>, <code>getTime()</code>, or 190 * <code>getTimeInMillis()</code> is made. Thus, multiple calls to 191 * <code>set()</code> do not trigger multiple, unnecessary 192 * computations. As a result of changing a field using 193 * <code>set()</code>, other fields may also change, depending on the 194 * field, the field value, and the calendar system. In addition, 195 * <code>get(f)</code> will not necessarily return <code>value</code> 196 * after the fields have been recomputed. The specifics are determined by 197 * the concrete calendar class.</p> 198 * 199 * <p><em>Example</em>: Consider a <code>GregorianCalendar</code> 200 * originally set to August 31, 1999. Calling <code>set(Calendar.MONTH, 201 * Calendar.SEPTEMBER)</code> sets the calendar to September 31, 202 * 1999. This is a temporary internal representation that resolves to 203 * October 1, 1999 if <code>getTime()</code>is then called. However, a 204 * call to <code>set(Calendar.DAY_OF_MONTH, 30)</code> before the call to 205 * <code>getTime()</code> sets the calendar to September 30, 1999, since 206 * no recomputation occurs after <code>set()</code> itself.</p> 207 * 208 * <p><strong><code>add(f, delta)</code></strong> adds <code>delta</code> 209 * to field <code>f</code>. This is equivalent to calling <code>set(f, 210 * get(f) + delta)</code> with two adjustments:</p> 211 * 212 * <blockquote> 213 * <p><strong>Add rule 1</strong>. The value of field <code>f</code> 214 * after the call minus the value of field <code>f</code> before the 215 * call is <code>delta</code>, modulo any overflow that has occurred in 216 * field <code>f</code>. Overflow occurs when a field value exceeds its 217 * range and, as a result, the next larger field is incremented or 218 * decremented and the field value is adjusted back into its range.</p> 219 * 220 * <p><strong>Add rule 2</strong>. If a smaller field is expected to be 221 * invariant, but it is impossible for it to be equal to its 222 * prior value because of changes in its minimum or maximum after field 223 * <code>f</code> is changed, then its value is adjusted to be as close 224 * as possible to its expected value. A smaller field represents a 225 * smaller unit of time. <code>HOUR</code> is a smaller field than 226 * <code>DAY_OF_MONTH</code>. No adjustment is made to smaller fields 227 * that are not expected to be invariant. The calendar system 228 * determines what fields are expected to be invariant.</p> 229 * </blockquote> 230 * 231 * <p>In addition, unlike <code>set()</code>, <code>add()</code> forces 232 * an immediate recomputation of the calendar's milliseconds and all 233 * fields.</p> 234 * 235 * <p><em>Example</em>: Consider a <code>GregorianCalendar</code> 236 * originally set to August 31, 1999. Calling <code>add(Calendar.MONTH, 237 * 13)</code> sets the calendar to September 30, 2000. <strong>Add rule 238 * 1</strong> sets the <code>MONTH</code> field to September, since 239 * adding 13 months to August gives September of the next year. Since 240 * <code>DAY_OF_MONTH</code> cannot be 31 in September in a 241 * <code>GregorianCalendar</code>, <strong>add rule 2</strong> sets the 242 * <code>DAY_OF_MONTH</code> to 30, the closest possible value. Although 243 * it is a smaller field, <code>DAY_OF_WEEK</code> is not adjusted by 244 * rule 2, since it is expected to change when the month changes in a 245 * <code>GregorianCalendar</code>.</p> 246 * 247 * <p><strong><code>roll(f, delta)</code></strong> adds 248 * <code>delta</code> to field <code>f</code> without changing larger 249 * fields. This is equivalent to calling <code>add(f, delta)</code> with 250 * the following adjustment:</p> 251 * 252 * <blockquote> 253 * <p><strong>Roll rule</strong>. Larger fields are unchanged after the 254 * call. A larger field represents a larger unit of 255 * time. <code>DAY_OF_MONTH</code> is a larger field than 256 * <code>HOUR</code>.</p> 257 * </blockquote> 258 * 259 * <p><em>Example</em>: Consider a <code>GregorianCalendar</code> 260 * originally set to August 31, 1999. Calling <code>roll(Calendar.MONTH, 261 * 8)</code> sets the calendar to April 30, <strong>1999</strong>. Add 262 * rule 1 sets the <code>MONTH</code> field to April. Using a 263 * <code>GregorianCalendar</code>, the <code>DAY_OF_MONTH</code> cannot 264 * be 31 in the month April. Add rule 2 sets it to the closest possible 265 * value, 30. Finally, the <strong>roll rule</strong> maintains the 266 * <code>YEAR</code> field value of 1999.</p> 267 * 268 * <p><em>Example</em>: Consider a <code>GregorianCalendar</code> 269 * originally set to Sunday June 6, 1999. Calling 270 * <code>roll(Calendar.WEEK_OF_MONTH, -1)</code> sets the calendar to 271 * Tuesday June 1, 1999, whereas calling 272 * <code>add(Calendar.WEEK_OF_MONTH, -1)</code> sets the calendar to 273 * Sunday May 30, 1999. This is because the roll rule imposes an 274 * additional constraint: The <code>MONTH</code> must not change when the 275 * <code>WEEK_OF_MONTH</code> is rolled. Taken together with add rule 1, 276 * the resultant date must be between Tuesday June 1 and Saturday June 277 * 5. According to add rule 2, the <code>DAY_OF_WEEK</code>, an invariant 278 * when changing the <code>WEEK_OF_MONTH</code>, is set to Tuesday, the 279 * closest possible value to Sunday (where Sunday is the first day of the 280 * week).</p> 281 * 282 * <p><strong>Usage model</strong>. To motivate the behavior of 283 * <code>add()</code> and <code>roll()</code>, consider a user interface 284 * component with increment and decrement buttons for the month, day, and 285 * year, and an underlying <code>GregorianCalendar</code>. If the 286 * interface reads January 31, 1999 and the user presses the month 287 * increment button, what should it read? If the underlying 288 * implementation uses <code>set()</code>, it might read March 3, 1999. A 289 * better result would be February 28, 1999. Furthermore, if the user 290 * presses the month increment button again, it should read March 31, 291 * 1999, not March 28, 1999. By saving the original date and using either 292 * <code>add()</code> or <code>roll()</code>, depending on whether larger 293 * fields should be affected, the user interface can behave as most users 294 * will intuitively expect.</p> 295 * 296 * <p><b>Note:</b> You should always use {@link #roll roll} and {@link #add add} rather 297 * than attempting to perform arithmetic operations directly on the fields 298 * of a <tt>Calendar</tt>. It is quite possible for <tt>Calendar</tt> subclasses 299 * to have fields with non-linear behavior, for example missing months 300 * or days during non-leap years. The subclasses' <tt>add</tt> and <tt>roll</tt> 301 * methods will take this into account, while simple arithmetic manipulations 302 * may give invalid results. 303 * 304 * <p><big><big><b>Calendar Architecture in ICU4J</b></big></big></p> 305 * 306 * <p>Recently the implementation of <code>Calendar</code> has changed 307 * significantly in order to better support subclassing. The original 308 * <code>Calendar</code> class was designed to support subclassing, but 309 * it had only one implemented subclass, <code>GregorianCalendar</code>. 310 * With the implementation of several new calendar subclasses, including 311 * the <code>BuddhistCalendar</code>, <code>ChineseCalendar</code>, 312 * <code>HebrewCalendar</code>, <code>IslamicCalendar</code>, and 313 * <code>JapaneseCalendar</code>, the subclassing API has been reworked 314 * thoroughly. This section details the new subclassing API and other 315 * ways in which <code>com.ibm.icu.util.Calendar</code> differs from 316 * <code>java.util.Calendar</code>. 317 * </p> 318 * 319 * <p><big><b>Changes</b></big></p> 320 * 321 * <p>Overview of changes between the classic <code>Calendar</code> 322 * architecture and the new architecture. 323 * 324 * <ul> 325 * 326 * <li>The <code>fields[]</code> array is <code>private</code> now 327 * instead of <code>protected</code>. Subclasses must access it 328 * using the methods {@link #internalSet} and 329 * {@link #internalGet}. <b>Motivation:</b> Subclasses should 330 * not directly access data members.</li> 331 * 332 * <li>The <code>time</code> long word is <code>private</code> now 333 * instead of <code>protected</code>. Subclasses may access it using 334 * the method {@link #internalGetTimeInMillis}, which does not 335 * provoke an update. <b>Motivation:</b> Subclasses should not 336 * directly access data members.</li> 337 * 338 * <li>The scope of responsibility of subclasses has been drastically 339 * reduced. As much functionality as possible is implemented in the 340 * <code>Calendar</code> base class. As a result, it is much easier 341 * to subclass <code>Calendar</code>. <b>Motivation:</b> Subclasses 342 * should not have to reimplement common code. Certain behaviors are 343 * common across calendar systems: The definition and behavior of 344 * week-related fields and time fields, the arithmetic 345 * ({@link #add(int, int) add} and {@link #roll(int, int) roll}) behavior of many 346 * fields, and the field validation system.</li> 347 * 348 * <li>The subclassing API has been completely redesigned.</li> 349 * 350 * <li>The <code>Calendar</code> base class contains some Gregorian 351 * calendar algorithmic support that subclasses can use (specifically 352 * in {@link #handleComputeFields}). Subclasses can use the 353 * methods <code>getGregorianXxx()</code> to obtain precomputed 354 * values. <b>Motivation:</b> This is required by all 355 * <code>Calendar</code> subclasses in order to implement consistent 356 * time zone behavior, and Gregorian-derived systems can use the 357 * already computed data.</li> 358 * 359 * <li>The <code>FIELD_COUNT</code> constant has been removed. Use 360 * {@link #getFieldCount}. In addition, framework API has been 361 * added to allow subclasses to define additional fields. 362 * <b>Motivation: </b>The number of fields is not constant across 363 * calendar systems.</li> 364 * 365 * <li>The range of handled dates has been narrowed from +/- 366 * ~300,000,000 years to +/- ~5,000,000 years. In practical terms 367 * this should not affect clients. However, it does mean that client 368 * code cannot be guaranteed well-behaved results with dates such as 369 * <code>Date(Long.MIN_VALUE)</code> or 370 * <code>Date(Long.MAX_VALUE)</code>. Instead, the 371 * <code>Calendar</code> protected constants should be used. 372 * <b>Motivation:</b> With 373 * the addition of the {@link #JULIAN_DAY} field, Julian day 374 * numbers must be restricted to a 32-bit <code>int</code>. This 375 * restricts the overall supported range. Furthermore, restricting 376 * the supported range simplifies the computations by removing 377 * special case code that was used to accomodate arithmetic overflow 378 * at millis near <code>Long.MIN_VALUE</code> and 379 * <code>Long.MAX_VALUE</code>.</li> 380 * 381 * <li>New fields are implemented: {@link #JULIAN_DAY} defines 382 * single-field specification of the 383 * date. {@link #MILLISECONDS_IN_DAY} defines a single-field 384 * specification of the wall time. {@link #DOW_LOCAL} and 385 * {@link #YEAR_WOY} implement localized day-of-week and 386 * week-of-year behavior.</li> 387 * 388 * <li>Subclasses can access protected millisecond constants 389 * defined in <code>Calendar</code>.</li> 390 * 391 * <li>New API has been added to support calendar-specific subclasses 392 * of <code>DateFormat</code>.</li> 393 * 394 * <li>Several subclasses have been implemented, representing 395 * various international calendar systems.</li> 396 * 397 * </ul> 398 * 399 * <p><big><b>Subclass API</b></big></p> 400 * 401 * <p>The original <code>Calendar</code> API was based on the experience 402 * of implementing a only a single subclass, 403 * <code>GregorianCalendar</code>. As a result, all of the subclassing 404 * kinks had not been worked out. The new subclassing API has been 405 * refined based on several implemented subclasses. This includes methods 406 * that must be overridden and methods for subclasses to call. Subclasses 407 * no longer have direct access to <code>fields</code> and 408 * <code>stamp</code>. Instead, they have new API to access 409 * these. Subclasses are able to allocate the <code>fields</code> array 410 * through a protected framework method; this allows subclasses to 411 * specify additional fields. </p> 412 * 413 * <p>More functionality has been moved into the base class. The base 414 * class now contains much of the computational machinery to support the 415 * Gregorian calendar. This is based on two things: (1) Many calendars 416 * are based on the Gregorian calendar (such as the Buddhist and Japanese 417 * imperial calendars). (2) <em>All</em> calendars require basic 418 * Gregorian support in order to handle timezone computations. </p> 419 * 420 * <p>Common computations have been moved into 421 * <code>Calendar</code>. Subclasses no longer compute the week related 422 * fields and the time related fields. These are commonly handled for all 423 * calendars by the base class. </p> 424 * 425 * <p><b>Subclass computation of time <tt>=></tt> fields</b> 426 * 427 * <p>The {@link #ERA}, {@link #YEAR}, 428 * {@link #EXTENDED_YEAR}, {@link #MONTH}, 429 * {@link #DAY_OF_MONTH}, and {@link #DAY_OF_YEAR} fields are 430 * computed by the subclass, based on the Julian day. All other fields 431 * are computed by <code>Calendar</code>. 432 * 433 * <ul> 434 * 435 * <li>Subclasses should implement {@link #handleComputeFields} 436 * to compute the {@link #ERA}, {@link #YEAR}, 437 * {@link #EXTENDED_YEAR}, {@link #MONTH}, 438 * {@link #DAY_OF_MONTH}, and {@link #DAY_OF_YEAR} fields, 439 * based on the value of the {@link #JULIAN_DAY} field. If there 440 * are calendar-specific fields not defined by <code>Calendar</code>, 441 * they must also be computed. These are the only fields that the 442 * subclass should compute. All other fields are computed by the base 443 * class, so time and week fields behave in a consistent way across 444 * all calendars. The default version of this method in 445 * <code>Calendar</code> implements a proleptic Gregorian 446 * calendar. Within this method, subclasses may call 447 * <code>getGregorianXxx()</code> to obtain the Gregorian calendar 448 * month, day of month, and extended year for the given date.</li> 449 * 450 * </ul> 451 * 452 * <p><b>Subclass computation of fields <tt>=></tt> time</b> 453 * 454 * <p>The interpretation of most field values is handled entirely by 455 * <code>Calendar</code>. <code>Calendar</code> determines which fields 456 * are set, which are not, which are set more recently, and so on. In 457 * addition, <code>Calendar</code> handles the computation of the time 458 * from the time fields and handles the week-related fields. The only 459 * thing the subclass must do is determine the extended year, based on 460 * the year fields, and then, given an extended year and a month, it must 461 * return a Julian day number. 462 * 463 * <ul> 464 * 465 * <li>Subclasses should implement {@link #handleGetExtendedYear} 466 * to return the extended year for this calendar system, based on the 467 * {@link #YEAR}, {@link #EXTENDED_YEAR}, and any fields that 468 * the calendar system uses that are larger than a year, such as 469 * {@link #ERA}.</li> 470 * 471 * <li>Subclasses should implement {@link #handleComputeMonthStart} 472 * to return the Julian day number 473 * associated with a month and extended year. This is the Julian day 474 * number of the day before the first day of the month. The month 475 * number is zero-based. This computation should not depend on any 476 * field values.</li> 477 * 478 * </ul> 479 * 480 * <p><b>Other methods</b> 481 * 482 * <ul> 483 * 484 * <li>Subclasses should implement {@link #handleGetMonthLength} 485 * to return the number of days in a 486 * given month of a given extended year. The month number, as always, 487 * is zero-based.</li> 488 * 489 * <li>Subclasses should implement {@link #handleGetYearLength} 490 * to return the number of days in the given 491 * extended year. This method is used by 492 * <tt>computeWeekFields</tt> to compute the 493 * {@link #WEEK_OF_YEAR} and {@link #YEAR_WOY} fields.</li> 494 * 495 * <li>Subclasses should implement {@link #handleGetLimit} 496 * to return the protected values of a field, depending on the value of 497 * <code>limitType</code>. This method only needs to handle the 498 * fields {@link #ERA}, {@link #YEAR}, {@link #MONTH}, 499 * {@link #WEEK_OF_YEAR}, {@link #WEEK_OF_MONTH}, 500 * {@link #DAY_OF_MONTH}, {@link #DAY_OF_YEAR}, 501 * {@link #DAY_OF_WEEK_IN_MONTH}, {@link #YEAR_WOY}, and 502 * {@link #EXTENDED_YEAR}. Other fields are invariant (with 503 * respect to calendar system) and are handled by the base 504 * class.</li> 505 * 506 * <li>Optionally, subclasses may override {@link #validateField} 507 * to check any subclass-specific fields. If the 508 * field's value is out of range, the method should throw an 509 * <code>IllegalArgumentException</code>. The method may call 510 * <code>super.validateField(field)</code> to handle fields in a 511 * generic way, that is, to compare them to the range 512 * <code>getMinimum(field)</code>..<code>getMaximum(field)</code>.</li> 513 * 514 * <li>Optionally, subclasses may override 515 * {@link #handleCreateFields} to create an <code>int[]</code> 516 * array large enough to hold the calendar's fields. This is only 517 * necessary if the calendar defines additional fields beyond those 518 * defined by <code>Calendar</code>. The length of the result must be 519 * be between the base and maximum field counts.</li> 520 * 521 * <li>Optionally, subclasses may override 522 * {@link #handleGetDateFormat} to create a 523 * <code>DateFormat</code> appropriate to this calendar. This is only 524 * required if a calendar subclass redefines the use of a field (for 525 * example, changes the {@link #ERA} field from a symbolic field 526 * to a numeric one) or defines an additional field.</li> 527 * 528 * <li>Optionally, subclasses may override {@link #roll roll} and 529 * {@link #add add} to handle fields that are discontinuous. For 530 * example, in the Hebrew calendar the month "Adar I" only 531 * occurs in leap years; in other years the calendar jumps from 532 * Shevat (month #4) to Adar (month #6). The {@link 533 * HebrewCalendar#add HebrewCalendar.add} and {@link 534 * HebrewCalendar#roll HebrewCalendar.roll} methods take this into 535 * account, so that adding 1 month to Shevat gives the proper result 536 * (Adar) in a non-leap year. The protected utility method {@link 537 * #pinField pinField} is often useful when implementing these two 538 * methods. </li> 539 * 540 * </ul> 541 * 542 * <p><big><b>Normalized behavior</b></big> 543 * 544 * <p>The behavior of certain fields has been made consistent across all 545 * calendar systems and implemented in <code>Calendar</code>. 546 * 547 * <ul> 548 * 549 * <li>Time is normalized. Even though some calendar systems transition 550 * between days at sunset or at other times, all ICU4J calendars 551 * transition between days at <em>local zone midnight</em>. This 552 * allows ICU4J to centralize the time computations in 553 * <code>Calendar</code> and to maintain basic correpsondences 554 * between calendar systems. Affected fields: {@link #AM_PM}, 555 * {@link #HOUR}, {@link #HOUR_OF_DAY}, {@link #MINUTE}, 556 * {@link #SECOND}, {@link #MILLISECOND}, 557 * {@link #ZONE_OFFSET}, and {@link #DST_OFFSET}.</li> 558 * 559 * <li>DST behavior is normalized. Daylight savings time behavior is 560 * computed the same for all calendar systems, and depends on the 561 * value of several <code>GregorianCalendar</code> fields: the 562 * {@link #YEAR}, {@link #MONTH}, and 563 * {@link #DAY_OF_MONTH}. As a result, <code>Calendar</code> 564 * always computes these fields, even for non-Gregorian calendar 565 * systems. These fields are available to subclasses.</li> 566 * 567 * <li>Weeks are normalized. Although locales define the week 568 * differently, in terms of the day on which it starts, and the 569 * designation of week number one of a month or year, they all use a 570 * common mechanism. Furthermore, the day of the week has a simple 571 * and consistent definition throughout history. For example, 572 * although the Gregorian calendar introduced a discontinuity when 573 * first instituted, the day of week was not disrupted. For this 574 * reason, the fields {@link #DAY_OF_WEEK}, <code>WEEK_OF_YEAR, 575 * WEEK_OF_MONTH</code>, {@link #DAY_OF_WEEK_IN_MONTH}, 576 * {@link #DOW_LOCAL}, {@link #YEAR_WOY} are all computed in 577 * a consistent way in the base class, based on the 578 * {@link #EXTENDED_YEAR}, {@link #DAY_OF_YEAR}, 579 * {@link #MONTH}, and {@link #DAY_OF_MONTH}, which are 580 * computed by the subclass.</li> 581 * 582 * </ul> 583 * 584 * <p><big><b>Supported range</b></big> 585 * 586 * <p>The allowable range of <code>Calendar</code> has been 587 * narrowed. <code>GregorianCalendar</code> used to attempt to support 588 * the range of dates with millisecond values from 589 * <code>Long.MIN_VALUE</code> to <code>Long.MAX_VALUE</code>. This 590 * introduced awkward constructions (hacks) which slowed down 591 * performance. It also introduced non-uniform behavior at the 592 * boundaries. The new <code>Calendar</code> protocol specifies the 593 * maximum range of supportable dates as those having Julian day numbers 594 * of <code>-0x7F000000</code> to <code>+0x7F000000</code>. This 595 * corresponds to years from ~5,800,000 BCE to ~5,800,000 CE. Programmers 596 * should use the protected constants in <code>Calendar</code> to 597 * specify an extremely early or extremely late date.</p> 598 * 599 * <p><big><b>General notes</b></big> 600 * 601 * <ul> 602 * 603 * <li>Calendars implementations are <em>proleptic</em>. For example, 604 * even though the Gregorian calendar was not instituted until the 605 * 16th century, the <code>GregorianCalendar</code> class supports 606 * dates before the historical onset of the calendar by extending the 607 * calendar system backward in time. Similarly, the 608 * <code>HebrewCalendar</code> extends backward before the start of 609 * its epoch into zero and negative years. Subclasses do not throw 610 * exceptions because a date precedes the historical start of a 611 * calendar system. Instead, they implement 612 * {@link #handleGetLimit} to return appropriate limits on 613 * {@link #YEAR}, {@link #ERA}, etc. fields. Then, if the 614 * calendar is set to not be lenient, out-of-range field values will 615 * trigger an exception.</li> 616 * 617 * <li>Calendar system subclasses compute a <em>extended 618 * year</em>. This differs from the {@link #YEAR} field in that 619 * it ranges over all integer values, including zero and negative 620 * values, and it encapsulates the information of the 621 * {@link #YEAR} field and all larger fields. Thus, for the 622 * Gregorian calendar, the {@link #EXTENDED_YEAR} is computed as 623 * <code>ERA==AD ? YEAR : 1-YEAR</code>. Another example is the Mayan 624 * long count, which has years (<code>KUN</code>) and nested cycles 625 * of years (<code>KATUN</code> and <code>BAKTUN</code>). The Mayan 626 * {@link #EXTENDED_YEAR} is computed as <code>TUN + 20 * (KATUN 627 * + 20 * BAKTUN)</code>. The <code>Calendar</code> base class uses 628 * the {@link #EXTENDED_YEAR} field to compute the week-related 629 * fields.</li> 630 * 631 * </ul> 632 * 633 * @see Date 634 * @see GregorianCalendar 635 * @see TimeZone 636 * @see DateFormat 637 * @author Mark Davis, David Goldsmith, Chen-Lieh Huang, Alan Liu, Laura Werner 638 * @stable ICU 2.0 639 */ 640 public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar> { 641 642 // Data flow in Calendar 643 // --------------------- 644 645 // The current time is represented in two ways by Calendar: as UTC 646 // milliseconds from the epoch start (1 January 1970 0:00 UTC), and as local 647 // fields such as MONTH, HOUR, AM_PM, etc. It is possible to compute the 648 // millis from the fields, and vice versa. The data needed to do this 649 // conversion is encapsulated by a TimeZone object owned by the Calendar. 650 // The data provided by the TimeZone object may also be overridden if the 651 // user sets the ZONE_OFFSET and/or DST_OFFSET fields directly. The class 652 // keeps track of what information was most recently set by the caller, and 653 // uses that to compute any other information as needed. 654 655 // If the user sets the fields using set(), the data flow is as follows. 656 // This is implemented by the Calendar subclass's computeTime() method. 657 // During this process, certain fields may be ignored. The disambiguation 658 // algorithm for resolving which fields to pay attention to is described 659 // above. 660 661 // local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.) 662 // | 663 // | Using Calendar-specific algorithm 664 // V 665 // local standard millis 666 // | 667 // | Using TimeZone or user-set ZONE_OFFSET / DST_OFFSET 668 // V 669 // UTC millis (in time data member) 670 671 // If the user sets the UTC millis using setTime(), the data flow is as 672 // follows. This is implemented by the Calendar subclass's computeFields() 673 // method. 674 675 // UTC millis (in time data member) 676 // | 677 // | Using TimeZone getOffset() 678 // V 679 // local standard millis 680 // | 681 // | Using Calendar-specific algorithm 682 // V 683 // local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.) 684 685 // In general, a round trip from fields, through local and UTC millis, and 686 // back out to fields is made when necessary. This is implemented by the 687 // complete() method. Resolving a partial set of fields into a UTC millis 688 // value allows all remaining fields to be generated from that value. If 689 // the Calendar is lenient, the fields are also renormalized to standard 690 // ranges when they are regenerated. 691 692 /** 693 * Field number for <code>get</code> and <code>set</code> indicating the 694 * era, e.g., AD or BC in the Julian calendar. This is a calendar-specific 695 * value; see subclass documentation. 696 * @see GregorianCalendar#AD 697 * @see GregorianCalendar#BC 698 * @stable ICU 2.0 699 */ 700 public final static int ERA = 0; 701 702 /** 703 * Field number for <code>get</code> and <code>set</code> indicating the 704 * year. This is a calendar-specific value; see subclass documentation. 705 * @stable ICU 2.0 706 */ 707 public final static int YEAR = 1; 708 709 /** 710 * Field number for <code>get</code> and <code>set</code> indicating the 711 * month. This is a calendar-specific value. The first month of the year is 712 * <code>JANUARY</code>; the last depends on the number of months in a year. 713 * @see #JANUARY 714 * @see #FEBRUARY 715 * @see #MARCH 716 * @see #APRIL 717 * @see #MAY 718 * @see #JUNE 719 * @see #JULY 720 * @see #AUGUST 721 * @see #SEPTEMBER 722 * @see #OCTOBER 723 * @see #NOVEMBER 724 * @see #DECEMBER 725 * @see #UNDECIMBER 726 * @stable ICU 2.0 727 */ 728 public final static int MONTH = 2; 729 730 /** 731 * Field number for <code>get</code> and <code>set</code> indicating the 732 * week number within the current year. The first week of the year, as 733 * defined by {@link #getFirstDayOfWeek()} and 734 * {@link #getMinimalDaysInFirstWeek()}, has value 1. Subclasses define 735 * the value of {@link #WEEK_OF_YEAR} for days before the first week of 736 * the year. 737 * @see #getFirstDayOfWeek 738 * @see #getMinimalDaysInFirstWeek 739 * @stable ICU 2.0 740 */ 741 public final static int WEEK_OF_YEAR = 3; 742 743 /** 744 * Field number for <code>get</code> and <code>set</code> indicating the 745 * week number within the current month. The first week of the month, as 746 * defined by {@link #getFirstDayOfWeek()} and 747 * {@link #getMinimalDaysInFirstWeek()}, has value 1. Subclasses define 748 * the value of {@link #WEEK_OF_MONTH} for days before the first week of 749 * the month. 750 * @see #getFirstDayOfWeek 751 * @see #getMinimalDaysInFirstWeek 752 * @stable ICU 2.0 753 */ 754 public final static int WEEK_OF_MONTH = 4; 755 756 /** 757 * Field number for <code>get</code> and <code>set</code> indicating the 758 * day of the month. This is a synonym for {@link #DAY_OF_MONTH}. 759 * The first day of the month has value 1. 760 * @see #DAY_OF_MONTH 761 * @stable ICU 2.0 762 */ 763 public final static int DATE = 5; 764 765 /** 766 * Field number for <code>get</code> and <code>set</code> indicating the 767 * day of the month. This is a synonym for {@link #DATE}. 768 * The first day of the month has value 1. 769 * @see #DATE 770 * @stable ICU 2.0 771 */ 772 public final static int DAY_OF_MONTH = 5; 773 774 /** 775 * Field number for <code>get</code> and <code>set</code> indicating the day 776 * number within the current year. The first day of the year has value 1. 777 * @stable ICU 2.0 778 */ 779 public final static int DAY_OF_YEAR = 6; 780 781 /** 782 * Field number for <code>get</code> and <code>set</code> indicating the day 783 * of the week. This field takes values {@link #SUNDAY}, 784 * {@link #MONDAY}, {@link #TUESDAY}, {@link #WEDNESDAY}, 785 * {@link #THURSDAY}, {@link #FRIDAY}, and {@link #SATURDAY}. 786 * @see #SUNDAY 787 * @see #MONDAY 788 * @see #TUESDAY 789 * @see #WEDNESDAY 790 * @see #THURSDAY 791 * @see #FRIDAY 792 * @see #SATURDAY 793 * @stable ICU 2.0 794 */ 795 public final static int DAY_OF_WEEK = 7; 796 797 /** 798 * Field number for <code>get</code> and <code>set</code> indicating the 799 * ordinal number of the day of the week within the current month. Together 800 * with the {@link #DAY_OF_WEEK} field, this uniquely specifies a day 801 * within a month. Unlike {@link #WEEK_OF_MONTH} and 802 * {@link #WEEK_OF_YEAR}, this field's value does <em>not</em> depend on 803 * {@link #getFirstDayOfWeek()} or 804 * {@link #getMinimalDaysInFirstWeek()}. <code>DAY_OF_MONTH 1</code> 805 * through <code>7</code> always correspond to <code>DAY_OF_WEEK_IN_MONTH 806 * 1</code>; <code>8</code> through <code>15</code> correspond to 807 * <code>DAY_OF_WEEK_IN_MONTH 2</code>, and so on. 808 * <code>DAY_OF_WEEK_IN_MONTH 0</code> indicates the week before 809 * <code>DAY_OF_WEEK_IN_MONTH 1</code>. Negative values count back from the 810 * end of the month, so the last Sunday of a month is specified as 811 * <code>DAY_OF_WEEK = SUNDAY, DAY_OF_WEEK_IN_MONTH = -1</code>. Because 812 * negative values count backward they will usually be aligned differently 813 * within the month than positive values. For example, if a month has 31 814 * days, <code>DAY_OF_WEEK_IN_MONTH -1</code> will overlap 815 * <code>DAY_OF_WEEK_IN_MONTH 5</code> and the end of <code>4</code>. 816 * @see #DAY_OF_WEEK 817 * @see #WEEK_OF_MONTH 818 * @stable ICU 2.0 819 */ 820 public final static int DAY_OF_WEEK_IN_MONTH = 8; 821 822 /** 823 * Field number for <code>get</code> and <code>set</code> indicating 824 * whether the <code>HOUR</code> is before or after noon. 825 * E.g., at 10:04:15.250 PM the <code>AM_PM</code> is <code>PM</code>. 826 * @see #AM 827 * @see #PM 828 * @see #HOUR 829 * @stable ICU 2.0 830 */ 831 public final static int AM_PM = 9; 832 833 /** 834 * Field number for <code>get</code> and <code>set</code> indicating the 835 * hour of the morning or afternoon. <code>HOUR</code> is used for the 12-hour 836 * clock. 837 * E.g., at 10:04:15.250 PM the <code>HOUR</code> is 10. 838 * @see #AM_PM 839 * @see #HOUR_OF_DAY 840 * @stable ICU 2.0 841 */ 842 public final static int HOUR = 10; 843 844 /** 845 * Field number for <code>get</code> and <code>set</code> indicating the 846 * hour of the day. <code>HOUR_OF_DAY</code> is used for the 24-hour clock. 847 * E.g., at 10:04:15.250 PM the <code>HOUR_OF_DAY</code> is 22. 848 * @see #HOUR 849 * @stable ICU 2.0 850 */ 851 public final static int HOUR_OF_DAY = 11; 852 853 /** 854 * Field number for <code>get</code> and <code>set</code> indicating the 855 * minute within the hour. 856 * E.g., at 10:04:15.250 PM the <code>MINUTE</code> is 4. 857 * @stable ICU 2.0 858 */ 859 public final static int MINUTE = 12; 860 861 /** 862 * Field number for <code>get</code> and <code>set</code> indicating the 863 * second within the minute. 864 * E.g., at 10:04:15.250 PM the <code>SECOND</code> is 15. 865 * @stable ICU 2.0 866 */ 867 public final static int SECOND = 13; 868 869 /** 870 * Field number for <code>get</code> and <code>set</code> indicating the 871 * millisecond within the second. 872 * E.g., at 10:04:15.250 PM the <code>MILLISECOND</code> is 250. 873 * @stable ICU 2.0 874 */ 875 public final static int MILLISECOND = 14; 876 877 /** 878 * Field number for <code>get</code> and <code>set</code> indicating the 879 * raw offset from GMT in milliseconds. 880 * @stable ICU 2.0 881 */ 882 public final static int ZONE_OFFSET = 15; 883 884 /** 885 * Field number for <code>get</code> and <code>set</code> indicating the 886 * daylight savings offset in milliseconds. 887 * @stable ICU 2.0 888 */ 889 public final static int DST_OFFSET = 16; 890 891 /** 892 * {@icu} Field number for <code>get()</code> and <code>set()</code> 893 * indicating the extended year corresponding to the 894 * {@link #WEEK_OF_YEAR} field. This may be one greater or less 895 * than the value of {@link #EXTENDED_YEAR}. 896 * @stable ICU 2.0 897 */ 898 public static final int YEAR_WOY = 17; 899 900 /** 901 * {@icu} Field number for <code>get()</code> and <code>set()</code> 902 * indicating the localized day of week. This will be a value from 1 903 * to 7 inclusive, with 1 being the localized first day of the week. 904 * @stable ICU 2.0 905 */ 906 public static final int DOW_LOCAL = 18; 907 908 /** 909 * {@icu} Field number for <code>get()</code> and <code>set()</code> 910 * indicating the extended year. This is a single number designating 911 * the year of this calendar system, encompassing all supra-year 912 * fields. For example, for the Julian calendar system, year numbers 913 * are positive, with an era of BCE or CE. An extended year value for 914 * the Julian calendar system assigns positive values to CE years and 915 * negative values to BCE years, with 1 BCE being year 0. 916 * @stable ICU 2.0 917 */ 918 public static final int EXTENDED_YEAR = 19; 919 920 /** 921 * {@icu} Field number for <code>get()</code> and <code>set()</code> 922 * indicating the modified Julian day number. This is different from 923 * the conventional Julian day number in two regards. First, it 924 * demarcates days at local zone midnight, rather than noon GMT. 925 * Second, it is a local number; that is, it depends on the local time 926 * zone. It can be thought of as a single number that encompasses all 927 * the date-related fields. 928 * @stable ICU 2.0 929 */ 930 public static final int JULIAN_DAY = 20; 931 932 /** 933 * {@icu} Field number for <code>get()</code> and <code>set()</code> 934 * indicating the milliseconds in the day. This ranges from 0 to 935 * 23:59:59.999 (regardless of DST). This field behaves 936 * <em>exactly</em> like a composite of all time-related fields, not 937 * including the zone fields. As such, it also reflects 938 * discontinuities of those fields on DST transition days. On a day of 939 * DST onset, it will jump forward. On a day of DST cessation, it will 940 * jump backward. This reflects the fact that is must be combined with 941 * the DST_OFFSET field to obtain a unique local time value. 942 * @stable ICU 2.0 943 */ 944 public static final int MILLISECONDS_IN_DAY = 21; 945 946 /** 947 * {@icu} Field indicating whether or not the current month is a leap month. 948 * Should have a value of 0 for non-leap months, and 1 for leap months. 949 * @stable ICU 4.4 950 */ 951 public static final int IS_LEAP_MONTH = 22; 952 953 /** 954 * The number of fields defined by this class. Subclasses may define 955 * addition fields starting with this number. 956 * @stable ICU 2.0 957 */ 958 protected static final int BASE_FIELD_COUNT = 23; 959 960 /** 961 * The maximum number of fields possible. Subclasses must not define 962 * more total fields than this number. 963 * @stable ICU 2.0 964 */ 965 protected static final int MAX_FIELD_COUNT = 32; 966 967 /** 968 * Value of the <code>DAY_OF_WEEK</code> field indicating 969 * Sunday. 970 * @stable ICU 2.0 971 */ 972 public final static int SUNDAY = 1; 973 974 /** 975 * Value of the <code>DAY_OF_WEEK</code> field indicating 976 * Monday. 977 * @stable ICU 2.0 978 */ 979 public final static int MONDAY = 2; 980 981 /** 982 * Value of the <code>DAY_OF_WEEK</code> field indicating 983 * Tuesday. 984 * @stable ICU 2.0 985 */ 986 public final static int TUESDAY = 3; 987 988 /** 989 * Value of the <code>DAY_OF_WEEK</code> field indicating 990 * Wednesday. 991 * @stable ICU 2.0 992 */ 993 public final static int WEDNESDAY = 4; 994 995 /** 996 * Value of the <code>DAY_OF_WEEK</code> field indicating 997 * Thursday. 998 * @stable ICU 2.0 999 */ 1000 public final static int THURSDAY = 5; 1001 1002 /** 1003 * Value of the <code>DAY_OF_WEEK</code> field indicating 1004 * Friday. 1005 * @stable ICU 2.0 1006 */ 1007 public final static int FRIDAY = 6; 1008 1009 /** 1010 * Value of the <code>DAY_OF_WEEK</code> field indicating 1011 * Saturday. 1012 * @stable ICU 2.0 1013 */ 1014 public final static int SATURDAY = 7; 1015 1016 /** 1017 * Value of the <code>MONTH</code> field indicating the 1018 * first month of the year. 1019 * @stable ICU 2.0 1020 */ 1021 public final static int JANUARY = 0; 1022 1023 /** 1024 * Value of the <code>MONTH</code> field indicating the 1025 * second month of the year. 1026 * @stable ICU 2.0 1027 */ 1028 public final static int FEBRUARY = 1; 1029 1030 /** 1031 * Value of the <code>MONTH</code> field indicating the 1032 * third month of the year. 1033 * @stable ICU 2.0 1034 */ 1035 public final static int MARCH = 2; 1036 1037 /** 1038 * Value of the <code>MONTH</code> field indicating the 1039 * fourth month of the year. 1040 * @stable ICU 2.0 1041 */ 1042 public final static int APRIL = 3; 1043 1044 /** 1045 * Value of the <code>MONTH</code> field indicating the 1046 * fifth month of the year. 1047 * @stable ICU 2.0 1048 */ 1049 public final static int MAY = 4; 1050 1051 /** 1052 * Value of the <code>MONTH</code> field indicating the 1053 * sixth month of the year. 1054 * @stable ICU 2.0 1055 */ 1056 public final static int JUNE = 5; 1057 1058 /** 1059 * Value of the <code>MONTH</code> field indicating the 1060 * seventh month of the year. 1061 * @stable ICU 2.0 1062 */ 1063 public final static int JULY = 6; 1064 1065 /** 1066 * Value of the <code>MONTH</code> field indicating the 1067 * eighth month of the year. 1068 * @stable ICU 2.0 1069 */ 1070 public final static int AUGUST = 7; 1071 1072 /** 1073 * Value of the <code>MONTH</code> field indicating the 1074 * ninth month of the year. 1075 * @stable ICU 2.0 1076 */ 1077 public final static int SEPTEMBER = 8; 1078 1079 /** 1080 * Value of the <code>MONTH</code> field indicating the 1081 * tenth month of the year. 1082 * @stable ICU 2.0 1083 */ 1084 public final static int OCTOBER = 9; 1085 1086 /** 1087 * Value of the <code>MONTH</code> field indicating the 1088 * eleventh month of the year. 1089 * @stable ICU 2.0 1090 */ 1091 public final static int NOVEMBER = 10; 1092 1093 /** 1094 * Value of the <code>MONTH</code> field indicating the 1095 * twelfth month of the year. 1096 * @stable ICU 2.0 1097 */ 1098 public final static int DECEMBER = 11; 1099 1100 /** 1101 * Value of the <code>MONTH</code> field indicating the 1102 * thirteenth month of the year. Although {@link GregorianCalendar} 1103 * does not use this value, lunar calendars do. 1104 * @stable ICU 2.0 1105 */ 1106 public final static int UNDECIMBER = 12; 1107 1108 /** 1109 * Value of the <code>AM_PM</code> field indicating the 1110 * period of the day from midnight to just before noon. 1111 * @stable ICU 2.0 1112 */ 1113 public final static int AM = 0; 1114 1115 /** 1116 * Value of the <code>AM_PM</code> field indicating the 1117 * period of the day from noon to just before midnight. 1118 * @stable ICU 2.0 1119 */ 1120 public final static int PM = 1; 1121 1122 /** 1123 * {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a 1124 * weekday. 1125 * @see #WEEKEND 1126 * @see #WEEKEND_ONSET 1127 * @see #WEEKEND_CEASE 1128 * @see #getDayOfWeekType 1129 * @deprecated ICU 54 use {@link #getWeekDataForRegion(String)}, {@link #getWeekData()}, {@link #setWeekData(WeekData)} 1130 */ 1131 @Deprecated 1132 public static final int WEEKDAY = 0; 1133 1134 /** 1135 * {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a 1136 * weekend day. 1137 * @see #WEEKDAY 1138 * @see #WEEKEND_ONSET 1139 * @see #WEEKEND_CEASE 1140 * @see #getDayOfWeekType 1141 * @deprecated ICU 54 use {@link #getWeekDataForRegion(String)}, {@link #getWeekData()}, {@link #setWeekData(WeekData)} 1142 */ 1143 @Deprecated 1144 public static final int WEEKEND = 1; 1145 1146 /** 1147 * {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a 1148 * day that starts as a weekday and transitions to the weekend. 1149 * Call getWeekendTransition() to get the point of transition. 1150 * @see #WEEKDAY 1151 * @see #WEEKEND 1152 * @see #WEEKEND_CEASE 1153 * @see #getDayOfWeekType 1154 * @deprecated ICU 54 use {@link #getWeekDataForRegion(String)}, {@link #getWeekData()}, {@link #setWeekData(WeekData)} 1155 */ 1156 @Deprecated 1157 public static final int WEEKEND_ONSET = 2; 1158 1159 /** 1160 * {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a 1161 * day that starts as the weekend and transitions to a weekday. 1162 * Call getWeekendTransition() to get the point of transition. 1163 * @see #WEEKDAY 1164 * @see #WEEKEND 1165 * @see #WEEKEND_ONSET 1166 * @see #getDayOfWeekType 1167 * @deprecated ICU 54 use {@link #getWeekDataForRegion(String)}, {@link #getWeekData()}, {@link #setWeekData(WeekData)} 1168 */ 1169 @Deprecated 1170 public static final int WEEKEND_CEASE = 3; 1171 1172 /** 1173 * {@icu}Option used by {@link #setRepeatedWallTimeOption(int)} and 1174 * {@link #setSkippedWallTimeOption(int)} specifying an ambiguous wall time 1175 * to be interpreted as the latest. 1176 * @see #setRepeatedWallTimeOption(int) 1177 * @see #getRepeatedWallTimeOption() 1178 * @see #setSkippedWallTimeOption(int) 1179 * @see #getSkippedWallTimeOption() 1180 * @stable ICU 49 1181 */ 1182 public static final int WALLTIME_LAST = 0; 1183 1184 /** 1185 * {@icu}Option used by {@link #setRepeatedWallTimeOption(int)} and 1186 * {@link #setSkippedWallTimeOption(int)} specifying an ambiguous wall time 1187 * to be interpreted as the earliest. 1188 * @see #setRepeatedWallTimeOption(int) 1189 * @see #getRepeatedWallTimeOption() 1190 * @see #setSkippedWallTimeOption(int) 1191 * @see #getSkippedWallTimeOption() 1192 * @stable ICU 49 1193 */ 1194 public static final int WALLTIME_FIRST = 1; 1195 1196 /** 1197 * {@icu}Option used by {@link #setSkippedWallTimeOption(int)} specifying an 1198 * ambiguous wall time to be interpreted as the next valid wall time. 1199 * @see #setSkippedWallTimeOption(int) 1200 * @see #getSkippedWallTimeOption() 1201 * @stable ICU 49 1202 */ 1203 public static final int WALLTIME_NEXT_VALID = 2; 1204 1205 /** 1206 * The number of milliseconds in one second. 1207 * @stable ICU 2.0 1208 */ 1209 protected static final int ONE_SECOND = 1000; 1210 1211 /** 1212 * The number of milliseconds in one minute. 1213 * @stable ICU 2.0 1214 */ 1215 protected static final int ONE_MINUTE = 60*ONE_SECOND; 1216 1217 /** 1218 * The number of milliseconds in one hour. 1219 * @stable ICU 2.0 1220 */ 1221 protected static final int ONE_HOUR = 60*ONE_MINUTE; 1222 1223 /** 1224 * The number of milliseconds in one day. Although ONE_DAY and 1225 * ONE_WEEK can fit into ints, they must be longs in order to prevent 1226 * arithmetic overflow when performing (bug 4173516). 1227 * @stable ICU 2.0 1228 */ 1229 protected static final long ONE_DAY = 24*ONE_HOUR; 1230 1231 /** 1232 * The number of milliseconds in one week. Although ONE_DAY and 1233 * ONE_WEEK can fit into ints, they must be longs in order to prevent 1234 * arithmetic overflow when performing (bug 4173516). 1235 * @stable ICU 2.0 1236 */ 1237 protected static final long ONE_WEEK = 7*ONE_DAY; 1238 1239 /** 1240 * The Julian day of the Gregorian epoch, that is, January 1, 1 on the 1241 * Gregorian calendar. 1242 * @stable ICU 2.0 1243 */ 1244 protected static final int JAN_1_1_JULIAN_DAY = 1721426; 1245 1246 /** 1247 * The Julian day of the epoch, that is, January 1, 1970 on the 1248 * Gregorian calendar. 1249 * @stable ICU 2.0 1250 */ 1251 protected static final int EPOCH_JULIAN_DAY = 2440588; 1252 1253 /** 1254 * The minimum supported Julian day. This value is equivalent to 1255 * {@link #MIN_MILLIS} and {@link #MIN_DATE}. 1256 * @see #JULIAN_DAY 1257 * @stable ICU 2.0 1258 */ 1259 protected static final int MIN_JULIAN = -0x7F000000; 1260 1261 /** 1262 * The minimum supported epoch milliseconds. This value is equivalent 1263 * to {@link #MIN_JULIAN} and {@link #MIN_DATE}. 1264 * @stable ICU 2.0 1265 */ 1266 protected static final long MIN_MILLIS = -184303902528000000L; 1267 1268 // Get around bug in jikes 1.12 for now. Later, use: 1269 //protected static final long MIN_MILLIS = (MIN_JULIAN - EPOCH_JULIAN_DAY) * ONE_DAY; 1270 1271 /** 1272 * The minimum supported <code>Date</code>. This value is equivalent 1273 * to {@link #MIN_JULIAN} and {@link #MIN_MILLIS}. 1274 * @stable ICU 2.0 1275 */ 1276 protected static final Date MIN_DATE = new Date(MIN_MILLIS); 1277 1278 /** 1279 * The maximum supported Julian day. This value is equivalent to 1280 * {@link #MAX_MILLIS} and {@link #MAX_DATE}. 1281 * @see #JULIAN_DAY 1282 * @stable ICU 2.0 1283 */ 1284 protected static final int MAX_JULIAN = +0x7F000000; 1285 1286 /** 1287 * The maximum supported epoch milliseconds. This value is equivalent 1288 * to {@link #MAX_JULIAN} and {@link #MAX_DATE}. 1289 * @stable ICU 2.0 1290 */ 1291 protected static final long MAX_MILLIS = (MAX_JULIAN - EPOCH_JULIAN_DAY) * ONE_DAY; 1292 1293 /** 1294 * The maximum supported <code>Date</code>. This value is equivalent 1295 * to {@link #MAX_JULIAN} and {@link #MAX_MILLIS}. 1296 * @stable ICU 2.0 1297 */ 1298 protected static final Date MAX_DATE = new Date(MAX_MILLIS); 1299 1300 // Internal notes: 1301 // Calendar contains two kinds of time representations: current "time" in 1302 // milliseconds, and a set of time "fields" representing the current time. 1303 // The two representations are usually in sync, but can get out of sync 1304 // as follows. 1305 // 1. Initially, no fields are set, and the time is invalid. 1306 // 2. If the time is set, all fields are computed and in sync. 1307 // 3. If a single field is set, the time is invalid. 1308 // Recomputation of the time and fields happens when the object needs 1309 // to return a result to the user, or use a result for a computation. 1310 1311 /** 1312 * The field values for the currently set time for this calendar. 1313 * This is an array of at least {@link #BASE_FIELD_COUNT} integers. 1314 * @see #handleCreateFields 1315 * @serial 1316 */ 1317 private transient int fields[]; 1318 1319 /** 1320 * Pseudo-time-stamps which specify when each field was set. There 1321 * are two special values, UNSET and INTERNALLY_SET. Values from 1322 * MINIMUM_USER_SET to Integer.MAX_VALUE are legal user set values. 1323 */ 1324 private transient int stamp[]; 1325 1326 /** 1327 * The currently set time for this calendar, expressed in milliseconds after 1328 * January 1, 1970, 0:00:00 GMT. 1329 * @serial 1330 */ 1331 private long time; 1332 1333 /** 1334 * True if then the value of <code>time</code> is valid. 1335 * The time is made invalid by a change to an item of <code>field[]</code>. 1336 * @see #time 1337 * @serial 1338 */ 1339 private transient boolean isTimeSet; 1340 1341 /** 1342 * True if <code>fields[]</code> are in sync with the currently set time. 1343 * If false, then the next attempt to get the value of a field will 1344 * force a recomputation of all fields from the current value of 1345 * <code>time</code>. 1346 * @serial 1347 */ 1348 private transient boolean areFieldsSet; 1349 1350 /** 1351 * True if all fields have been set. This is only false in a few 1352 * situations: In a newly created, partially constructed object. After 1353 * a call to clear(). In an object just read from a stream using 1354 * readObject(). Once computeFields() has been called this is set to 1355 * true and stays true until one of the above situations recurs. 1356 * @serial 1357 */ 1358 private transient boolean areAllFieldsSet; 1359 1360 /** 1361 * True if all fields have been virtually set, but have not yet been 1362 * computed. This occurs only in setTimeInMillis(), or after readObject(). 1363 * A calendar set to this state will compute all fields from the time if it 1364 * becomes necessary, but otherwise will delay such computation. 1365 */ 1366 private transient boolean areFieldsVirtuallySet; 1367 1368 /** 1369 * True if this calendar allows out-of-range field values during computation 1370 * of <code>time</code> from <code>fields[]</code>. 1371 * @see #setLenient 1372 * @serial 1373 */ 1374 private boolean lenient = true; 1375 1376 /** 1377 * The {@link TimeZone} used by this calendar. {@link Calendar} 1378 * uses the time zone data to translate between local and GMT time. 1379 * @serial 1380 */ 1381 private TimeZone zone; 1382 1383 /** 1384 * The first day of the week, with possible values {@link #SUNDAY}, 1385 * {@link #MONDAY}, etc. This is a locale-dependent value. 1386 * @serial 1387 */ 1388 private int firstDayOfWeek; 1389 1390 /** 1391 * The number of days required for the first week in a month or year, 1392 * with possible values from 1 to 7. This is a locale-dependent value. 1393 * @serial 1394 */ 1395 private int minimalDaysInFirstWeek; 1396 1397 /** 1398 * First day of the weekend in this calendar's locale. Must be in 1399 * the range SUNDAY...SATURDAY (1..7). The weekend starts at 1400 * weekendOnsetMillis milliseconds after midnight on that day of 1401 * the week. This value is taken from locale resource data. 1402 */ 1403 private int weekendOnset; 1404 1405 /** 1406 * Milliseconds after midnight at which the weekend starts on the 1407 * day of the week weekendOnset. Times that are greater than or 1408 * equal to weekendOnsetMillis are considered part of the weekend. 1409 * Must be in the range 0..24*60*60*1000-1. This value is taken 1410 * from locale resource data. 1411 */ 1412 private int weekendOnsetMillis; 1413 1414 /** 1415 * Day of the week when the weekend stops in this calendar's 1416 * locale. Must be in the range SUNDAY...SATURDAY (1..7). The 1417 * weekend stops at weekendCeaseMillis milliseconds after midnight 1418 * on that day of the week. This value is taken from locale 1419 * resource data. 1420 */ 1421 private int weekendCease; 1422 1423 /** 1424 * Milliseconds after midnight at which the weekend stops on the 1425 * day of the week weekendCease. Times that are greater than or 1426 * equal to weekendCeaseMillis are considered not to be the 1427 * weekend. Must be in the range 0..24*60*60*1000-1. This value 1428 * is taken from locale resource data. 1429 */ 1430 private int weekendCeaseMillis; 1431 1432 /** 1433 * Option used when the specified wall time occurs multiple times. 1434 */ 1435 private int repeatedWallTime = WALLTIME_LAST; 1436 1437 /** 1438 * Option used when the specified wall time does not exist. 1439 */ 1440 private int skippedWallTime = WALLTIME_LAST; 1441 1442 /** 1443 * Value of the time stamp <code>stamp[]</code> indicating that 1444 * a field has not been set since the last call to <code>clear()</code>. 1445 * @see #INTERNALLY_SET 1446 * @see #MINIMUM_USER_STAMP 1447 * @stable ICU 2.0 1448 */ 1449 protected static final int UNSET = 0; 1450 1451 /** 1452 * Value of the time stamp <code>stamp[]</code> indicating that a field 1453 * has been set via computations from the time or from other fields. 1454 * @see #UNSET 1455 * @see #MINIMUM_USER_STAMP 1456 * @stable ICU 2.0 1457 */ 1458 protected static final int INTERNALLY_SET = 1; 1459 1460 /** 1461 * If the time stamp <code>stamp[]</code> has a value greater than or 1462 * equal to <code>MINIMUM_USER_SET</code> then it has been set by the 1463 * user via a call to <code>set()</code>. 1464 * @see #UNSET 1465 * @see #INTERNALLY_SET 1466 * @stable ICU 2.0 1467 */ 1468 protected static final int MINIMUM_USER_STAMP = 2; 1469 1470 /** 1471 * The next available value for <code>stamp[]</code>, an internal array. 1472 * @serial 1473 */ 1474 private transient int nextStamp = MINIMUM_USER_STAMP; 1475 1476 /* Max value for stamp allowable before recalcution */ 1477 private static int STAMP_MAX = 10000; 1478 1479 // the internal serial version which says which version was written 1480 // - 0 (default) for version up to JDK 1.1.5 1481 // - 1 for version from JDK 1.1.6, which writes a correct 'time' value 1482 // as well as compatible values for other fields. This is a 1483 // transitional format. 1484 // - 2 (not implemented yet) a future version, in which fields[], 1485 // areFieldsSet, and isTimeSet become transient, and isSet[] is 1486 // removed. In JDK 1.1.6 we write a format compatible with version 2. 1487 // static final int currentSerialVersion = 1; 1488 1489 /** 1490 * The version of the serialized data on the stream. Possible values: 1491 * <dl> 1492 * <dt><b>0</b> or not present on stream</dt> 1493 * <dd> 1494 * JDK 1.1.5 or earlier. 1495 * </dd> 1496 * <dt><b>1</b></dt> 1497 * <dd> 1498 * JDK 1.1.6 or later. Writes a correct 'time' value 1499 * as well as compatible values for other fields. This is a 1500 * transitional format. 1501 * </dd> 1502 * </dl> 1503 * When streaming out this class, the most recent format 1504 * and the highest allowable <code>serialVersionOnStream</code> 1505 * is written. 1506 * @serial 1507 * @since JDK1.1.6 1508 */ 1509 // private int serialVersionOnStream = currentSerialVersion; 1510 1511 // Proclaim serialization compatibility with JDK 1.1 1512 // static final long serialVersionUID = -1807547505821590642L; 1513 1514 // haven't been compatible for awhile, no longer try 1515 // jdk1.4.2 serialver 1516 private static final long serialVersionUID = 6222646104888790989L; 1517 1518 /** 1519 * Bitmask for internalSet() defining which fields may legally be set 1520 * by subclasses. Any attempt to set a field not in this bitmask 1521 * results in an exception, because such fields must be set by the base 1522 * class. 1523 */ 1524 private transient int internalSetMask; 1525 1526 /** 1527 * The Gregorian year, as computed by computeGregorianFields() and 1528 * returned by getGregorianYear(). 1529 */ 1530 private transient int gregorianYear; 1531 1532 /** 1533 * The Gregorian month, as computed by computeGregorianFields() and 1534 * returned by getGregorianMonth(). 1535 */ 1536 private transient int gregorianMonth; 1537 1538 /** 1539 * The Gregorian day of the year, as computed by 1540 * computeGregorianFields() and returned by getGregorianDayOfYear(). 1541 */ 1542 private transient int gregorianDayOfYear; 1543 1544 /** 1545 * The Gregorian day of the month, as computed by 1546 * computeGregorianFields() and returned by getGregorianDayOfMonth(). 1547 */ 1548 private transient int gregorianDayOfMonth; 1549 1550 /** 1551 * Constructs a Calendar with the default time zone 1552 * and the default <code>FORMAT</code> locale. 1553 * @see TimeZone#getDefault 1554 * @see Category#FORMAT 1555 * @stable ICU 2.0 1556 */ Calendar()1557 protected Calendar() 1558 { 1559 this(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT)); 1560 } 1561 1562 /** 1563 * Constructs a calendar with the specified time zone and locale. 1564 * @param zone the time zone to use 1565 * @param aLocale the locale for the week data 1566 * @stable ICU 2.0 1567 */ Calendar(TimeZone zone, Locale aLocale)1568 protected Calendar(TimeZone zone, Locale aLocale) 1569 { 1570 this(zone, ULocale.forLocale(aLocale)); 1571 } 1572 1573 /** 1574 * Constructs a calendar with the specified time zone and locale. 1575 * @param zone the time zone to use 1576 * @param locale the ulocale for the week data 1577 * @stable ICU 3.2 1578 */ Calendar(TimeZone zone, ULocale locale)1579 protected Calendar(TimeZone zone, ULocale locale) 1580 { 1581 this.zone = zone; 1582 1583 // week data 1584 setWeekData(getRegionForCalendar(locale)); 1585 1586 // set valid/actual locale 1587 setCalendarLocale(locale); 1588 1589 initInternal(); 1590 } 1591 1592 /* 1593 * Set valid/actual locale to this calendar during initialization. 1594 * 1595 * Valid or actual locale does not make much sense for Calendar 1596 * object. An instance of Calendar is initialized by week data 1597 * determine by region and calendar type (either region or keyword). 1598 * Language is not really used for calendar creation. 1599 */ setCalendarLocale(ULocale locale)1600 private void setCalendarLocale(ULocale locale) { 1601 ULocale calLocale = locale; 1602 1603 if (locale.getVariant().length() != 0 || locale.getKeywords() != null) { 1604 // Construct a ULocale, without variant and keywords (except calendar). 1605 StringBuilder buf = new StringBuilder(); 1606 1607 buf.append(locale.getLanguage()); 1608 1609 String script = locale.getScript(); 1610 if (script.length() > 0) { 1611 buf.append("_").append(script); 1612 } 1613 1614 String region = locale.getCountry(); 1615 if (region.length() > 0) { 1616 buf.append("_").append(region); 1617 } 1618 1619 String calType = locale.getKeywordValue("calendar"); 1620 if (calType != null) { 1621 buf.append("@calendar=").append(calType); 1622 } 1623 1624 calLocale = new ULocale(buf.toString()); 1625 } 1626 1627 setLocale(calLocale, calLocale); 1628 } 1629 recalculateStamp()1630 private void recalculateStamp() { 1631 int index; 1632 int currentValue; 1633 int j, i; 1634 1635 nextStamp = 1; 1636 1637 for (j = 0; j < stamp.length; j++) { 1638 currentValue = STAMP_MAX; 1639 index = -1; 1640 1641 for (i = 0; i < stamp.length; i++) { 1642 if (stamp[i] > nextStamp && stamp[i] < currentValue) { 1643 currentValue = stamp[i]; 1644 index = i; 1645 } 1646 } 1647 1648 if (index >= 0) { 1649 stamp[index] = ++nextStamp; 1650 } else { 1651 break; 1652 } 1653 } 1654 nextStamp++; 1655 } 1656 initInternal()1657 private void initInternal() 1658 { 1659 // Allocate fields through the framework method. Subclasses 1660 // may override this to define additional fields. 1661 fields = handleCreateFields(); 1662 ///CLOVER:OFF 1663 // todo: fix, difficult to test without subclassing 1664 if (fields == null || fields.length < BASE_FIELD_COUNT || 1665 fields.length > MAX_FIELD_COUNT) { 1666 throw new IllegalStateException("Invalid fields[]"); 1667 } 1668 ///CLOVER:ON 1669 stamp = new int[fields.length]; 1670 int mask = (1 << ERA) | 1671 (1 << YEAR) | 1672 (1 << MONTH) | 1673 (1 << DAY_OF_MONTH) | 1674 (1 << DAY_OF_YEAR) | 1675 (1 << EXTENDED_YEAR) | 1676 (1 << IS_LEAP_MONTH); 1677 for (int i=BASE_FIELD_COUNT; i<fields.length; ++i) { 1678 mask |= (1 << i); 1679 } 1680 internalSetMask = mask; 1681 } 1682 1683 /** 1684 * Returns a calendar using the default time zone and locale. 1685 * @return a Calendar. 1686 * @stable ICU 2.0 1687 */ getInstance()1688 public static Calendar getInstance() 1689 { 1690 return getInstanceInternal(null, null); 1691 } 1692 1693 /** 1694 * Returns a calendar using the specified time zone and default locale. 1695 * @param zone the time zone to use 1696 * @return a Calendar. 1697 * @stable ICU 2.0 1698 */ getInstance(TimeZone zone)1699 public static Calendar getInstance(TimeZone zone) 1700 { 1701 return getInstanceInternal(zone, null); 1702 } 1703 1704 /** 1705 * Returns a calendar using the default time zone and specified locale. 1706 * @param aLocale the locale for the week data 1707 * @return a Calendar. 1708 * @stable ICU 2.0 1709 */ getInstance(Locale aLocale)1710 public static Calendar getInstance(Locale aLocale) 1711 { 1712 return getInstanceInternal(null, ULocale.forLocale(aLocale)); 1713 } 1714 1715 /** 1716 * Returns a calendar using the default time zone and specified locale. 1717 * @param locale the ulocale for the week data 1718 * @return a Calendar. 1719 * @stable ICU 3.2 1720 */ getInstance(ULocale locale)1721 public static Calendar getInstance(ULocale locale) 1722 { 1723 return getInstanceInternal(null, locale); 1724 } 1725 1726 /** 1727 * Returns a calendar with the specified time zone and locale. 1728 * @param zone the time zone to use 1729 * @param aLocale the locale for the week data 1730 * @return a Calendar. 1731 * @stable ICU 2.0 1732 */ getInstance(TimeZone zone, Locale aLocale)1733 public static Calendar getInstance(TimeZone zone, Locale aLocale) { 1734 return getInstanceInternal(zone, ULocale.forLocale(aLocale)); 1735 } 1736 1737 /** 1738 * Returns a calendar with the specified time zone and locale. 1739 * @param zone the time zone to use 1740 * @param locale the ulocale for the week data 1741 * @return a Calendar. 1742 * @stable ICU 3.2 1743 */ getInstance(TimeZone zone, ULocale locale)1744 public static Calendar getInstance(TimeZone zone, ULocale locale) { 1745 return getInstanceInternal(zone, locale); 1746 } 1747 1748 /* 1749 * All getInstance implementations call this private method to create a new 1750 * Calendar instance. 1751 */ getInstanceInternal(TimeZone tz, ULocale locale)1752 private static Calendar getInstanceInternal(TimeZone tz, ULocale locale) { 1753 if (locale == null) { 1754 locale = ULocale.getDefault(Category.FORMAT); 1755 } 1756 if (tz == null) { 1757 tz = TimeZone.getDefault(); 1758 } 1759 1760 Calendar cal = createInstance(locale); 1761 cal.setTimeZone(tz); 1762 cal.setTimeInMillis(System.currentTimeMillis()); 1763 return cal; 1764 } 1765 getRegionForCalendar(ULocale loc)1766 private static String getRegionForCalendar(ULocale loc) { 1767 String region = loc.getCountry(); 1768 if (region.length() == 0) { 1769 ULocale maxLocale = ULocale.addLikelySubtags(loc); 1770 region = maxLocale.getCountry(); 1771 if (region.length() == 0) { 1772 region = "001"; 1773 } 1774 } 1775 return region; 1776 } 1777 1778 private enum CalType { 1779 GREGORIAN("gregorian"), 1780 ISO8601("iso8601"), 1781 1782 BUDDHIST("buddhist"), 1783 CHINESE("chinese"), 1784 COPTIC("coptic"), 1785 DANGI("dangi"), 1786 ETHIOPIC("ethiopic"), 1787 ETHIOPIC_AMETE_ALEM("ethiopic-amete-alem"), 1788 HEBREW("hebrew"), 1789 INDIAN("indian"), 1790 ISLAMIC("islamic"), 1791 ISLAMIC_CIVIL("islamic-civil"), 1792 ISLAMIC_RGSA("islamic-rgsa"), 1793 ISLAMIC_TBLA("islamic-tbla"), 1794 ISLAMIC_UMALQURA("islamic-umalqura"), 1795 JAPANESE("japanese"), 1796 PERSIAN("persian"), 1797 ROC("roc"), 1798 1799 UNKNOWN("unknown"); 1800 1801 String id; 1802 CalType(String id)1803 CalType(String id) { 1804 this.id = id; 1805 } 1806 } 1807 getCalendarTypeForLocale(ULocale l)1808 private static CalType getCalendarTypeForLocale(ULocale l) { 1809 String s = CalendarUtil.getCalendarType(l); 1810 if (s != null) { 1811 s = s.toLowerCase(Locale.ENGLISH); 1812 for (CalType type : CalType.values()) { 1813 if (s.equals(type.id)) { 1814 return type; 1815 } 1816 } 1817 } 1818 return CalType.UNKNOWN; 1819 } 1820 createInstance(ULocale locale)1821 private static Calendar createInstance(ULocale locale) { 1822 Calendar cal = null; 1823 TimeZone zone = TimeZone.getDefault(); 1824 CalType calType = getCalendarTypeForLocale(locale); 1825 if (calType == CalType.UNKNOWN) { 1826 // fallback to Gregorian 1827 calType = CalType.GREGORIAN; 1828 } 1829 1830 switch (calType) { 1831 case GREGORIAN: 1832 cal = new GregorianCalendar(zone, locale); 1833 break; 1834 case ISO8601: 1835 // Only differs week numbering rule from Gregorian 1836 cal = new GregorianCalendar(zone, locale); 1837 cal.setFirstDayOfWeek(MONDAY); 1838 cal.setMinimalDaysInFirstWeek(4); 1839 break; 1840 1841 case BUDDHIST: 1842 cal = new BuddhistCalendar(zone, locale); 1843 break; 1844 case CHINESE: 1845 cal = new ChineseCalendar(zone, locale); 1846 break; 1847 case COPTIC: 1848 cal = new CopticCalendar(zone, locale); 1849 break; 1850 case DANGI: 1851 cal = new DangiCalendar(zone, locale); 1852 break; 1853 case ETHIOPIC: 1854 cal = new EthiopicCalendar(zone, locale); 1855 break; 1856 case ETHIOPIC_AMETE_ALEM: 1857 cal = new EthiopicCalendar(zone, locale); 1858 ((EthiopicCalendar)cal).setAmeteAlemEra(true); 1859 break; 1860 case HEBREW: 1861 cal = new HebrewCalendar(zone, locale); 1862 break; 1863 case INDIAN: 1864 cal = new IndianCalendar(zone, locale); 1865 break; 1866 case ISLAMIC_CIVIL: 1867 case ISLAMIC_UMALQURA : 1868 case ISLAMIC_TBLA: 1869 case ISLAMIC_RGSA: 1870 case ISLAMIC: 1871 cal = new IslamicCalendar(zone, locale); 1872 break; 1873 case JAPANESE: 1874 cal = new JapaneseCalendar(zone, locale); 1875 break; 1876 case PERSIAN: 1877 cal = new PersianCalendar(zone, locale); 1878 break; 1879 case ROC: 1880 cal = new TaiwanCalendar(zone, locale); 1881 break; 1882 1883 default: 1884 // we must not get here, because unknown type is mapped to 1885 // Gregorian at the beginning of this method. 1886 throw new IllegalArgumentException("Unknown calendar type"); 1887 } 1888 1889 return cal; 1890 } 1891 1892 /** 1893 * Returns the list of locales for which Calendars are installed. 1894 * @return the list of locales for which Calendars are installed. 1895 * @stable ICU 2.0 1896 */ getAvailableLocales()1897 public static Locale[] getAvailableLocales() 1898 { 1899 // TODO 1900 return ICUResourceBundle.getAvailableLocales(); 1901 } 1902 1903 /** 1904 * {@icu} Returns the list of locales for which Calendars are installed. 1905 * @return the list of locales for which Calendars are installed. 1906 * @draft ICU 3.2 (retain) 1907 * @provisional This API might change or be removed in a future release. 1908 */ getAvailableULocales()1909 public static ULocale[] getAvailableULocales() 1910 { 1911 // TODO 1912 return ICUResourceBundle.getAvailableULocales(); 1913 } 1914 1915 /** 1916 * {@icu} Given a key and a locale, returns an array of string values in a preferred 1917 * order that would make a difference. These are all and only those values where 1918 * the open (creation) of the service with the locale formed from the input locale 1919 * plus input keyword and that value has different behavior than creation with the 1920 * input locale alone. 1921 * @param key one of the keys supported by this service. For now, only 1922 * "calendar" is supported. 1923 * @param locale the locale 1924 * @param commonlyUsed if set to true it will return only commonly used values 1925 * with the given locale in preferred order. Otherwise, 1926 * it will return all the available values for the locale. 1927 * @return an array of string values for the given key and the locale. 1928 * @stable ICU 4.2 1929 */ getKeywordValuesForLocale(String key, ULocale locale, boolean commonlyUsed)1930 public static final String[] getKeywordValuesForLocale(String key, ULocale locale, 1931 boolean commonlyUsed) { 1932 // Resolve region 1933 String prefRegion = locale.getCountry(); 1934 if (prefRegion.length() == 0){ 1935 ULocale loc = ULocale.addLikelySubtags(locale); 1936 prefRegion = loc.getCountry(); 1937 } 1938 1939 // Read preferred calendar values from supplementalData calendarPreferences 1940 ArrayList<String> values = new ArrayList<String>(); 1941 1942 UResourceBundle rb = UResourceBundle.getBundleInstance( 1943 ICUResourceBundle.ICU_BASE_NAME, 1944 "supplementalData", 1945 ICUResourceBundle.ICU_DATA_CLASS_LOADER); 1946 UResourceBundle calPref = rb.get("calendarPreferenceData"); 1947 UResourceBundle order = null; 1948 try { 1949 order = calPref.get(prefRegion); 1950 } catch (MissingResourceException mre) { 1951 // use "001" as fallback 1952 order = calPref.get("001"); 1953 } 1954 1955 String[] caltypes = order.getStringArray(); 1956 if (commonlyUsed) { 1957 // we have all commonly used calendar for the target region 1958 return caltypes; 1959 } 1960 1961 // if not commonlyUsed, add all preferred calendars in the order 1962 for (int i = 0; i < caltypes.length; i++) { 1963 values.add(caltypes[i]); 1964 } 1965 // then, add other available clanedars 1966 for (CalType t : CalType.values()) { 1967 if (!values.contains(t.id)) { 1968 values.add(t.id); 1969 } 1970 } 1971 return values.toArray(new String[values.size()]); 1972 } 1973 1974 /** 1975 * Returns this Calendar's current time. 1976 * @return the current time. 1977 * @stable ICU 2.0 1978 */ getTime()1979 public final Date getTime() { 1980 return new Date( getTimeInMillis() ); 1981 } 1982 1983 /** 1984 * Sets this Calendar's current time with the given Date. 1985 * 1986 * <p>Note: Calling <code>setTime</code> with 1987 * <code>Date(Long.MAX_VALUE)</code> or <code>Date(Long.MIN_VALUE)</code> 1988 * may yield incorrect field values from {@link #get(int)}. 1989 * @param date the given Date. 1990 * @stable ICU 2.0 1991 */ setTime(Date date)1992 public final void setTime(Date date) { 1993 setTimeInMillis( date.getTime() ); 1994 } 1995 1996 /** 1997 * Returns this Calendar's current time as a long. 1998 * @return the current time as UTC milliseconds from the epoch. 1999 * @stable ICU 2.0 2000 */ getTimeInMillis()2001 public long getTimeInMillis() { 2002 if (!isTimeSet) updateTime(); 2003 return time; 2004 } 2005 2006 /** 2007 * Sets this Calendar's current time from the given long value. 2008 * An IllegalIcuArgumentException is thrown when millis is outside the range permitted 2009 * by a Calendar object when in strict mode. 2010 * When in lenient mode the out of range values are pinned to their respective min/max. 2011 * @param millis the new time in UTC milliseconds from the epoch. 2012 * @stable ICU 2.0 2013 */ setTimeInMillis( long millis )2014 public void setTimeInMillis( long millis ) { 2015 if (millis > MAX_MILLIS) { 2016 if(isLenient()) { 2017 millis = MAX_MILLIS; 2018 } else { 2019 throw new IllegalArgumentException("millis value greater than upper bounds for a Calendar : " + millis); 2020 } 2021 } else if (millis < MIN_MILLIS) { 2022 if(isLenient()) { 2023 millis = MIN_MILLIS; 2024 } else { 2025 throw new IllegalArgumentException("millis value less than lower bounds for a Calendar : " + millis); 2026 } 2027 } 2028 time = millis; 2029 areFieldsSet = areAllFieldsSet = false; 2030 isTimeSet = areFieldsVirtuallySet = true; 2031 2032 for (int i=0; i<fields.length; ++i) { 2033 fields[i] = stamp[i] = 0; // UNSET == 0 2034 } 2035 2036 } 2037 2038 /** 2039 * Returns the value for a given time field. 2040 * @param field the given time field. 2041 * @return the value for the given time field. 2042 * @stable ICU 2.0 2043 */ get(int field)2044 public final int get(int field) 2045 { 2046 complete(); 2047 return fields[field]; 2048 } 2049 2050 /** 2051 * Returns the value for a given time field. This is an internal method 2052 * for subclasses that does <em>not</em> trigger any calculations. 2053 * @param field the given time field. 2054 * @return the value for the given time field. 2055 * @stable ICU 2.0 2056 */ internalGet(int field)2057 protected final int internalGet(int field) 2058 { 2059 return fields[field]; 2060 } 2061 2062 /** 2063 * Returns the value for a given time field, or return the given default 2064 * value if the field is not set. This is an internal method for 2065 * subclasses that does <em>not</em> trigger any calculations. 2066 * @param field the given time field. 2067 * @param defaultValue value to return if field is not set 2068 * @return the value for the given time field of defaultValue if the 2069 * field is unset 2070 * @stable ICU 2.0 2071 */ internalGet(int field, int defaultValue)2072 protected final int internalGet(int field, int defaultValue) { 2073 return (stamp[field] > UNSET) ? fields[field] : defaultValue; 2074 } 2075 2076 /** 2077 * Sets the time field with the given value. 2078 * @param field the given time field. 2079 * @param value the value to be set for the given time field. 2080 * @stable ICU 2.0 2081 */ set(int field, int value)2082 public final void set(int field, int value) 2083 { 2084 if (areFieldsVirtuallySet) { 2085 computeFields(); 2086 } 2087 fields[field] = value; 2088 /* Ensure that the fNextStamp value doesn't go pass max value for 32 bit integer */ 2089 if (nextStamp == STAMP_MAX) { 2090 recalculateStamp(); 2091 } 2092 stamp[field] = nextStamp++; 2093 isTimeSet = areFieldsSet = areFieldsVirtuallySet = false; 2094 } 2095 2096 /** 2097 * Sets the values for the fields year, month, and date. 2098 * Previous values of other fields are retained. If this is not desired, 2099 * call {@link #clear()} first. 2100 * @param year the value used to set the YEAR time field. 2101 * @param month the value used to set the MONTH time field. 2102 * Month value is 0-based. e.g., 0 for January. 2103 * @param date the value used to set the DATE time field. 2104 * @stable ICU 2.0 2105 */ set(int year, int month, int date)2106 public final void set(int year, int month, int date) 2107 { 2108 set(YEAR, year); 2109 set(MONTH, month); 2110 set(DATE, date); 2111 } 2112 2113 /** 2114 * Sets the values for the fields year, month, date, hour, and minute. 2115 * Previous values of other fields are retained. If this is not desired, 2116 * call {@link #clear()} first. 2117 * @param year the value used to set the YEAR time field. 2118 * @param month the value used to set the MONTH time field. 2119 * Month value is 0-based. e.g., 0 for January. 2120 * @param date the value used to set the DATE time field. 2121 * @param hour the value used to set the HOUR_OF_DAY time field. 2122 * @param minute the value used to set the MINUTE time field. 2123 * @stable ICU 2.0 2124 */ set(int year, int month, int date, int hour, int minute)2125 public final void set(int year, int month, int date, int hour, int minute) 2126 { 2127 set(YEAR, year); 2128 set(MONTH, month); 2129 set(DATE, date); 2130 set(HOUR_OF_DAY, hour); 2131 set(MINUTE, minute); 2132 } 2133 2134 /** 2135 * Sets the values for the fields year, month, date, hour, minute, and second. 2136 * Previous values of other fields are retained. If this is not desired, 2137 * call {@link #clear} first. 2138 * @param year the value used to set the YEAR time field. 2139 * @param month the value used to set the MONTH time field. 2140 * Month value is 0-based. e.g., 0 for January. 2141 * @param date the value used to set the DATE time field. 2142 * @param hour the value used to set the HOUR_OF_DAY time field. 2143 * @param minute the value used to set the MINUTE time field. 2144 * @param second the value used to set the SECOND time field. 2145 * @stable ICU 2.0 2146 */ set(int year, int month, int date, int hour, int minute, int second)2147 public final void set(int year, int month, int date, int hour, int minute, 2148 int second) 2149 { 2150 set(YEAR, year); 2151 set(MONTH, month); 2152 set(DATE, date); 2153 set(HOUR_OF_DAY, hour); 2154 set(MINUTE, minute); 2155 set(SECOND, second); 2156 } 2157 2158 // ------------------------------------- 2159 // For now the full getRelatedYear implementation is here; 2160 // per #10752 move the non-default implementation to subclasses 2161 // (default implementation will do no year adjustment) 2162 2163 /** 2164 * utility function for getRelatedYear 2165 */ gregoYearFromIslamicStart(int year)2166 private static int gregoYearFromIslamicStart(int year) { 2167 // ad hoc conversion, improve under #10752 2168 // rough est for now, ok for grego 1846-2138, 2169 // otherwise occasionally wrong (for 3% of years) 2170 int cycle, offset, shift = 0; 2171 if (year >= 1397) { 2172 cycle = (year - 1397) / 67; 2173 offset = (year - 1397) % 67; 2174 shift = 2*cycle + ((offset >= 33)? 1: 0); 2175 } else { 2176 cycle = (year - 1396) / 67 - 1; 2177 offset = -(year - 1396) % 67; 2178 shift = 2*cycle + ((offset <= 33)? 1: 0); 2179 } 2180 return year + 579 - shift; 2181 } 2182 2183 /** 2184 * @internal 2185 * @deprecated This API is ICU internal only. 2186 */ 2187 @Deprecated getRelatedYear()2188 public final int getRelatedYear() { 2189 int year = get(EXTENDED_YEAR); 2190 CalType type = CalType.GREGORIAN; 2191 String typeString = getType(); 2192 for (CalType testType : CalType.values()) { 2193 if (typeString.equals(testType.id)) { 2194 type = testType; 2195 break; 2196 } 2197 } 2198 switch (type) { 2199 case PERSIAN: 2200 year += 622; break; 2201 case HEBREW: 2202 year -= 3760; break; 2203 case CHINESE: 2204 year -= 2637; break; 2205 case INDIAN: 2206 year += 79; break; 2207 case COPTIC: 2208 year += 284; break; 2209 case ETHIOPIC: 2210 year += 8; break; 2211 case ETHIOPIC_AMETE_ALEM: 2212 year -=5492; break; 2213 case DANGI: 2214 year -= 2333; break; 2215 case ISLAMIC_CIVIL: 2216 case ISLAMIC: 2217 case ISLAMIC_UMALQURA: 2218 case ISLAMIC_TBLA: 2219 case ISLAMIC_RGSA: 2220 year = gregoYearFromIslamicStart(year); break; 2221 // case GREGORIAN: 2222 // case JAPANESE: 2223 // case BUDDHIST: 2224 // case ROC: 2225 // case ISO8601: 2226 default: 2227 // do nothing, EXTENDED_YEAR same as Gregorian 2228 break; 2229 } 2230 return year; 2231 } 2232 2233 // ------------------------------------- 2234 // For now the full setRelatedYear implementation is here; 2235 // per #10752 move the non-default implementation to subclasses 2236 // (default implementation will do no year adjustment) 2237 2238 /** 2239 * utility function for setRelatedYear 2240 */ firstIslamicStartYearFromGrego(int year)2241 private static int firstIslamicStartYearFromGrego(int year) { 2242 // ad hoc conversion, improve under #10752 2243 // rough est for now, ok for grego 1846-2138, 2244 // otherwise occasionally wrong (for 3% of years) 2245 int cycle, offset, shift = 0; 2246 if (year >= 1977) { 2247 cycle = (year - 1977) / 65; 2248 offset = (year - 1977) % 65; 2249 shift = 2*cycle + ((offset >= 32)? 1: 0); 2250 } else { 2251 cycle = (year - 1976) / 65 - 1; 2252 offset = -(year - 1976) % 65; 2253 shift = 2*cycle + ((offset <= 32)? 1: 0); 2254 } 2255 return year - 579 + shift; 2256 } 2257 2258 /** 2259 * @internal 2260 * @deprecated This API is ICU internal only. 2261 */ 2262 @Deprecated setRelatedYear(int year)2263 public final void setRelatedYear(int year) { 2264 CalType type = CalType.GREGORIAN; 2265 String typeString = getType(); 2266 for (CalType testType : CalType.values()) { 2267 if (typeString.equals(testType.id)) { 2268 type = testType; 2269 break; 2270 } 2271 } 2272 switch (type) { 2273 case PERSIAN: 2274 year -= 622; break; 2275 case HEBREW: 2276 year += 3760; break; 2277 case CHINESE: 2278 year += 2637; break; 2279 case INDIAN: 2280 year -= 79; break; 2281 case COPTIC: 2282 year -= 284; break; 2283 case ETHIOPIC: 2284 year -= 8; break; 2285 case ETHIOPIC_AMETE_ALEM: 2286 year +=5492; break; 2287 case DANGI: 2288 year += 2333; break; 2289 case ISLAMIC_CIVIL: 2290 case ISLAMIC: 2291 case ISLAMIC_UMALQURA: 2292 case ISLAMIC_TBLA: 2293 case ISLAMIC_RGSA: 2294 year = firstIslamicStartYearFromGrego(year); break; 2295 // case GREGORIAN: 2296 // case JAPANESE: 2297 // case BUDDHIST: 2298 // case ROC: 2299 // case ISO8601: 2300 default: 2301 // do nothing, EXTENDED_YEAR same as Gregorian 2302 break; 2303 } 2304 set(EXTENDED_YEAR, year); 2305 } 2306 2307 /** 2308 * Clears the values of all the time fields. 2309 * @stable ICU 2.0 2310 */ clear()2311 public final void clear() 2312 { 2313 for (int i=0; i<fields.length; ++i) { 2314 fields[i] = stamp[i] = 0; // UNSET == 0 2315 } 2316 isTimeSet = areFieldsSet = areAllFieldsSet = areFieldsVirtuallySet = false; 2317 } 2318 2319 /** 2320 * Clears the value in the given time field. 2321 * @param field the time field to be cleared. 2322 * @stable ICU 2.0 2323 */ clear(int field)2324 public final void clear(int field) 2325 { 2326 if (areFieldsVirtuallySet) { 2327 computeFields(); 2328 } 2329 fields[field] = 0; 2330 stamp[field] = UNSET; 2331 isTimeSet = areFieldsSet = areAllFieldsSet = areFieldsVirtuallySet = false; 2332 } 2333 2334 /** 2335 * Determines if the given time field has a value set. 2336 * @return true if the given time field has a value set; false otherwise. 2337 * @stable ICU 2.0 2338 */ isSet(int field)2339 public final boolean isSet(int field) 2340 { 2341 return areFieldsVirtuallySet || (stamp[field] != UNSET); 2342 } 2343 2344 /** 2345 * Fills in any unset fields in the time field list. 2346 * @stable ICU 2.0 2347 */ complete()2348 protected void complete() 2349 { 2350 if (!isTimeSet) updateTime(); 2351 if (!areFieldsSet) { 2352 computeFields(); // fills in unset fields 2353 areFieldsSet = true; 2354 areAllFieldsSet = true; 2355 } 2356 } 2357 2358 /** 2359 * Compares this calendar to the specified object. 2360 * The result is <code>true</code> if and only if the argument is 2361 * not <code>null</code> and is a <code>Calendar</code> object that 2362 * represents the same calendar as this object. 2363 * @param obj the object to compare with. 2364 * @return <code>true</code> if the objects are the same; 2365 * <code>false</code> otherwise. 2366 * @stable ICU 2.0 2367 */ equals(Object obj)2368 public boolean equals(Object obj) { 2369 if (obj == null) { 2370 return false; 2371 } 2372 if (this == obj) { 2373 return true; 2374 } 2375 if (this.getClass() != obj.getClass()) { 2376 return false; 2377 } 2378 2379 Calendar that = (Calendar) obj; 2380 2381 return isEquivalentTo(that) && 2382 getTimeInMillis() == that.getTime().getTime(); 2383 } 2384 2385 /** 2386 * {@icu} Returns true if the given Calendar object is equivalent to this 2387 * one. An equivalent Calendar will behave exactly as this one 2388 * does, but it may be set to a different time. By contrast, for 2389 * the equals() method to return true, the other Calendar must 2390 * be set to the same time. 2391 * 2392 * @param other the Calendar to be compared with this Calendar 2393 * @stable ICU 2.4 2394 */ isEquivalentTo(Calendar other)2395 public boolean isEquivalentTo(Calendar other) { 2396 return this.getClass() == other.getClass() && 2397 isLenient() == other.isLenient() && 2398 getFirstDayOfWeek() == other.getFirstDayOfWeek() && 2399 getMinimalDaysInFirstWeek() == other.getMinimalDaysInFirstWeek() && 2400 getTimeZone().equals(other.getTimeZone()) && 2401 getRepeatedWallTimeOption() == other.getRepeatedWallTimeOption() && 2402 getSkippedWallTimeOption() == other.getSkippedWallTimeOption(); 2403 } 2404 2405 /** 2406 * Returns a hash code for this calendar. 2407 * @return a hash code value for this object. 2408 * @stable ICU 2.0 2409 */ hashCode()2410 public int hashCode() { 2411 /* Don't include the time because (a) we don't want the hash value to 2412 * move around just because a calendar is set to different times, and 2413 * (b) we don't want to trigger a time computation just to get a hash. 2414 * Note that it is not necessary for unequal objects to always have 2415 * unequal hashes, but equal objects must have equal hashes. */ 2416 return (lenient ? 1 : 0) 2417 | (firstDayOfWeek << 1) 2418 | (minimalDaysInFirstWeek << 4) 2419 | (repeatedWallTime << 7) 2420 | (skippedWallTime << 9) 2421 | (zone.hashCode() << 11); 2422 } 2423 2424 /** 2425 * Returns the difference in milliseconds between the moment this 2426 * calendar is set to and the moment the given calendar or Date object 2427 * is set to. 2428 */ compare(Object that)2429 private long compare(Object that) { 2430 long thatMs; 2431 if (that instanceof Calendar) { 2432 thatMs = ((Calendar)that).getTimeInMillis(); 2433 } else if (that instanceof Date) { 2434 thatMs = ((Date)that).getTime(); 2435 } else { 2436 throw new IllegalArgumentException(that + "is not a Calendar or Date"); 2437 } 2438 return getTimeInMillis() - thatMs; 2439 } 2440 2441 /** 2442 * Compares the time field records. 2443 * Equivalent to comparing result of conversion to UTC. 2444 * @param when the Calendar to be compared with this Calendar. 2445 * @return true if the current time of this Calendar is before 2446 * the time of Calendar when; false otherwise. 2447 * @stable ICU 2.0 2448 */ before(Object when)2449 public boolean before(Object when) { 2450 return compare(when) < 0; 2451 } 2452 2453 /** 2454 * Compares the time field records. 2455 * Equivalent to comparing result of conversion to UTC. 2456 * @param when the Calendar to be compared with this Calendar. 2457 * @return true if the current time of this Calendar is after 2458 * the time of Calendar when; false otherwise. 2459 * @stable ICU 2.0 2460 */ after(Object when)2461 public boolean after(Object when) { 2462 return compare(when) > 0; 2463 } 2464 2465 /** 2466 * Returns the maximum value that this field could have, given the 2467 * current date. For example, with the Gregorian date February 3, 1997 2468 * and the {@link #DAY_OF_MONTH DAY_OF_MONTH} field, the actual maximum 2469 * is 28; for February 3, 1996 it is 29. 2470 * 2471 * <p>The actual maximum computation ignores smaller fields and the 2472 * current value of like-sized fields. For example, the actual maximum 2473 * of the DAY_OF_YEAR or MONTH depends only on the year and supra-year 2474 * fields. The actual maximum of the DAY_OF_MONTH depends, in 2475 * addition, on the MONTH field and any other fields at that 2476 * granularity (such as IS_LEAP_MONTH). The 2477 * DAY_OF_WEEK_IN_MONTH field does not depend on the current 2478 * DAY_OF_WEEK; it returns the maximum for any day of week in the 2479 * current month. Likewise for the WEEK_OF_MONTH and WEEK_OF_YEAR 2480 * fields. 2481 * 2482 * @param field the field whose maximum is desired 2483 * @return the maximum of the given field for the current date of this calendar 2484 * @see #getMaximum 2485 * @see #getLeastMaximum 2486 * @stable ICU 2.0 2487 */ getActualMaximum(int field)2488 public int getActualMaximum(int field) { 2489 int result; 2490 2491 switch (field) { 2492 case DAY_OF_MONTH: 2493 { 2494 Calendar cal = (Calendar) clone(); 2495 cal.setLenient(true); 2496 cal.prepareGetActual(field, false); 2497 result = handleGetMonthLength(cal.get(EXTENDED_YEAR), cal.get(MONTH)); 2498 } 2499 break; 2500 2501 case DAY_OF_YEAR: 2502 { 2503 Calendar cal = (Calendar) clone(); 2504 cal.setLenient(true); 2505 cal.prepareGetActual(field, false); 2506 result = handleGetYearLength(cal.get(EXTENDED_YEAR)); 2507 } 2508 break; 2509 2510 case ERA: 2511 case DAY_OF_WEEK: 2512 case AM_PM: 2513 case HOUR: 2514 case HOUR_OF_DAY: 2515 case MINUTE: 2516 case SECOND: 2517 case MILLISECOND: 2518 case ZONE_OFFSET: 2519 case DST_OFFSET: 2520 case DOW_LOCAL: 2521 case JULIAN_DAY: 2522 case MILLISECONDS_IN_DAY: 2523 // These fields all have fixed minima/maxima 2524 result = getMaximum(field); 2525 break; 2526 2527 default: 2528 // For all other fields, do it the hard way.... 2529 result = getActualHelper(field, getLeastMaximum(field), getMaximum(field)); 2530 break; 2531 } 2532 return result; 2533 } 2534 2535 /** 2536 * Returns the minimum value that this field could have, given the current date. 2537 * For most fields, this is the same as {@link #getMinimum getMinimum} 2538 * and {@link #getGreatestMinimum getGreatestMinimum}. However, some fields, 2539 * especially those related to week number, are more complicated. 2540 * <p> 2541 * For example, assume {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} 2542 * returns 4 and {@link #getFirstDayOfWeek getFirstDayOfWeek} returns SUNDAY. 2543 * If the first day of the month is Sunday, Monday, Tuesday, or Wednesday 2544 * there will be four or more days in the first week, so it will be week number 1, 2545 * and <code>getActualMinimum(WEEK_OF_MONTH)</code> will return 1. However, 2546 * if the first of the month is a Thursday, Friday, or Saturday, there are 2547 * <em>not</em> four days in that week, so it is week number 0, and 2548 * <code>getActualMinimum(WEEK_OF_MONTH)</code> will return 0. 2549 * <p> 2550 * @param field the field whose actual minimum value is desired. 2551 * @return the minimum of the given field for the current date of this calendar 2552 * 2553 * @see #getMinimum 2554 * @see #getGreatestMinimum 2555 * @stable ICU 2.0 2556 */ getActualMinimum(int field)2557 public int getActualMinimum(int field) { 2558 int result; 2559 2560 switch (field) { 2561 case DAY_OF_WEEK: 2562 case AM_PM: 2563 case HOUR: 2564 case HOUR_OF_DAY: 2565 case MINUTE: 2566 case SECOND: 2567 case MILLISECOND: 2568 case ZONE_OFFSET: 2569 case DST_OFFSET: 2570 case DOW_LOCAL: 2571 case JULIAN_DAY: 2572 case MILLISECONDS_IN_DAY: 2573 // These fields all have fixed minima/maxima 2574 result = getMinimum(field); 2575 break; 2576 2577 default: 2578 // For all other fields, do it the hard way.... 2579 result = getActualHelper(field, getGreatestMinimum(field), getMinimum(field)); 2580 break; 2581 } 2582 return result; 2583 } 2584 2585 /** 2586 * Prepare this calendar for computing the actual minimum or maximum. 2587 * This method modifies this calendar's fields; it is called on a 2588 * temporary calendar. 2589 * 2590 * <p>Rationale: The semantics of getActualXxx() is to return the 2591 * maximum or minimum value that the given field can take, taking into 2592 * account other relevant fields. In general these other fields are 2593 * larger fields. For example, when computing the actual maximum 2594 * DAY_OF_MONTH, the current value of DAY_OF_MONTH itself is ignored, 2595 * as is the value of any field smaller. 2596 * 2597 * <p>The time fields all have fixed minima and maxima, so we don't 2598 * need to worry about them. This also lets us set the 2599 * MILLISECONDS_IN_DAY to zero to erase any effects the time fields 2600 * might have when computing date fields. 2601 * 2602 * <p>DAY_OF_WEEK is adjusted specially for the WEEK_OF_MONTH and 2603 * WEEK_OF_YEAR fields to ensure that they are computed correctly. 2604 * @stable ICU 2.0 2605 */ prepareGetActual(int field, boolean isMinimum)2606 protected void prepareGetActual(int field, boolean isMinimum) { 2607 set(MILLISECONDS_IN_DAY, 0); 2608 2609 switch (field) { 2610 case YEAR: 2611 case EXTENDED_YEAR: 2612 set(DAY_OF_YEAR, getGreatestMinimum(DAY_OF_YEAR)); 2613 break; 2614 2615 case YEAR_WOY: 2616 set(WEEK_OF_YEAR, getGreatestMinimum(WEEK_OF_YEAR)); 2617 break; 2618 2619 case MONTH: 2620 set(DAY_OF_MONTH, getGreatestMinimum(DAY_OF_MONTH)); 2621 break; 2622 2623 case DAY_OF_WEEK_IN_MONTH: 2624 // For dowim, the maximum occurs for the DOW of the first of the 2625 // month. 2626 set(DAY_OF_MONTH, 1); 2627 set(DAY_OF_WEEK, get(DAY_OF_WEEK)); // Make this user set 2628 break; 2629 2630 case WEEK_OF_MONTH: 2631 case WEEK_OF_YEAR: 2632 // If we're counting weeks, set the day of the week to either the 2633 // first or last localized DOW. We know the last week of a month 2634 // or year will contain the first day of the week, and that the 2635 // first week will contain the last DOW. 2636 { 2637 int dow = firstDayOfWeek; 2638 if (isMinimum) { 2639 dow = (dow + 6) % 7; // set to last DOW 2640 if (dow < SUNDAY) { 2641 dow += 7; 2642 } 2643 } 2644 set(DAY_OF_WEEK, dow); 2645 } 2646 break; 2647 } 2648 2649 // Do this last to give it the newest time stamp 2650 set(field, getGreatestMinimum(field)); 2651 } 2652 getActualHelper(int field, int startValue, int endValue)2653 private int getActualHelper(int field, int startValue, int endValue) { 2654 2655 if (startValue == endValue) { 2656 // if we know that the maximum value is always the same, just return it 2657 return startValue; 2658 } 2659 2660 final int delta = (endValue > startValue) ? 1 : -1; 2661 2662 // clone the calendar so we don't mess with the real one, and set it to 2663 // accept anything for the field values 2664 Calendar work = (Calendar) clone(); 2665 2666 // need to resolve time here, otherwise, fields set for actual limit 2667 // may cause conflict with fields previously set (but not yet resolved). 2668 work.complete(); 2669 2670 work.setLenient(true); 2671 work.prepareGetActual(field, delta < 0); 2672 2673 // now try each value from the start to the end one by one until 2674 // we get a value that normalizes to another value. The last value that 2675 // normalizes to itself is the actual maximum for the current date 2676 2677 work.set(field, startValue); 2678 // prepareGetActual sets the first day of week in the same week with 2679 // the first day of a month. Unlike WEEK_OF_YEAR, week number for the 2680 // which week contains days from both previous and current month is 2681 // not unique. For example, last several days in the previous month 2682 // is week 5, and the rest of week is week 1. 2683 if (work.get(field) != startValue 2684 && field != WEEK_OF_MONTH && delta > 0) { 2685 return startValue; 2686 } 2687 int result = startValue; 2688 do { 2689 startValue += delta; 2690 work.add(field, delta); 2691 if (work.get(field) != startValue) { 2692 break; 2693 } 2694 result = startValue; 2695 } while (startValue != endValue); 2696 2697 return result; 2698 } 2699 2700 /** 2701 * Rolls (up/down) a single unit of time on the given field. If the 2702 * field is rolled past its maximum allowable value, it will "wrap" back 2703 * to its minimum and continue rolling. For 2704 * example, to roll the current date up by one day, you can call: 2705 * <p> 2706 * <code>roll({@link #DATE}, true)</code> 2707 * <p> 2708 * When rolling on the {@link #YEAR} field, it will roll the year 2709 * value in the range between 1 and the value returned by calling 2710 * {@link #getMaximum getMaximum}({@link #YEAR}). 2711 * <p> 2712 * When rolling on certain fields, the values of other fields may conflict and 2713 * need to be changed. For example, when rolling the <code>MONTH</code> field 2714 * for the Gregorian date 1/31/96 upward, the <code>DAY_OF_MONTH</code> field 2715 * must be adjusted so that the result is 2/29/96 rather than the invalid 2716 * 2/31/96. 2717 * <p> 2718 * Rolling up always means rolling forward in time (unless 2719 * the limit of the field is reached, in which case it may pin or wrap), so for the 2720 * Gregorian calendar, starting with 100 BC and rolling the year up results in 99 BC. 2721 * When eras have a definite beginning and end (as in the Chinese calendar, or as in 2722 * most eras in the Japanese calendar) then rolling the year past either limit of the 2723 * era will cause the year to wrap around. When eras only have a limit at one end, 2724 * then attempting to roll the year past that limit will result in pinning the year 2725 * at that limit. Note that for most calendars in which era 0 years move forward in 2726 * time (such as Buddhist, Hebrew, or Islamic), it is possible for add or roll to 2727 * result in negative years for era 0 (that is the only way to represent years before 2728 * the calendar epoch in such calendars). 2729 * <p> 2730 * <b>Note:</b> Calling <tt>roll(field, true)</tt> N times is <em>not</em> 2731 * necessarily equivalent to calling <tt>roll(field, N)</tt>. For example, 2732 * imagine that you start with the date Gregorian date January 31, 1995. If you call 2733 * <tt>roll(Calendar.MONTH, 2)</tt>, the result will be March 31, 1995. 2734 * But if you call <tt>roll(Calendar.MONTH, true)</tt>, the result will be 2735 * February 28, 1995. Calling it one more time will give March 28, 1995, which 2736 * is usually not the desired result. 2737 * <p> 2738 * <b>Note:</b> You should always use <tt>roll</tt> and <tt>add</tt> rather 2739 * than attempting to perform arithmetic operations directly on the fields 2740 * of a <tt>Calendar</tt>. It is quite possible for <tt>Calendar</tt> subclasses 2741 * to have fields with non-linear behavior, for example missing months 2742 * or days during non-leap years. The subclasses' <tt>add</tt> and <tt>roll</tt> 2743 * methods will take this into account, while simple arithmetic manipulations 2744 * may give invalid results. 2745 * <p> 2746 * @param field the calendar field to roll. 2747 * 2748 * @param up indicates if the value of the specified time field is to be 2749 * rolled up or rolled down. Use <code>true</code> if rolling up, 2750 * <code>false</code> otherwise. 2751 * 2752 * @exception IllegalArgumentException if the field is invalid or refers 2753 * to a field that cannot be handled by this method. 2754 * @see #roll(int, int) 2755 * @see #add 2756 * @stable ICU 2.0 2757 */ roll(int field, boolean up)2758 public final void roll(int field, boolean up) 2759 { 2760 roll(field, up ? +1 : -1); 2761 } 2762 2763 /** 2764 * Rolls (up/down) a specified amount time on the given field. For 2765 * example, to roll the current date up by three days, you can call 2766 * <code>roll(Calendar.DATE, 3)</code>. If the 2767 * field is rolled past its maximum allowable value, it will "wrap" back 2768 * to its minimum and continue rolling. 2769 * For example, calling <code>roll(Calendar.DATE, 10)</code> 2770 * on a Gregorian calendar set to 4/25/96 will result in the date 4/5/96. 2771 * <p> 2772 * When rolling on certain fields, the values of other fields may conflict and 2773 * need to be changed. For example, when rolling the {@link #MONTH MONTH} field 2774 * for the Gregorian date 1/31/96 by +1, the {@link #DAY_OF_MONTH DAY_OF_MONTH} field 2775 * must be adjusted so that the result is 2/29/96 rather than the invalid 2776 * 2/31/96. 2777 * <p> 2778 * Rolling by a positive value always means rolling forward in time (unless 2779 * the limit of the field is reached, in which case it may pin or wrap), so for the 2780 * Gregorian calendar, starting with 100 BC and rolling the year by + 1 results in 99 BC. 2781 * When eras have a definite beginning and end (as in the Chinese calendar, or as in 2782 * most eras in the Japanese calendar) then rolling the year past either limit of the 2783 * era will cause the year to wrap around. When eras only have a limit at one end, 2784 * then attempting to roll the year past that limit will result in pinning the year 2785 * at that limit. Note that for most calendars in which era 0 years move forward in 2786 * time (such as Buddhist, Hebrew, or Islamic), it is possible for add or roll to 2787 * result in negative years for era 0 (that is the only way to represent years before 2788 * the calendar epoch in such calendars). 2789 * <p> 2790 * {@icunote} the ICU implementation of this method is able to roll 2791 * all fields except for {@link #ERA ERA}, {@link #DST_OFFSET DST_OFFSET}, 2792 * and {@link #ZONE_OFFSET ZONE_OFFSET}. Subclasses may, of course, add support for 2793 * additional fields in their overrides of <code>roll</code>. 2794 * <p> 2795 * <b>Note:</b> You should always use <tt>roll</tt> and <tt>add</tt> rather 2796 * than attempting to perform arithmetic operations directly on the fields 2797 * of a <tt>Calendar</tt>. It is quite possible for <tt>Calendar</tt> subclasses 2798 * to have fields with non-linear behavior, for example missing months 2799 * or days during non-leap years. The subclasses' <tt>add</tt> and <tt>roll</tt> 2800 * methods will take this into account, while simple arithmetic manipulations 2801 * may give invalid results. 2802 * <p> 2803 * <b>Subclassing:</b><br> 2804 * This implementation of <code>roll</code> assumes that the behavior of the 2805 * field is continuous between its minimum and maximum, which are found by 2806 * calling {@link #getActualMinimum getActualMinimum} and {@link #getActualMaximum getActualMaximum}. 2807 * For most such fields, simple addition, subtraction, and modulus operations 2808 * are sufficient to perform the roll. For week-related fields, 2809 * the results of {@link #getFirstDayOfWeek getFirstDayOfWeek} and 2810 * {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} are also necessary. 2811 * Subclasses can override these two methods if their values differ from the defaults. 2812 * <p> 2813 * Subclasses that have fields for which the assumption of continuity breaks 2814 * down must overide <code>roll</code> to handle those fields specially. 2815 * For example, in the Hebrew calendar the month "Adar I" 2816 * only occurs in leap years; in other years the calendar jumps from 2817 * Shevat (month #4) to Adar (month #6). The 2818 * {@link HebrewCalendar#roll HebrewCalendar.roll} method takes this into account, 2819 * so that rolling the month of Shevat by one gives the proper result (Adar) in a 2820 * non-leap year. 2821 * <p> 2822 * @param field the calendar field to roll. 2823 * @param amount the amount by which the field should be rolled. 2824 * 2825 * @exception IllegalArgumentException if the field is invalid or refers 2826 * to a field that cannot be handled by this method. 2827 * @see #roll(int, boolean) 2828 * @see #add 2829 * @stable ICU 2.0 2830 */ roll(int field, int amount)2831 public void roll(int field, int amount) { 2832 2833 if (amount == 0) { 2834 return; // Nothing to do 2835 } 2836 2837 complete(); 2838 2839 switch (field) { 2840 case DAY_OF_MONTH: 2841 case AM_PM: 2842 case MINUTE: 2843 case SECOND: 2844 case MILLISECOND: 2845 case MILLISECONDS_IN_DAY: 2846 case ERA: 2847 // These are the standard roll instructions. These work for all 2848 // simple cases, that is, cases in which the limits are fixed, such 2849 // as the hour, the day of the month, and the era. 2850 { 2851 int min = getActualMinimum(field); 2852 int max = getActualMaximum(field); 2853 int gap = max - min + 1; 2854 2855 int value = internalGet(field) + amount; 2856 value = (value - min) % gap; 2857 if (value < 0) { 2858 value += gap; 2859 } 2860 value += min; 2861 2862 set(field, value); 2863 return; 2864 } 2865 2866 case HOUR: 2867 case HOUR_OF_DAY: 2868 // Rolling the hour is difficult on the ONSET and CEASE days of 2869 // daylight savings. For example, if the change occurs at 2870 // 2 AM, we have the following progression: 2871 // ONSET: 12 Std -> 1 Std -> 3 Dst -> 4 Dst 2872 // CEASE: 12 Dst -> 1 Dst -> 1 Std -> 2 Std 2873 // To get around this problem we don't use fields; we manipulate 2874 // the time in millis directly. 2875 { 2876 // Assume min == 0 in calculations below 2877 long start = getTimeInMillis(); 2878 int oldHour = internalGet(field); 2879 int max = getMaximum(field); 2880 int newHour = (oldHour + amount) % (max + 1); 2881 if (newHour < 0) { 2882 newHour += max + 1; 2883 } 2884 setTimeInMillis(start + ONE_HOUR * ((long)newHour - oldHour)); 2885 return; 2886 } 2887 2888 case MONTH: 2889 // Rolling the month involves both pinning the final value 2890 // and adjusting the DAY_OF_MONTH if necessary. We only adjust the 2891 // DAY_OF_MONTH if, after updating the MONTH field, it is illegal. 2892 // E.g., <jan31>.roll(MONTH, 1) -> <feb28> or <feb29>. 2893 { 2894 int max = getActualMaximum(MONTH); 2895 int mon = (internalGet(MONTH) + amount) % (max+1); 2896 2897 if (mon < 0) { 2898 mon += (max + 1); 2899 } 2900 set(MONTH, mon); 2901 2902 // Keep the day of month in range. We don't want to spill over 2903 // into the next month; e.g., we don't want jan31 + 1 mo -> feb31 -> 2904 // mar3. 2905 pinField(DAY_OF_MONTH); 2906 return; 2907 } 2908 2909 case YEAR: 2910 case YEAR_WOY: 2911 // * If era==0 and years go backwards in time, change sign of amount. 2912 // * Until we have new API per #9393, we temporarily hardcode knowledge of 2913 // which calendars have era 0 years that go backwards. 2914 { 2915 boolean era0WithYearsThatGoBackwards = false; 2916 int era = get(ERA); 2917 if (era == 0) { 2918 String calType = getType(); 2919 if (calType.equals("gregorian") || calType.equals("roc") || calType.equals("coptic")) { 2920 amount = -amount; 2921 era0WithYearsThatGoBackwards = true; 2922 } 2923 } 2924 int newYear = internalGet(field) + amount; 2925 if (era > 0 || newYear >= 1) { 2926 int maxYear = getActualMaximum(field); 2927 if (maxYear < 32768) { 2928 // this era has real bounds, roll should wrap years 2929 if (newYear < 1) { 2930 newYear = maxYear - ((-newYear) % maxYear); 2931 } else if (newYear > maxYear) { 2932 newYear = ((newYear - 1) % maxYear) + 1; 2933 } 2934 // else era is unbounded, just pin low year instead of wrapping 2935 } else if (newYear < 1) { 2936 newYear = 1; 2937 } 2938 // else we are in era 0 with newYear < 1; 2939 // calendars with years that go backwards must pin the year value at 0, 2940 // other calendars can have years < 0 in era 0 2941 } else if (era0WithYearsThatGoBackwards) { 2942 newYear = 1; 2943 } 2944 set(field, newYear); 2945 pinField(MONTH); 2946 pinField(DAY_OF_MONTH); 2947 return; 2948 } 2949 case EXTENDED_YEAR: 2950 // Rolling the year can involve pinning the DAY_OF_MONTH. 2951 set(field, internalGet(field) + amount); 2952 pinField(MONTH); 2953 pinField(DAY_OF_MONTH); 2954 return; 2955 2956 case WEEK_OF_MONTH: 2957 { 2958 // This is tricky, because during the roll we may have to shift 2959 // to a different day of the week. For example: 2960 2961 // s m t w r f s 2962 // 1 2 3 4 5 2963 // 6 7 8 9 10 11 12 2964 2965 // When rolling from the 6th or 7th back one week, we go to the 2966 // 1st (assuming that the first partial week counts). The same 2967 // thing happens at the end of the month. 2968 2969 // The other tricky thing is that we have to figure out whether 2970 // the first partial week actually counts or not, based on the 2971 // minimal first days in the week. And we have to use the 2972 // correct first day of the week to delineate the week 2973 // boundaries. 2974 2975 // Here's our algorithm. First, we find the real boundaries of 2976 // the month. Then we discard the first partial week if it 2977 // doesn't count in this locale. Then we fill in the ends with 2978 // phantom days, so that the first partial week and the last 2979 // partial week are full weeks. We then have a nice square 2980 // block of weeks. We do the usual rolling within this block, 2981 // as is done elsewhere in this method. If we wind up on one of 2982 // the phantom days that we added, we recognize this and pin to 2983 // the first or the last day of the month. Easy, eh? 2984 2985 // Normalize the DAY_OF_WEEK so that 0 is the first day of the week 2986 // in this locale. We have dow in 0..6. 2987 int dow = internalGet(DAY_OF_WEEK) - getFirstDayOfWeek(); 2988 if (dow < 0) dow += 7; 2989 2990 // Find the day of the week (normalized for locale) for the first 2991 // of the month. 2992 int fdm = (dow - internalGet(DAY_OF_MONTH) + 1) % 7; 2993 if (fdm < 0) fdm += 7; 2994 2995 // Get the first day of the first full week of the month, 2996 // including phantom days, if any. Figure out if the first week 2997 // counts or not; if it counts, then fill in phantom days. If 2998 // not, advance to the first real full week (skip the partial week). 2999 int start; 3000 if ((7 - fdm) < getMinimalDaysInFirstWeek()) 3001 start = 8 - fdm; // Skip the first partial week 3002 else 3003 start = 1 - fdm; // This may be zero or negative 3004 3005 // Get the day of the week (normalized for locale) for the last 3006 // day of the month. 3007 int monthLen = getActualMaximum(DAY_OF_MONTH); 3008 int ldm = (monthLen - internalGet(DAY_OF_MONTH) + dow) % 7; 3009 // We know monthLen >= DAY_OF_MONTH so we skip the += 7 step here. 3010 3011 // Get the limit day for the blocked-off rectangular month; that 3012 // is, the day which is one past the last day of the month, 3013 // after the month has already been filled in with phantom days 3014 // to fill out the last week. This day has a normalized DOW of 0. 3015 int limit = monthLen + 7 - ldm; 3016 3017 // Now roll between start and (limit - 1). 3018 int gap = limit - start; 3019 int day_of_month = (internalGet(DAY_OF_MONTH) + amount*7 - 3020 start) % gap; 3021 if (day_of_month < 0) day_of_month += gap; 3022 day_of_month += start; 3023 3024 // Finally, pin to the real start and end of the month. 3025 if (day_of_month < 1) day_of_month = 1; 3026 if (day_of_month > monthLen) day_of_month = monthLen; 3027 3028 // Set the DAY_OF_MONTH. We rely on the fact that this field 3029 // takes precedence over everything else (since all other fields 3030 // are also set at this point). If this fact changes (if the 3031 // disambiguation algorithm changes) then we will have to unset 3032 // the appropriate fields here so that DAY_OF_MONTH is attended 3033 // to. 3034 set(DAY_OF_MONTH, day_of_month); 3035 return; 3036 } 3037 case WEEK_OF_YEAR: 3038 { 3039 // This follows the outline of WEEK_OF_MONTH, except it applies 3040 // to the whole year. Please see the comment for WEEK_OF_MONTH 3041 // for general notes. 3042 3043 // Normalize the DAY_OF_WEEK so that 0 is the first day of the week 3044 // in this locale. We have dow in 0..6. 3045 int dow = internalGet(DAY_OF_WEEK) - getFirstDayOfWeek(); 3046 if (dow < 0) dow += 7; 3047 3048 // Find the day of the week (normalized for locale) for the first 3049 // of the year. 3050 int fdy = (dow - internalGet(DAY_OF_YEAR) + 1) % 7; 3051 if (fdy < 0) fdy += 7; 3052 3053 // Get the first day of the first full week of the year, 3054 // including phantom days, if any. Figure out if the first week 3055 // counts or not; if it counts, then fill in phantom days. If 3056 // not, advance to the first real full week (skip the partial week). 3057 int start; 3058 if ((7 - fdy) < getMinimalDaysInFirstWeek()) 3059 start = 8 - fdy; // Skip the first partial week 3060 else 3061 start = 1 - fdy; // This may be zero or negative 3062 3063 // Get the day of the week (normalized for locale) for the last 3064 // day of the year. 3065 int yearLen = getActualMaximum(DAY_OF_YEAR); 3066 int ldy = (yearLen - internalGet(DAY_OF_YEAR) + dow) % 7; 3067 // We know yearLen >= DAY_OF_YEAR so we skip the += 7 step here. 3068 3069 // Get the limit day for the blocked-off rectangular year; that 3070 // is, the day which is one past the last day of the year, 3071 // after the year has already been filled in with phantom days 3072 // to fill out the last week. This day has a normalized DOW of 0. 3073 int limit = yearLen + 7 - ldy; 3074 3075 // Now roll between start and (limit - 1). 3076 int gap = limit - start; 3077 int day_of_year = (internalGet(DAY_OF_YEAR) + amount*7 - 3078 start) % gap; 3079 if (day_of_year < 0) day_of_year += gap; 3080 day_of_year += start; 3081 3082 // Finally, pin to the real start and end of the month. 3083 if (day_of_year < 1) day_of_year = 1; 3084 if (day_of_year > yearLen) day_of_year = yearLen; 3085 3086 // Make sure that the year and day of year are attended to by 3087 // clearing other fields which would normally take precedence. 3088 // If the disambiguation algorithm is changed, this section will 3089 // have to be updated as well. 3090 set(DAY_OF_YEAR, day_of_year); 3091 clear(MONTH); 3092 return; 3093 } 3094 case DAY_OF_YEAR: 3095 { 3096 // Roll the day of year using millis. Compute the millis for 3097 // the start of the year, and get the length of the year. 3098 long delta = amount * ONE_DAY; // Scale up from days to millis 3099 long min2 = time - (internalGet(DAY_OF_YEAR) - 1) * ONE_DAY; 3100 int yearLength = getActualMaximum(DAY_OF_YEAR); 3101 time = (time + delta - min2) % (yearLength*ONE_DAY); 3102 if (time < 0) time += yearLength*ONE_DAY; 3103 setTimeInMillis(time + min2); 3104 return; 3105 } 3106 case DAY_OF_WEEK: 3107 case DOW_LOCAL: 3108 { 3109 // Roll the day of week using millis. Compute the millis for 3110 // the start of the week, using the first day of week setting. 3111 // Restrict the millis to [start, start+7days). 3112 long delta = amount * ONE_DAY; // Scale up from days to millis 3113 // Compute the number of days before the current day in this 3114 // week. This will be a value 0..6. 3115 int leadDays = internalGet(field); 3116 leadDays -= (field == DAY_OF_WEEK) ? getFirstDayOfWeek() : 1; 3117 if (leadDays < 0) leadDays += 7; 3118 long min2 = time - leadDays * ONE_DAY; 3119 time = (time + delta - min2) % ONE_WEEK; 3120 if (time < 0) time += ONE_WEEK; 3121 setTimeInMillis(time + min2); 3122 return; 3123 } 3124 case DAY_OF_WEEK_IN_MONTH: 3125 { 3126 // Roll the day of week in the month using millis. Determine 3127 // the first day of the week in the month, and then the last, 3128 // and then roll within that range. 3129 long delta = amount * ONE_WEEK; // Scale up from weeks to millis 3130 // Find the number of same days of the week before this one 3131 // in this month. 3132 int preWeeks = (internalGet(DAY_OF_MONTH) - 1) / 7; 3133 // Find the number of same days of the week after this one 3134 // in this month. 3135 int postWeeks = (getActualMaximum(DAY_OF_MONTH) - 3136 internalGet(DAY_OF_MONTH)) / 7; 3137 // From these compute the min and gap millis for rolling. 3138 long min2 = time - preWeeks * ONE_WEEK; 3139 long gap2 = ONE_WEEK * (preWeeks + postWeeks + 1); // Must add 1! 3140 // Roll within this range 3141 time = (time + delta - min2) % gap2; 3142 if (time < 0) time += gap2; 3143 setTimeInMillis(time + min2); 3144 return; 3145 } 3146 case JULIAN_DAY: 3147 set(field, internalGet(field) + amount); 3148 return; 3149 default: 3150 // Other fields cannot be rolled by this method 3151 throw new IllegalArgumentException("Calendar.roll(" + fieldName(field) + 3152 ") not supported"); 3153 } 3154 } 3155 3156 /** 3157 * Add a signed amount to a specified field, using this calendar's rules. 3158 * For example, to add three days to the current date, you can call 3159 * <code>add(Calendar.DATE, 3)</code>. 3160 * <p> 3161 * When adding to certain fields, the values of other fields may conflict and 3162 * need to be changed. For example, when adding one to the {@link #MONTH MONTH} field 3163 * for the Gregorian date 1/31/96, the {@link #DAY_OF_MONTH DAY_OF_MONTH} field 3164 * must be adjusted so that the result is 2/29/96 rather than the invalid 3165 * 2/31/96. 3166 * <p> 3167 * Adding a positive value always means moving forward in time, so for the Gregorian 3168 * calendar, starting with 100 BC and adding +1 to year results in 99 BC (even though 3169 * this actually reduces the numeric value of the field itself). 3170 * <p> 3171 * {@icunote} The ICU implementation of this method is able to add to 3172 * all fields except for {@link #ERA ERA}, {@link #DST_OFFSET DST_OFFSET}, 3173 * and {@link #ZONE_OFFSET ZONE_OFFSET}. Subclasses may, of course, add support for 3174 * additional fields in their overrides of <code>add</code>. 3175 * <p> 3176 * <b>Note:</b> You should always use <tt>roll</tt> and <tt>add</tt> rather 3177 * than attempting to perform arithmetic operations directly on the fields 3178 * of a <tt>Calendar</tt>. It is quite possible for <tt>Calendar</tt> subclasses 3179 * to have fields with non-linear behavior, for example missing months 3180 * or days during non-leap years. The subclasses' <tt>add</tt> and <tt>roll</tt> 3181 * methods will take this into account, while simple arithmetic manipulations 3182 * may give invalid results. 3183 * <p> 3184 * <b>Subclassing:</b><br> 3185 * This implementation of <code>add</code> assumes that the behavior of the 3186 * field is continuous between its minimum and maximum, which are found by 3187 * calling {@link #getActualMinimum getActualMinimum} and 3188 * {@link #getActualMaximum getActualMaximum}. 3189 * For such fields, simple arithmetic operations are sufficient to 3190 * perform the add. 3191 * <p> 3192 * Subclasses that have fields for which this assumption of continuity breaks 3193 * down must overide <code>add</code> to handle those fields specially. 3194 * For example, in the Hebrew calendar the month "Adar I" 3195 * only occurs in leap years; in other years the calendar jumps from 3196 * Shevat (month #4) to Adar (month #6). The 3197 * {@link HebrewCalendar#add HebrewCalendar.add} method takes this into account, 3198 * so that adding one month 3199 * to a date in Shevat gives the proper result (Adar) in a non-leap year. 3200 * <p> 3201 * @param field the time field. 3202 * @param amount the amount to add to the field. 3203 * 3204 * @exception IllegalArgumentException if the field is invalid or refers 3205 * to a field that cannot be handled by this method. 3206 * @see #roll(int, int) 3207 * @stable ICU 2.0 3208 */ 3209 @SuppressWarnings("fallthrough") add(int field, int amount)3210 public void add(int field, int amount) { 3211 3212 if (amount == 0) { 3213 return; // Do nothing! 3214 } 3215 3216 // We handle most fields in the same way. The algorithm is to add 3217 // a computed amount of millis to the current millis. The only 3218 // wrinkle is with DST (and/or a change to the zone's UTC offset, which 3219 // we'll include with DST) -- for some fields, like the DAY_OF_MONTH, 3220 // we don't want the wall time to shift due to changes in DST. If the 3221 // result of the add operation is to move from DST to Standard, or 3222 // vice versa, we need to adjust by an hour forward or back, 3223 // respectively. For such fields we set keepWallTimeInvariant to true. 3224 3225 // We only adjust the DST for fields larger than an hour. For 3226 // fields smaller than an hour, we cannot adjust for DST without 3227 // causing problems. for instance, if you add one hour to April 5, 3228 // 1998, 1:00 AM, in PST, the time becomes "2:00 AM PDT" (an 3229 // illegal value), but then the adjustment sees the change and 3230 // compensates by subtracting an hour. As a result the time 3231 // doesn't advance at all. 3232 3233 // For some fields larger than a day, such as a MONTH, we pin the 3234 // DAY_OF_MONTH. This allows <March 31>.add(MONTH, 1) to be 3235 // <April 30>, rather than <April 31> => <May 1>. 3236 3237 long delta = amount; // delta in ms 3238 boolean keepWallTimeInvariant = true; 3239 3240 switch (field) { 3241 case ERA: 3242 set(field, get(field) + amount); 3243 pinField(ERA); 3244 return; 3245 3246 case YEAR: 3247 case YEAR_WOY: 3248 // * If era=0 and years go backwards in time, change sign of amount. 3249 // * Until we have new API per #9393, we temporarily hardcode knowledge of 3250 // which calendars have era 0 years that go backwards. 3251 // * Note that for YEAR (but not YEAR_WOY) we could instead handle 3252 // this by applying the amount to the EXTENDED_YEAR field; but since 3253 // we would still need to handle YEAR_WOY as below, might as well 3254 // also handle YEAR the same way. 3255 { 3256 int era = get(ERA); 3257 if (era == 0) { 3258 String calType = getType(); 3259 if (calType.equals("gregorian") || calType.equals("roc") || calType.equals("coptic")) { 3260 amount = -amount; 3261 } 3262 } 3263 } 3264 // Fall through into standard handling 3265 case EXTENDED_YEAR: 3266 case MONTH: 3267 { 3268 boolean oldLenient = isLenient(); 3269 setLenient(true); 3270 set(field, get(field) + amount); 3271 pinField(DAY_OF_MONTH); 3272 if(oldLenient==false) { 3273 complete(); 3274 setLenient(oldLenient); 3275 } 3276 } 3277 return; 3278 3279 case WEEK_OF_YEAR: 3280 case WEEK_OF_MONTH: 3281 case DAY_OF_WEEK_IN_MONTH: 3282 delta *= ONE_WEEK; 3283 break; 3284 3285 case AM_PM: 3286 delta *= 12 * ONE_HOUR; 3287 break; 3288 3289 case DAY_OF_MONTH: 3290 case DAY_OF_YEAR: 3291 case DAY_OF_WEEK: 3292 case DOW_LOCAL: 3293 case JULIAN_DAY: 3294 delta *= ONE_DAY; 3295 break; 3296 3297 case HOUR_OF_DAY: 3298 case HOUR: 3299 delta *= ONE_HOUR; 3300 keepWallTimeInvariant = false; 3301 break; 3302 3303 case MINUTE: 3304 delta *= ONE_MINUTE; 3305 keepWallTimeInvariant = false; 3306 break; 3307 3308 case SECOND: 3309 delta *= ONE_SECOND; 3310 keepWallTimeInvariant = false; 3311 break; 3312 3313 case MILLISECOND: 3314 case MILLISECONDS_IN_DAY: 3315 keepWallTimeInvariant = false; 3316 break; 3317 3318 default: 3319 throw new IllegalArgumentException("Calendar.add(" + fieldName(field) + 3320 ") not supported"); 3321 } 3322 3323 // In order to keep the wall time invariant (for fields where this is 3324 // appropriate), check the combined DST & ZONE offset before and 3325 // after the add() operation. If it changes, then adjust the millis 3326 // to compensate. 3327 int prevOffset = 0; 3328 int prevWallTime = 0; 3329 if (keepWallTimeInvariant) { 3330 prevOffset = get(DST_OFFSET) + get(ZONE_OFFSET); 3331 prevWallTime = get(MILLISECONDS_IN_DAY); 3332 } 3333 3334 setTimeInMillis(getTimeInMillis() + delta); 3335 3336 if (keepWallTimeInvariant) { 3337 int newWallTime = get(MILLISECONDS_IN_DAY); 3338 if (newWallTime != prevWallTime) { 3339 // There is at least one zone transition between the base 3340 // time and the result time. As the result, wall time has 3341 // changed. 3342 long t = internalGetTimeInMillis(); 3343 int newOffset = get(DST_OFFSET) + get(ZONE_OFFSET); 3344 if (newOffset != prevOffset) { 3345 // When the difference of the previous UTC offset and 3346 // the new UTC offset exceeds 1 full day, we do not want 3347 // to roll over/back the date. For now, this only happens 3348 // in Samoa (Pacific/Apia) on Dec 30, 2011. See ticket:9452. 3349 long adjAmount = (prevOffset - newOffset) % ONE_DAY; 3350 if (adjAmount != 0) { 3351 setTimeInMillis(t + adjAmount); 3352 newWallTime = get(MILLISECONDS_IN_DAY); 3353 } 3354 if (newWallTime != prevWallTime) { 3355 // The result wall time or adjusted wall time was shifted because 3356 // the target wall time does not exist on the result date. 3357 switch (skippedWallTime) { 3358 case WALLTIME_FIRST: 3359 if (adjAmount > 0) { 3360 setTimeInMillis(t); 3361 } 3362 break; 3363 case WALLTIME_LAST: 3364 if (adjAmount < 0) { 3365 setTimeInMillis(t); 3366 } 3367 break; 3368 case WALLTIME_NEXT_VALID: 3369 long tmpT = adjAmount > 0 ? internalGetTimeInMillis() : t; 3370 Long immediatePrevTrans = getImmediatePreviousZoneTransition(tmpT); 3371 if (immediatePrevTrans != null) { 3372 setTimeInMillis(immediatePrevTrans); 3373 } else { 3374 throw new RuntimeException("Could not locate a time zone transition before " + tmpT); 3375 } 3376 break; 3377 } 3378 } 3379 } 3380 } 3381 } 3382 } 3383 3384 /** 3385 * Returns the name of this calendar in the language of the given locale. 3386 * @stable ICU 2.0 3387 */ getDisplayName(Locale loc)3388 public String getDisplayName(Locale loc) { 3389 return this.getClass().getName(); 3390 } 3391 3392 /** 3393 * Returns the name of this calendar in the language of the given locale. 3394 * @stable ICU 3.2 3395 */ getDisplayName(ULocale loc)3396 public String getDisplayName(ULocale loc) { 3397 return this.getClass().getName(); 3398 } 3399 3400 /** 3401 * Compares the times (in millis) represented by two 3402 * <code>Calendar</code> objects. 3403 * 3404 * @param that the <code>Calendar</code> to compare to this. 3405 * @return <code>0</code> if the time represented by 3406 * this <code>Calendar</code> is equal to the time represented 3407 * by that <code>Calendar</code>, a value less than 3408 * <code>0</code> if the time represented by this is before 3409 * the time represented by that, and a value greater than 3410 * <code>0</code> if the time represented by this 3411 * is after the time represented by that. 3412 * @throws NullPointerException if that 3413 * <code>Calendar</code> is null. 3414 * @throws IllegalArgumentException if the time of that 3415 * <code>Calendar</code> can't be obtained because of invalid 3416 * calendar values. 3417 * @stable ICU 3.4 3418 */ compareTo(Calendar that)3419 public int compareTo(Calendar that) { 3420 long v = getTimeInMillis() - that.getTimeInMillis(); 3421 return v < 0 ? -1 : (v > 0 ? 1 : 0); 3422 } 3423 3424 //------------------------------------------------------------------------- 3425 // Interface for creating custon DateFormats for different types of Calendars 3426 //------------------------------------------------------------------------- 3427 3428 /** 3429 * {@icu} Returns a <code>DateFormat</code> appropriate to this calendar. 3430 * Subclasses wishing to specialize this behavior should override 3431 * {@link #handleGetDateFormat}. 3432 * @stable ICU 2.0 3433 */ getDateTimeFormat(int dateStyle, int timeStyle, Locale loc)3434 public DateFormat getDateTimeFormat(int dateStyle, int timeStyle, Locale loc) { 3435 return formatHelper(this, ULocale.forLocale(loc), dateStyle, timeStyle); 3436 } 3437 3438 /** 3439 * {@icu} Returns a <code>DateFormat</code> appropriate to this calendar. 3440 * Subclasses wishing to specialize this behavior should override 3441 * {@link #handleGetDateFormat}. 3442 * @stable ICU 3.2 3443 */ getDateTimeFormat(int dateStyle, int timeStyle, ULocale loc)3444 public DateFormat getDateTimeFormat(int dateStyle, int timeStyle, ULocale loc) { 3445 return formatHelper(this, loc, dateStyle, timeStyle); 3446 } 3447 3448 /** 3449 * Creates a <code>DateFormat</code> appropriate to this calendar. 3450 * This is a framework method for subclasses to override. This method 3451 * is responsible for creating the calendar-specific DateFormat and 3452 * DateFormatSymbols objects as needed. 3453 * @param pattern the pattern, specific to the <code>DateFormat</code> 3454 * subclass 3455 * @param locale the locale for which the symbols should be drawn 3456 * @return a <code>DateFormat</code> appropriate to this calendar 3457 * @stable ICU 2.0 3458 */ handleGetDateFormat(String pattern, Locale locale)3459 protected DateFormat handleGetDateFormat(String pattern, Locale locale) { 3460 return handleGetDateFormat(pattern, null, ULocale.forLocale(locale)); 3461 } 3462 3463 /** 3464 * Creates a <code>DateFormat</code> appropriate to this calendar. 3465 * This is a framework method for subclasses to override. This method 3466 * is responsible for creating the calendar-specific DateFormat and 3467 * DateFormatSymbols objects as needed. 3468 * @param pattern the pattern, specific to the <code>DateFormat</code> 3469 * subclass 3470 * @param override The override string. A numbering system override string can take one of the following forms: 3471 * 1). If just a numbering system name is specified, it applies to all numeric fields in the date format pattern. 3472 * 2). To specify an alternate numbering system on a field by field basis, use the field letters from the pattern 3473 * followed by an = sign, followed by the numbering system name. For example, to specify that just the year 3474 * be formatted using Hebrew digits, use the override "y=hebr". Multiple overrides can be specified in a single 3475 * string by separating them with a semi-colon. For example, the override string "m=thai;y=deva" would format using 3476 * Thai digits for the month and Devanagari digits for the year. 3477 * @param locale the locale for which the symbols should be drawn 3478 * @return a <code>DateFormat</code> appropriate to this calendar 3479 * @stable ICU 4.2 3480 */ handleGetDateFormat(String pattern, String override, Locale locale)3481 protected DateFormat handleGetDateFormat(String pattern, String override, Locale locale) { 3482 return handleGetDateFormat(pattern, override, ULocale.forLocale(locale)); 3483 } 3484 3485 /** 3486 * Creates a <code>DateFormat</code> appropriate to this calendar. 3487 * This is a framework method for subclasses to override. This method 3488 * is responsible for creating the calendar-specific DateFormat and 3489 * DateFormatSymbols objects as needed. 3490 * @param pattern the pattern, specific to the <code>DateFormat</code> 3491 * subclass 3492 * @param locale the locale for which the symbols should be drawn 3493 * @return a <code>DateFormat</code> appropriate to this calendar 3494 * @stable ICU 2.0 3495 */ handleGetDateFormat(String pattern, ULocale locale)3496 protected DateFormat handleGetDateFormat(String pattern, ULocale locale) { 3497 return handleGetDateFormat(pattern, null, locale); 3498 } 3499 3500 /** 3501 * Creates a <code>DateFormat</code> appropriate to this calendar. 3502 * This is a framework method for subclasses to override. This method 3503 * is responsible for creating the calendar-specific DateFormat and 3504 * DateFormatSymbols objects as needed. 3505 * @param pattern the pattern, specific to the <code>DateFormat</code> 3506 * subclass 3507 * @param locale the locale for which the symbols should be drawn 3508 * @return a <code>DateFormat</code> appropriate to this calendar 3509 * @draft ICU 3.2 (retain) 3510 * @provisional This API might change or be removed in a future release. 3511 */ handleGetDateFormat(String pattern, String override, ULocale locale)3512 protected DateFormat handleGetDateFormat(String pattern, String override, ULocale locale) { 3513 FormatConfiguration fmtConfig = new FormatConfiguration(); 3514 fmtConfig.pattern = pattern; 3515 fmtConfig.override = override; 3516 fmtConfig.formatData = new DateFormatSymbols(this, locale); 3517 fmtConfig.loc = locale; 3518 fmtConfig.cal = this; 3519 3520 return SimpleDateFormat.getInstance(fmtConfig); 3521 } 3522 3523 // date format pattern cache 3524 private static final ICUCache<String, PatternData> PATTERN_CACHE = 3525 new SimpleCache<String, PatternData>(); 3526 // final fallback patterns 3527 private static final String[] DEFAULT_PATTERNS = { 3528 "HH:mm:ss z", 3529 "HH:mm:ss z", 3530 "HH:mm:ss", 3531 "HH:mm", 3532 "EEEE, yyyy MMMM dd", 3533 "yyyy MMMM d", 3534 "yyyy MMM d", 3535 "yy/MM/dd", 3536 "{1} {0}", 3537 "{1} {0}", 3538 "{1} {0}", 3539 "{1} {0}", 3540 "{1} {0}" 3541 }; 3542 formatHelper(Calendar cal, ULocale loc, int dateStyle, int timeStyle)3543 static private DateFormat formatHelper(Calendar cal, ULocale loc, int dateStyle, 3544 int timeStyle) { 3545 if (timeStyle < DateFormat.NONE || timeStyle > DateFormat.SHORT) { 3546 throw new IllegalArgumentException("Illegal time style " + timeStyle); 3547 } 3548 if (dateStyle < DateFormat.NONE || dateStyle > DateFormat.SHORT) { 3549 throw new IllegalArgumentException("Illegal date style " + dateStyle); 3550 } 3551 3552 PatternData patternData = PatternData.make(cal, loc); 3553 String override = null; 3554 3555 // Resolve a pattern for the date/time style 3556 String pattern = null; 3557 if ((timeStyle >= 0) && (dateStyle >= 0)) { 3558 pattern = MessageFormat.format(patternData.getDateTimePattern(dateStyle), 3559 new Object[] {patternData.patterns[timeStyle], 3560 patternData.patterns[dateStyle + 4]}); 3561 // Might need to merge the overrides from the date and time into a single 3562 // override string TODO: Right now we are forcing the date's override into the 3563 // time style. 3564 if ( patternData.overrides != null ) { 3565 String dateOverride = patternData.overrides[dateStyle + 4]; 3566 String timeOverride = patternData.overrides[timeStyle]; 3567 override = mergeOverrideStrings( 3568 patternData.patterns[dateStyle+4], 3569 patternData.patterns[timeStyle], 3570 dateOverride, timeOverride); 3571 } 3572 } else if (timeStyle >= 0) { 3573 pattern = patternData.patterns[timeStyle]; 3574 if ( patternData.overrides != null ) { 3575 override = patternData.overrides[timeStyle]; 3576 } 3577 } else if (dateStyle >= 0) { 3578 pattern = patternData.patterns[dateStyle + 4]; 3579 if ( patternData.overrides != null ) { 3580 override = patternData.overrides[dateStyle + 4]; 3581 } 3582 } else { 3583 throw new IllegalArgumentException("No date or time style specified"); 3584 } 3585 DateFormat result = cal.handleGetDateFormat(pattern, override, loc); 3586 result.setCalendar(cal); 3587 return result; 3588 } 3589 3590 static class PatternData { 3591 // TODO make this even more object oriented 3592 private String[] patterns; 3593 private String[] overrides; PatternData(String[] patterns, String[] overrides)3594 public PatternData(String[] patterns, String[] overrides) { 3595 this.patterns = patterns; 3596 this.overrides = overrides; 3597 } getDateTimePattern(int dateStyle)3598 private String getDateTimePattern(int dateStyle) { 3599 int glueIndex = 8; 3600 if (patterns.length >= 13) { 3601 glueIndex += (dateStyle + 1); 3602 } 3603 final String dateTimePattern = patterns[glueIndex]; 3604 return dateTimePattern; 3605 } make(Calendar cal, ULocale loc)3606 private static PatternData make(Calendar cal, ULocale loc) { 3607 // First, try to get a pattern from PATTERN_CACHE 3608 String calType = cal.getType(); 3609 String key = loc.getBaseName() + "+" + calType; 3610 PatternData patternData = PATTERN_CACHE.get(key); 3611 if (patternData == null) { 3612 // Cache missed. Get one from bundle 3613 try { 3614 CalendarData calData = new CalendarData(loc, calType); 3615 patternData = new PatternData(calData.getDateTimePatterns(), 3616 calData.getOverrides()); 3617 } catch (MissingResourceException e) { 3618 patternData = new PatternData(DEFAULT_PATTERNS, null); 3619 } 3620 PATTERN_CACHE.put(key, patternData); 3621 } 3622 return patternData; 3623 } 3624 } 3625 3626 /** 3627 * @internal 3628 * @deprecated This API is ICU internal only. 3629 */ 3630 @Deprecated getDateTimePattern(Calendar cal, ULocale uLocale, int dateStyle)3631 public static String getDateTimePattern(Calendar cal, ULocale uLocale, int dateStyle) { 3632 PatternData patternData = PatternData.make(cal, uLocale); 3633 return patternData.getDateTimePattern(dateStyle); 3634 } 3635 mergeOverrideStrings( String datePattern, String timePattern, String dateOverride, String timeOverride )3636 private static String mergeOverrideStrings( String datePattern, String timePattern, 3637 String dateOverride, String timeOverride ) { 3638 3639 if ( dateOverride == null && timeOverride == null ) { 3640 return null; 3641 } 3642 3643 if ( dateOverride == null ) { 3644 return expandOverride(timePattern,timeOverride); 3645 } 3646 3647 if ( timeOverride == null ) { 3648 return expandOverride(datePattern,dateOverride); 3649 } 3650 3651 if ( dateOverride.equals(timeOverride) ) { 3652 return dateOverride; 3653 } 3654 3655 return (expandOverride(datePattern,dateOverride)+";"+ 3656 expandOverride(timePattern,timeOverride)); 3657 3658 } 3659 3660 private static final char QUOTE = '\''; expandOverride(String pattern, String override)3661 private static String expandOverride(String pattern, String override) { 3662 3663 if (override.indexOf('=') >= 0) { 3664 return override; 3665 } 3666 boolean inQuotes = false; 3667 char prevChar = ' '; 3668 StringBuilder result = new StringBuilder(); 3669 3670 StringCharacterIterator it = new StringCharacterIterator(pattern); 3671 3672 for (char c = it.first(); c!= StringCharacterIterator.DONE; c = it.next()) { 3673 if ( c == QUOTE ) { 3674 inQuotes = !inQuotes; 3675 prevChar = c; 3676 continue; 3677 } 3678 if ( !inQuotes && c != prevChar ) { 3679 if (result.length() > 0) { 3680 result.append(";"); 3681 } 3682 result.append(c); 3683 result.append("="); 3684 result.append(override); 3685 } 3686 prevChar = c; 3687 } 3688 return result.toString(); 3689 } 3690 /** 3691 * An instance of FormatConfiguration represents calendar specific 3692 * date format configuration and used for calling the ICU private 3693 * SimpleDateFormat factory method. 3694 * 3695 * @internal 3696 * @deprecated This API is ICU internal only. 3697 */ 3698 @Deprecated 3699 public static class FormatConfiguration { 3700 private String pattern; 3701 private String override; 3702 private DateFormatSymbols formatData; 3703 private Calendar cal; 3704 private ULocale loc; 3705 3706 // Only Calendar can instantiate FormatConfiguration()3707 private FormatConfiguration() { 3708 } 3709 3710 /** 3711 * Returns the pattern string 3712 * @return the format pattern string 3713 * @internal 3714 * @deprecated This API is ICU internal only. 3715 */ 3716 @Deprecated getPatternString()3717 public String getPatternString() { 3718 return pattern; 3719 } 3720 3721 /** 3722 * @internal 3723 * @deprecated This API is ICU internal only. 3724 */ 3725 @Deprecated getOverrideString()3726 public String getOverrideString() { 3727 return override; 3728 } 3729 3730 /** 3731 * Returns the calendar 3732 * @return the calendar 3733 * @internal 3734 * @deprecated This API is ICU internal only. 3735 */ 3736 @Deprecated getCalendar()3737 public Calendar getCalendar() { 3738 return cal; 3739 } 3740 3741 /** 3742 * Returns the locale 3743 * @return the locale 3744 * @internal 3745 * @deprecated This API is ICU internal only. 3746 */ 3747 @Deprecated getLocale()3748 public ULocale getLocale() { 3749 return loc; 3750 } 3751 3752 /** 3753 * Returns the format symbols 3754 * @return the format symbols 3755 * @internal 3756 * @deprecated This API is ICU internal only. 3757 */ 3758 @Deprecated getDateFormatSymbols()3759 public DateFormatSymbols getDateFormatSymbols() { 3760 return formatData; 3761 } 3762 } 3763 3764 //------------------------------------------------------------------------- 3765 // Protected utility methods for use by subclasses. These are very handy 3766 // for implementing add, roll, and computeFields. 3767 //------------------------------------------------------------------------- 3768 3769 /** 3770 * Adjust the specified field so that it is within 3771 * the allowable range for the date to which this calendar is set. 3772 * For example, in a Gregorian calendar pinning the {@link #DAY_OF_MONTH DAY_OF_MONTH} 3773 * field for a calendar set to April 31 would cause it to be set 3774 * to April 30. 3775 * <p> 3776 * <b>Subclassing:</b> 3777 * <br> 3778 * This utility method is intended for use by subclasses that need to implement 3779 * their own overrides of {@link #roll roll} and {@link #add add}. 3780 * <p> 3781 * <b>Note:</b> 3782 * <code>pinField</code> is implemented in terms of 3783 * {@link #getActualMinimum getActualMinimum} 3784 * and {@link #getActualMaximum getActualMaximum}. If either of those methods uses 3785 * a slow, iterative algorithm for a particular field, it would be 3786 * unwise to attempt to call <code>pinField</code> for that field. If you 3787 * really do need to do so, you should override this method to do 3788 * something more efficient for that field. 3789 * <p> 3790 * @param field The calendar field whose value should be pinned. 3791 * 3792 * @see #getActualMinimum 3793 * @see #getActualMaximum 3794 * @stable ICU 2.0 3795 */ pinField(int field)3796 protected void pinField(int field) { 3797 int max = getActualMaximum(field); 3798 int min = getActualMinimum(field); 3799 3800 if (fields[field] > max) { 3801 set(field, max); 3802 } else if (fields[field] < min) { 3803 set(field, min); 3804 } 3805 } 3806 3807 /** 3808 * Returns the week number of a day, within a period. This may be the week number in 3809 * a year or the week number in a month. Usually this will be a value >= 1, but if 3810 * some initial days of the period are excluded from week 1, because 3811 * {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} is > 1, then 3812 * the week number will be zero for those 3813 * initial days. This method requires the day number and day of week for some 3814 * known date in the period in order to determine the day of week 3815 * on the desired day. 3816 * <p> 3817 * <b>Subclassing:</b> 3818 * <br> 3819 * This method is intended for use by subclasses in implementing their 3820 * {@link #computeTime computeTime} and/or {@link #computeFields computeFields} methods. 3821 * It is often useful in {@link #getActualMinimum getActualMinimum} and 3822 * {@link #getActualMaximum getActualMaximum} as well. 3823 * <p> 3824 * This variant is handy for computing the week number of some other 3825 * day of a period (often the first or last day of the period) when its day 3826 * of the week is not known but the day number and day of week for some other 3827 * day in the period (e.g. the current date) <em>is</em> known. 3828 * <p> 3829 * @param desiredDay The {@link #DAY_OF_YEAR DAY_OF_YEAR} or 3830 * {@link #DAY_OF_MONTH DAY_OF_MONTH} whose week number is desired. 3831 * Should be 1 for the first day of the period. 3832 * 3833 * @param dayOfPeriod The {@link #DAY_OF_YEAR DAY_OF_YEAR} 3834 * or {@link #DAY_OF_MONTH DAY_OF_MONTH} for a day in the period whose 3835 * {@link #DAY_OF_WEEK DAY_OF_WEEK} is specified by the 3836 * <code>dayOfWeek</code> parameter. 3837 * Should be 1 for first day of period. 3838 * 3839 * @param dayOfWeek The {@link #DAY_OF_WEEK DAY_OF_WEEK} for the day 3840 * corresponding to the <code>dayOfPeriod</code> parameter. 3841 * 1-based with 1=Sunday. 3842 * 3843 * @return The week number (one-based), or zero if the day falls before 3844 * the first week because 3845 * {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} 3846 * is more than one. 3847 * @stable ICU 2.0 3848 */ weekNumber(int desiredDay, int dayOfPeriod, int dayOfWeek)3849 protected int weekNumber(int desiredDay, int dayOfPeriod, int dayOfWeek) 3850 { 3851 // Determine the day of the week of the first day of the period 3852 // in question (either a year or a month). Zero represents the 3853 // first day of the week on this calendar. 3854 int periodStartDayOfWeek = (dayOfWeek - getFirstDayOfWeek() - dayOfPeriod + 1) % 7; 3855 if (periodStartDayOfWeek < 0) periodStartDayOfWeek += 7; 3856 3857 // Compute the week number. Initially, ignore the first week, which 3858 // may be fractional (or may not be). We add periodStartDayOfWeek in 3859 // order to fill out the first week, if it is fractional. 3860 int weekNo = (desiredDay + periodStartDayOfWeek - 1)/7; 3861 3862 // If the first week is long enough, then count it. If 3863 // the minimal days in the first week is one, or if the period start 3864 // is zero, we always increment weekNo. 3865 if ((7 - periodStartDayOfWeek) >= getMinimalDaysInFirstWeek()) ++weekNo; 3866 3867 return weekNo; 3868 } 3869 3870 /** 3871 * Returns the week number of a day, within a period. This may be the week number in 3872 * a year, or the week number in a month. Usually this will be a value >= 1, but if 3873 * some initial days of the period are excluded from week 1, because 3874 * {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} is > 1, 3875 * then the week number will be zero for those 3876 * initial days. This method requires the day of week for the given date in order to 3877 * determine the result. 3878 * <p> 3879 * <b>Subclassing:</b> 3880 * <br> 3881 * This method is intended for use by subclasses in implementing their 3882 * {@link #computeTime computeTime} and/or {@link #computeFields computeFields} methods. 3883 * It is often useful in {@link #getActualMinimum getActualMinimum} and 3884 * {@link #getActualMaximum getActualMaximum} as well. 3885 * <p> 3886 * @param dayOfPeriod The {@link #DAY_OF_YEAR DAY_OF_YEAR} or 3887 * {@link #DAY_OF_MONTH DAY_OF_MONTH} whose week number is desired. 3888 * Should be 1 for the first day of the period. 3889 * 3890 * @param dayOfWeek The {@link #DAY_OF_WEEK DAY_OF_WEEK} for the day 3891 * corresponding to the <code>dayOfPeriod</code> parameter. 3892 * 1-based with 1=Sunday. 3893 * 3894 * @return The week number (one-based), or zero if the day falls before 3895 * the first week because 3896 * {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} 3897 * is more than one. 3898 * @stable ICU 2.0 3899 */ weekNumber(int dayOfPeriod, int dayOfWeek)3900 protected final int weekNumber(int dayOfPeriod, int dayOfWeek) 3901 { 3902 return weekNumber(dayOfPeriod, dayOfPeriod, dayOfWeek); 3903 } 3904 3905 //------------------------------------------------------------------------- 3906 // Constants 3907 //------------------------------------------------------------------------- 3908 3909 private static final int FIELD_DIFF_MAX_INT = Integer.MAX_VALUE; // 2147483647 3910 3911 /** 3912 * {@icu} Returns the difference between the given time and the time this 3913 * calendar object is set to. If this calendar is set 3914 * <em>before</em> the given time, the returned value will be 3915 * positive. If this calendar is set <em>after</em> the given 3916 * time, the returned value will be negative. The 3917 * <code>field</code> parameter specifies the units of the return 3918 * value. For example, if <code>fieldDifference(when, 3919 * Calendar.MONTH)</code> returns 3, then this calendar is set to 3920 * 3 months before <code>when</code>, and possibly some additional 3921 * time less than one month. 3922 * 3923 * <p>As a side effect of this call, this calendar is advanced 3924 * toward <code>when</code> by the given amount. That is, calling 3925 * this method has the side effect of calling <code>add(field, 3926 * n)</code>, where <code>n</code> is the return value. 3927 * 3928 * <p>Usage: To use this method, call it first with the largest 3929 * field of interest, then with progressively smaller fields. For 3930 * example: 3931 * 3932 * <pre> 3933 * int y = cal.fieldDifference(when, Calendar.YEAR); 3934 * int m = cal.fieldDifference(when, Calendar.MONTH); 3935 * int d = cal.fieldDifference(when, Calendar.DATE);</pre> 3936 * 3937 * computes the difference between <code>cal</code> and 3938 * <code>when</code> in years, months, and days. 3939 * 3940 * <p>Note: <code>fieldDifference()</code> is 3941 * <em>asymmetrical</em>. That is, in the following code: 3942 * 3943 * <pre> 3944 * cal.setTime(date1); 3945 * int m1 = cal.fieldDifference(date2, Calendar.MONTH); 3946 * int d1 = cal.fieldDifference(date2, Calendar.DATE); 3947 * cal.setTime(date2); 3948 * int m2 = cal.fieldDifference(date1, Calendar.MONTH); 3949 * int d2 = cal.fieldDifference(date1, Calendar.DATE);</pre> 3950 * 3951 * one might expect that <code>m1 == -m2 && d1 == -d2</code>. 3952 * However, this is not generally the case, because of 3953 * irregularities in the underlying calendar system (e.g., the 3954 * Gregorian calendar has a varying number of days per month). 3955 * 3956 * @param when the date to compare this calendar's time to 3957 * @param field the field in which to compute the result 3958 * @return the difference, either positive or negative, between 3959 * this calendar's time and <code>when</code>, in terms of 3960 * <code>field</code>. 3961 * @stable ICU 2.0 3962 */ fieldDifference(Date when, int field)3963 public int fieldDifference(Date when, int field) { 3964 int min = 0; 3965 long startMs = getTimeInMillis(); 3966 long targetMs = when.getTime(); 3967 // Always add from the start millis. This accomodates 3968 // operations like adding years from February 29, 2000 up to 3969 // February 29, 2004. If 1, 1, 1, 1 is added to the year 3970 // field, the DOM gets pinned to 28 and stays there, giving an 3971 // incorrect DOM difference of 1. We have to add 1, reset, 2, 3972 // reset, 3, reset, 4. 3973 if (startMs < targetMs) { 3974 int max = 1; 3975 // Find a value that is too large 3976 for (;;) { 3977 setTimeInMillis(startMs); 3978 add(field, max); 3979 long ms = getTimeInMillis(); 3980 if (ms == targetMs) { 3981 return max; 3982 } else if (ms > targetMs) { 3983 break; 3984 } else if (max < FIELD_DIFF_MAX_INT) { 3985 min = max; 3986 max <<= 1; 3987 if (max < 0) { 3988 max = FIELD_DIFF_MAX_INT; 3989 } 3990 } else { 3991 // Field difference too large to fit into int 3992 throw new RuntimeException(); 3993 } 3994 } 3995 // Do a binary search 3996 while ((max - min) > 1) { 3997 int t = min + (max - min)/2; // make sure intermediate values don't exceed FIELD_DIFF_MAX_INT 3998 setTimeInMillis(startMs); 3999 add(field, t); 4000 long ms = getTimeInMillis(); 4001 if (ms == targetMs) { 4002 return t; 4003 } else if (ms > targetMs) { 4004 max = t; 4005 } else { 4006 min = t; 4007 } 4008 } 4009 } else if (startMs > targetMs) { 4010 //Eclipse stated the following is "dead code" 4011 /*if (false) { 4012 // This works, and makes the code smaller, but costs 4013 // an extra object creation and an extra couple cycles 4014 // of calendar computation. 4015 setTimeInMillis(targetMs); 4016 min = -fieldDifference(new Date(startMs), field); 4017 }*/ 4018 int max = -1; 4019 // Find a value that is too small 4020 for (;;) { 4021 setTimeInMillis(startMs); 4022 add(field, max); 4023 long ms = getTimeInMillis(); 4024 if (ms == targetMs) { 4025 return max; 4026 } else if (ms < targetMs) { 4027 break; 4028 } else { 4029 min = max; 4030 max <<= 1; 4031 if (max == 0) { 4032 // Field difference too large to fit into int 4033 throw new RuntimeException(); 4034 } 4035 } 4036 } 4037 // Do a binary search 4038 while ((min - max) > 1) { 4039 int t = min + (max - min)/2; // make sure intermediate values don't exceed FIELD_DIFF_MAX_INT 4040 setTimeInMillis(startMs); 4041 add(field, t); 4042 long ms = getTimeInMillis(); 4043 if (ms == targetMs) { 4044 return t; 4045 } else if (ms < targetMs) { 4046 max = t; 4047 } else { 4048 min = t; 4049 } 4050 } 4051 } 4052 // Set calendar to end point 4053 setTimeInMillis(startMs); 4054 add(field, min); 4055 return min; 4056 } 4057 4058 /** 4059 * Sets the time zone with the given time zone value. 4060 * @param value the given time zone. 4061 * @stable ICU 2.0 4062 */ setTimeZone(TimeZone value)4063 public void setTimeZone(TimeZone value) 4064 { 4065 zone = value; 4066 /* Recompute the fields from the time using the new zone. This also 4067 * works if isTimeSet is false (after a call to set()). In that case 4068 * the time will be computed from the fields using the new zone, then 4069 * the fields will get recomputed from that. Consider the sequence of 4070 * calls: cal.setTimeZone(EST); cal.set(HOUR, 1); cal.setTimeZone(PST). 4071 * Is cal set to 1 o'clock EST or 1 o'clock PST? Answer: PST. More 4072 * generally, a call to setTimeZone() affects calls to set() BEFORE AND 4073 * AFTER it up to the next call to complete(). 4074 */ 4075 areFieldsSet = false; 4076 } 4077 4078 /** 4079 * Returns the time zone. 4080 * @return the time zone object associated with this calendar. 4081 * @stable ICU 2.0 4082 */ getTimeZone()4083 public TimeZone getTimeZone() 4084 { 4085 return zone; 4086 } 4087 4088 /** 4089 * Specify whether or not date/time interpretation is to be lenient. With 4090 * lenient interpretation, a date such as "February 942, 1996" will be 4091 * treated as being equivalent to the 941st day after February 1, 1996. 4092 * With strict interpretation, such dates will cause an exception to be 4093 * thrown. 4094 * 4095 * @see DateFormat#setLenient 4096 * @stable ICU 2.0 4097 */ setLenient(boolean lenient)4098 public void setLenient(boolean lenient) 4099 { 4100 this.lenient = lenient; 4101 } 4102 4103 /** 4104 * Tell whether date/time interpretation is to be lenient. 4105 * @stable ICU 2.0 4106 */ isLenient()4107 public boolean isLenient() 4108 { 4109 return lenient; 4110 } 4111 4112 /** 4113 * {@icu}Sets the behavior for handling wall time repeating multiple times 4114 * at negative time zone offset transitions. For example, 1:30 AM on 4115 * November 6, 2011 in US Eastern time (Ameirca/New_York) occurs twice; 4116 * 1:30 AM EDT, then 1:30 AM EST one hour later. When <code>WALLTIME_FIRST</code> 4117 * is used, the wall time 1:30AM in this example will be interpreted as 1:30 AM EDT 4118 * (first occurrence). When <code>WALLTIME_LAST</code> is used, it will be 4119 * interpreted as 1:30 AM EST (last occurrence). The default value is 4120 * <code>WALLTIME_LAST</code>. 4121 * 4122 * @param option the behavior for handling repeating wall time, either 4123 * <code>WALLTIME_FIRST</code> or <code>WALLTIME_LAST</code>. 4124 * @throws IllegalArgumentException when <code>option</code> is neither 4125 * <code>WALLTIME_FIRST</code> nor <code>WALLTIME_LAST</code>. 4126 * 4127 * @see #getRepeatedWallTimeOption() 4128 * @see #WALLTIME_FIRST 4129 * @see #WALLTIME_LAST 4130 * 4131 * @stable ICU 49 4132 */ setRepeatedWallTimeOption(int option)4133 public void setRepeatedWallTimeOption(int option) { 4134 if (option != WALLTIME_LAST && option != WALLTIME_FIRST) { 4135 throw new IllegalArgumentException("Illegal repeated wall time option - " + option); 4136 } 4137 repeatedWallTime = option; 4138 } 4139 4140 /** 4141 * {@icu}Gets the behavior for handling wall time repeating multiple times 4142 * at negative time zone offset transitions. 4143 * 4144 * @return the behavior for handling repeating wall time, either 4145 * <code>WALLTIME_FIRST</code> or <code>WALLTIME_LAST</code>. 4146 * 4147 * @see #setRepeatedWallTimeOption(int) 4148 * @see #WALLTIME_FIRST 4149 * @see #WALLTIME_LAST 4150 * 4151 * @stable ICU 49 4152 */ getRepeatedWallTimeOption()4153 public int getRepeatedWallTimeOption() { 4154 return repeatedWallTime; 4155 } 4156 4157 /** 4158 * {@icu}Sets the behavior for handling skipped wall time at positive time zone offset 4159 * transitions. For example, 2:30 AM on March 13, 2011 in US Eastern time (America/New_York) 4160 * does not exist because the wall time jump from 1:59 AM EST to 3:00 AM EDT. When 4161 * <code>WALLTIME_FIRST</code> is used, 2:30 AM is interpreted as 30 minutes before 3:00 AM 4162 * EDT, therefore, it will be resolved as 1:30 AM EST. When <code>WALLTIME_LAST</code> 4163 * is used, 2:30 AM is interpreted as 31 minutes after 1:59 AM EST, therefore, it will be 4164 * resolved as 3:30 AM EDT. When <code>WALLTIME_NEXT_VALID</code> is used, 2:30 AM will 4165 * be resolved as next valid wall time, that is 3:00 AM EDT. The default value is 4166 * <code>WALLTIME_LAST</code>. 4167 * <p> 4168 * <b>Note:</b>This option is effective only when this calendar is {@link #isLenient() lenient}. 4169 * When the calendar is strict, such non-existing wall time will cause an exception. 4170 * 4171 * @param option the behavior for handling skipped wall time at positive time zone 4172 * offset transitions, one of <code>WALLTIME_FIRST</code>, <code>WALLTIME_LAST</code> and 4173 * <code>WALLTIME_NEXT_VALID</code>. 4174 * @throws IllegalArgumentException when <code>option</code> is not any of 4175 * <code>WALLTIME_FIRST</code>, <code>WALLTIME_LAST</code> and <code>WALLTIME_NEXT_VALID</code>. 4176 * 4177 * @see #getSkippedWallTimeOption() 4178 * @see #WALLTIME_FIRST 4179 * @see #WALLTIME_LAST 4180 * @see #WALLTIME_NEXT_VALID 4181 * 4182 * @stable ICU 49 4183 */ setSkippedWallTimeOption(int option)4184 public void setSkippedWallTimeOption(int option) { 4185 if (option != WALLTIME_LAST && option != WALLTIME_FIRST && option != WALLTIME_NEXT_VALID) { 4186 throw new IllegalArgumentException("Illegal skipped wall time option - " + option); 4187 } 4188 skippedWallTime = option; 4189 } 4190 4191 /** 4192 * {@icu}Gets the behavior for handling skipped wall time at positive time zone offset 4193 * transitions. 4194 * 4195 * @return the behavior for handling skipped wall time, one of 4196 * <code>WALLTIME_FIRST</code>, <code>WALLTIME_LAST</code> and <code>WALLTIME_NEXT_VALID</code>. 4197 * 4198 * @see #setSkippedWallTimeOption(int) 4199 * @see #WALLTIME_FIRST 4200 * @see #WALLTIME_LAST 4201 * @see #WALLTIME_NEXT_VALID 4202 * 4203 * @stable ICU 49 4204 */ getSkippedWallTimeOption()4205 public int getSkippedWallTimeOption() { 4206 return skippedWallTime; 4207 } 4208 4209 /** 4210 * Sets what the first day of the week is, 4211 * where 1 = {@link #SUNDAY} and 7 = {@link #SATURDAY}. 4212 * @param value the given first day of the week, where 1 = {@link #SUNDAY} and 7 = {@link #SATURDAY}. 4213 * @stable ICU 2.0 4214 */ setFirstDayOfWeek(int value)4215 public void setFirstDayOfWeek(int value) 4216 { 4217 if (firstDayOfWeek != value) { 4218 if (value < SUNDAY || value > SATURDAY) { 4219 throw new IllegalArgumentException("Invalid day of week"); 4220 } 4221 firstDayOfWeek = value; 4222 areFieldsSet = false; 4223 } 4224 } 4225 4226 /** 4227 * Returns what the first day of the week is, 4228 * where 1 = {@link #SUNDAY} and 7 = {@link #SATURDAY}. 4229 * e.g., Sunday in US, Monday in France 4230 * @return the first day of the week, where 1 = {@link #SUNDAY} and 7 = {@link #SATURDAY}. 4231 * @stable ICU 2.0 4232 */ getFirstDayOfWeek()4233 public int getFirstDayOfWeek() 4234 { 4235 return firstDayOfWeek; 4236 } 4237 4238 /** 4239 * Sets what the minimal days required in the first week of the year are. 4240 * For example, if the first week is defined as one that contains the first 4241 * day of the first month of a year, call the method with value 1. If it 4242 * must be a full week, use value 7. 4243 * @param value the given minimal days required in the first week 4244 * of the year. 4245 * @stable ICU 2.0 4246 */ setMinimalDaysInFirstWeek(int value)4247 public void setMinimalDaysInFirstWeek(int value) 4248 { 4249 // Values less than 1 have the same effect as 1; values greater 4250 // than 7 have the same effect as 7. However, we normalize values 4251 // so operator== and so forth work. 4252 if (value < 1) { 4253 value = 1; 4254 } else if (value > 7) { 4255 value = 7; 4256 } 4257 if (minimalDaysInFirstWeek != value) { 4258 minimalDaysInFirstWeek = value; 4259 areFieldsSet = false; 4260 } 4261 } 4262 4263 /** 4264 * Returns what the minimal days required in the first week of the year are. 4265 * That is, if the first week is defined as one that contains the first day 4266 * of the first month of a year, getMinimalDaysInFirstWeek returns 1. If 4267 * the minimal days required must be a full week, getMinimalDaysInFirstWeek 4268 * returns 7. 4269 * @return the minimal days required in the first week of the year. 4270 * @stable ICU 2.0 4271 */ getMinimalDaysInFirstWeek()4272 public int getMinimalDaysInFirstWeek() 4273 { 4274 return minimalDaysInFirstWeek; 4275 } 4276 4277 private static final int LIMITS[][] = { 4278 // Minimum Greatest min Least max Greatest max 4279 {/* */}, // ERA 4280 {/* */}, // YEAR 4281 {/* */}, // MONTH 4282 {/* */}, // WEEK_OF_YEAR 4283 {/* */}, // WEEK_OF_MONTH 4284 {/* */}, // DAY_OF_MONTH 4285 {/* */}, // DAY_OF_YEAR 4286 { 1, 1, 7, 7 }, // DAY_OF_WEEK 4287 {/* */}, // DAY_OF_WEEK_IN_MONTH 4288 { 0, 0, 1, 1 }, // AM_PM 4289 { 0, 0, 11, 11 }, // HOUR 4290 { 0, 0, 23, 23 }, // HOUR_OF_DAY 4291 { 0, 0, 59, 59 }, // MINUTE 4292 { 0, 0, 59, 59 }, // SECOND 4293 { 0, 0, 999, 999 }, // MILLISECOND 4294 {-12*ONE_HOUR, -12*ONE_HOUR, 12*ONE_HOUR, 12*ONE_HOUR }, // ZONE_OFFSET 4295 { 0, 0, 1*ONE_HOUR, 1*ONE_HOUR }, // DST_OFFSET 4296 {/* */}, // YEAR_WOY 4297 { 1, 1, 7, 7 }, // DOW_LOCAL 4298 {/* */}, // EXTENDED_YEAR 4299 { -0x7F000000, -0x7F000000, 0x7F000000, 0x7F000000 }, // JULIAN_DAY 4300 { 0, 0, 24*ONE_HOUR-1, 24*ONE_HOUR-1 }, // MILLISECONDS_IN_DAY 4301 { 0, 0, 1, 1 }, // IS_LEAP_MONTH 4302 }; 4303 4304 /** 4305 * Subclass API for defining limits of different types. 4306 * Subclasses must implement this method to return limits for the 4307 * following fields: 4308 * 4309 * <pre>ERA 4310 * YEAR 4311 * MONTH 4312 * WEEK_OF_YEAR 4313 * WEEK_OF_MONTH 4314 * DAY_OF_MONTH 4315 * DAY_OF_YEAR 4316 * DAY_OF_WEEK_IN_MONTH 4317 * YEAR_WOY 4318 * EXTENDED_YEAR</pre> 4319 * 4320 * @param field one of the above field numbers 4321 * @param limitType one of <code>MINIMUM</code>, <code>GREATEST_MINIMUM</code>, 4322 * <code>LEAST_MAXIMUM</code>, or <code>MAXIMUM</code> 4323 * @stable ICU 2.0 4324 */ handleGetLimit(int field, int limitType)4325 abstract protected int handleGetLimit(int field, int limitType); 4326 4327 /** 4328 * Returns a limit for a field. 4329 * @param field the field, from 0..</code>getFieldCount()-1</code> 4330 * @param limitType the type specifier for the limit 4331 * @see #MINIMUM 4332 * @see #GREATEST_MINIMUM 4333 * @see #LEAST_MAXIMUM 4334 * @see #MAXIMUM 4335 * @stable ICU 2.0 4336 */ getLimit(int field, int limitType)4337 protected int getLimit(int field, int limitType) { 4338 switch (field) { 4339 case DAY_OF_WEEK: 4340 case AM_PM: 4341 case HOUR: 4342 case HOUR_OF_DAY: 4343 case MINUTE: 4344 case SECOND: 4345 case MILLISECOND: 4346 case ZONE_OFFSET: 4347 case DST_OFFSET: 4348 case DOW_LOCAL: 4349 case JULIAN_DAY: 4350 case MILLISECONDS_IN_DAY: 4351 case IS_LEAP_MONTH: 4352 return LIMITS[field][limitType]; 4353 4354 case WEEK_OF_MONTH: 4355 { 4356 int limit; 4357 if (limitType == MINIMUM) { 4358 limit = getMinimalDaysInFirstWeek() == 1 ? 1 : 0; 4359 } else if (limitType == GREATEST_MINIMUM){ 4360 limit = 1; 4361 } else { 4362 int minDaysInFirst = getMinimalDaysInFirstWeek(); 4363 int daysInMonth = handleGetLimit(DAY_OF_MONTH, limitType); 4364 if (limitType == LEAST_MAXIMUM) { 4365 limit = (daysInMonth + (7 - minDaysInFirst)) / 7; 4366 } else { // limitType == MAXIMUM 4367 limit = (daysInMonth + 6 + (7 - minDaysInFirst)) / 7; 4368 } 4369 } 4370 return limit; 4371 } 4372 4373 } 4374 return handleGetLimit(field, limitType); 4375 } 4376 4377 /** 4378 * Limit type for <code>getLimit()</code> and <code>handleGetLimit()</code> 4379 * indicating the minimum value that a field can take (least minimum). 4380 * @see #getLimit 4381 * @see #handleGetLimit 4382 * @stable ICU 2.0 4383 */ 4384 protected static final int MINIMUM = 0; 4385 4386 /** 4387 * Limit type for <code>getLimit()</code> and <code>handleGetLimit()</code> 4388 * indicating the greatest minimum value that a field can take. 4389 * @see #getLimit 4390 * @see #handleGetLimit 4391 * @stable ICU 2.0 4392 */ 4393 protected static final int GREATEST_MINIMUM = 1; 4394 4395 /** 4396 * Limit type for <code>getLimit()</code> and <code>handleGetLimit()</code> 4397 * indicating the least maximum value that a field can take. 4398 * @see #getLimit 4399 * @see #handleGetLimit 4400 * @stable ICU 2.0 4401 */ 4402 protected static final int LEAST_MAXIMUM = 2; 4403 4404 /** 4405 * Limit type for <code>getLimit()</code> and <code>handleGetLimit()</code> 4406 * indicating the maximum value that a field can take (greatest maximum). 4407 * @see #getLimit 4408 * @see #handleGetLimit 4409 * @stable ICU 2.0 4410 */ 4411 protected static final int MAXIMUM = 3; 4412 4413 /** 4414 * Returns the minimum value for the given time field. 4415 * e.g., for Gregorian DAY_OF_MONTH, 1. 4416 * @param field the given time field. 4417 * @return the minimum value for the given time field. 4418 * @stable ICU 2.0 4419 */ getMinimum(int field)4420 public final int getMinimum(int field) { 4421 return getLimit(field, MINIMUM); 4422 } 4423 4424 /** 4425 * Returns the maximum value for the given time field. 4426 * e.g. for Gregorian DAY_OF_MONTH, 31. 4427 * @param field the given time field. 4428 * @return the maximum value for the given time field. 4429 * @stable ICU 2.0 4430 */ getMaximum(int field)4431 public final int getMaximum(int field) { 4432 return getLimit(field, MAXIMUM); 4433 } 4434 4435 /** 4436 * Returns the highest minimum value for the given field if varies. 4437 * Otherwise same as getMinimum(). For Gregorian, no difference. 4438 * @param field the given time field. 4439 * @return the highest minimum value for the given time field. 4440 * @stable ICU 2.0 4441 */ getGreatestMinimum(int field)4442 public final int getGreatestMinimum(int field) { 4443 return getLimit(field, GREATEST_MINIMUM); 4444 } 4445 4446 /** 4447 * Returns the lowest maximum value for the given field if varies. 4448 * Otherwise same as getMaximum(). e.g., for Gregorian DAY_OF_MONTH, 28. 4449 * @param field the given time field. 4450 * @return the lowest maximum value for the given time field. 4451 * @stable ICU 2.0 4452 */ getLeastMaximum(int field)4453 public final int getLeastMaximum(int field) { 4454 return getLimit(field, LEAST_MAXIMUM); 4455 } 4456 4457 //------------------------------------------------------------------------- 4458 // Weekend support -- determining which days of the week are the weekend 4459 // in a given locale 4460 //------------------------------------------------------------------------- 4461 4462 /** 4463 * {@icu} Returns whether the given day of the week is a weekday, a 4464 * weekend day, or a day that transitions from one to the other, for the 4465 * locale and calendar system associated with this Calendar (the locale's 4466 * region is often the most determinant factor). If a transition occurs at 4467 * midnight, then the days before and after the transition will have the 4468 * type WEEKDAY or WEEKEND. If a transition occurs at a time 4469 * other than midnight, then the day of the transition will have 4470 * the type WEEKEND_ONSET or WEEKEND_CEASE. In this case, the 4471 * method getWeekendTransition() will return the point of 4472 * transition. 4473 * @param dayOfWeek either SUNDAY, MONDAY, TUESDAY, WEDNESDAY, 4474 * THURSDAY, FRIDAY, or SATURDAY 4475 * @return either WEEKDAY, WEEKEND, WEEKEND_ONSET, or 4476 * WEEKEND_CEASE 4477 * @exception IllegalArgumentException if dayOfWeek is not 4478 * between SUNDAY and SATURDAY, inclusive 4479 * @see #WEEKDAY 4480 * @see #WEEKEND 4481 * @see #WEEKEND_ONSET 4482 * @see #WEEKEND_CEASE 4483 * @see #getWeekendTransition 4484 * @see #isWeekend(Date) 4485 * @see #isWeekend() 4486 * @deprecated ICU 54 use {@link #getWeekDataForRegion(String)}, {@link #getWeekData()}, {@link #setWeekData(WeekData)} 4487 */ 4488 @Deprecated getDayOfWeekType(int dayOfWeek)4489 public int getDayOfWeekType(int dayOfWeek) { 4490 if (dayOfWeek < SUNDAY || dayOfWeek > SATURDAY) { 4491 throw new IllegalArgumentException("Invalid day of week"); 4492 } 4493 if (weekendOnset == weekendCease) { 4494 if (dayOfWeek != weekendOnset) 4495 return WEEKDAY; 4496 return (weekendOnsetMillis == 0) ? WEEKEND : WEEKEND_ONSET; 4497 } 4498 if (weekendOnset < weekendCease) { 4499 if (dayOfWeek < weekendOnset || dayOfWeek > weekendCease) { 4500 return WEEKDAY; 4501 } 4502 } else { 4503 if (dayOfWeek > weekendCease && dayOfWeek < weekendOnset) { 4504 return WEEKDAY; 4505 } 4506 } 4507 if (dayOfWeek == weekendOnset) { 4508 return (weekendOnsetMillis == 0) ? WEEKEND : WEEKEND_ONSET; 4509 } 4510 if (dayOfWeek == weekendCease) { 4511 return (weekendCeaseMillis >= 86400000) ? WEEKEND : WEEKEND_CEASE; 4512 } 4513 return WEEKEND; 4514 } 4515 4516 /** 4517 * {@icu} Returns the time during the day at which the weekend begins or end in this 4518 * calendar system. If getDayOfWeekType(dayOfWeek) == WEEKEND_ONSET return the time 4519 * at which the weekend begins. If getDayOfWeekType(dayOfWeek) == WEEKEND_CEASE 4520 * return the time at which the weekend ends. If getDayOfWeekType(dayOfWeek) has some 4521 * other value, then throw an exception. 4522 * @param dayOfWeek either SUNDAY, MONDAY, TUESDAY, WEDNESDAY, 4523 * THURSDAY, FRIDAY, or SATURDAY 4524 * @return the milliseconds after midnight at which the 4525 * weekend begins or ends 4526 * @exception IllegalArgumentException if dayOfWeek is not 4527 * WEEKEND_ONSET or WEEKEND_CEASE 4528 * @see #getDayOfWeekType 4529 * @see #isWeekend(Date) 4530 * @see #isWeekend() 4531 * @deprecated ICU 54 use {@link #getWeekDataForRegion(String)}, {@link #getWeekData()}, {@link #setWeekData(WeekData)} 4532 */ 4533 @Deprecated getWeekendTransition(int dayOfWeek)4534 public int getWeekendTransition(int dayOfWeek) { 4535 if (dayOfWeek == weekendOnset) { 4536 return weekendOnsetMillis; 4537 } else if (dayOfWeek == weekendCease) { 4538 return weekendCeaseMillis; 4539 } 4540 throw new IllegalArgumentException("Not weekend transition day"); 4541 } 4542 4543 /** 4544 * {@icu} Returns true if the given date and time is in the weekend in this calendar 4545 * system. Equivalent to calling setTime() followed by isWeekend(). Note: This 4546 * method changes the time this calendar is set to. 4547 * @param date the date and time 4548 * @return true if the given date and time is part of the 4549 * weekend 4550 * @see #getDayOfWeekType 4551 * @see #getWeekendTransition 4552 * @see #isWeekend() 4553 * @stable ICU 2.0 4554 */ isWeekend(Date date)4555 public boolean isWeekend(Date date) { 4556 setTime(date); 4557 return isWeekend(); 4558 } 4559 4560 /** 4561 * {@icu} Returns true if this Calendar's current date and time is in the weekend in 4562 * this calendar system. 4563 * @return true if the given date and time is part of the 4564 * weekend 4565 * @see #getDayOfWeekType 4566 * @see #getWeekendTransition 4567 * @see #isWeekend(Date) 4568 * @stable ICU 2.0 4569 */ isWeekend()4570 public boolean isWeekend() { 4571 int dow = get(DAY_OF_WEEK); 4572 int dowt = getDayOfWeekType(dow); 4573 switch (dowt) { 4574 case WEEKDAY: 4575 return false; 4576 case WEEKEND: 4577 return true; 4578 default: // That is, WEEKEND_ONSET or WEEKEND_CEASE 4579 // Use internalGet() because the above call to get() populated 4580 // all fields. 4581 // [Note: There should be a better way to get millis in day. 4582 // For ICU4J, submit request for a MILLIS_IN_DAY field 4583 // and a DAY_NUMBER field (could be Julian day #). - aliu] 4584 int millisInDay = internalGet(MILLISECOND) + 1000 * (internalGet(SECOND) + 4585 60 * (internalGet(MINUTE) + 60 * internalGet(HOUR_OF_DAY))); 4586 int transition = getWeekendTransition(dow); 4587 return (dowt == WEEKEND_ONSET) 4588 ? (millisInDay >= transition) 4589 : (millisInDay < transition); 4590 } 4591 // (We can never reach this point.) 4592 } 4593 4594 //------------------------------------------------------------------------- 4595 // End of weekend support 4596 //------------------------------------------------------------------------- 4597 4598 /** 4599 * Overrides Cloneable 4600 * @stable ICU 2.0 4601 */ clone()4602 public Object clone() 4603 { 4604 try { 4605 Calendar other = (Calendar) super.clone(); 4606 4607 other.fields = new int[fields.length]; 4608 other.stamp = new int[fields.length]; 4609 System.arraycopy(this.fields, 0, other.fields, 0, fields.length); 4610 System.arraycopy(this.stamp, 0, other.stamp, 0, fields.length); 4611 4612 other.zone = (TimeZone) zone.clone(); 4613 return other; 4614 } 4615 catch (CloneNotSupportedException e) { 4616 // this shouldn't happen, since we are Cloneable 4617 throw new ICUCloneNotSupportedException(e); 4618 } 4619 } 4620 4621 /** 4622 * Returns a string representation of this calendar. This method 4623 * is intended to be used only for debugging purposes, and the 4624 * format of the returned string may vary between implementations. 4625 * The returned string may be empty but may not be <code>null</code>. 4626 * 4627 * @return a string representation of this calendar. 4628 * @stable ICU 2.0 4629 */ toString()4630 public String toString() { 4631 StringBuilder buffer = new StringBuilder(); 4632 buffer.append(getClass().getName()); 4633 buffer.append("[time="); 4634 buffer.append(isTimeSet ? String.valueOf(time) : "?"); 4635 buffer.append(",areFieldsSet="); 4636 buffer.append(areFieldsSet); 4637 buffer.append(",areAllFieldsSet="); 4638 buffer.append(areAllFieldsSet); 4639 buffer.append(",lenient="); 4640 buffer.append(lenient); 4641 buffer.append(",zone="); 4642 buffer.append(zone); 4643 buffer.append(",firstDayOfWeek="); 4644 buffer.append(firstDayOfWeek); 4645 buffer.append(",minimalDaysInFirstWeek="); 4646 buffer.append(minimalDaysInFirstWeek); 4647 buffer.append(",repeatedWallTime="); 4648 buffer.append(repeatedWallTime); 4649 buffer.append(",skippedWallTime="); 4650 buffer.append(skippedWallTime); 4651 for (int i=0; i<fields.length; ++i) { 4652 buffer.append(',').append(fieldName(i)).append('='); 4653 buffer.append(isSet(i) ? String.valueOf(fields[i]) : "?"); 4654 } 4655 buffer.append(']'); 4656 return buffer.toString(); 4657 } 4658 4659 /** 4660 * Simple, immutable struct-like class for access to the CLDR weekend data. 4661 * 4662 * @draft ICU 54 4663 * @provisional This is a draft API and might change in a future release of ICU. 4664 */ 4665 public static final class WeekData { 4666 /** 4667 * the first day of the week, where 1 = {@link #SUNDAY} and 7 = {@link #SATURDAY} 4668 * 4669 * @draft ICU 54 4670 * @provisional This is a draft API and might change in a future release of ICU. 4671 */ 4672 public final int firstDayOfWeek; 4673 /** 4674 * the minimal number of days in the first week 4675 * 4676 * @draft ICU 54 4677 * @provisional This is a draft API and might change in a future release of ICU. 4678 */ 4679 public final int minimalDaysInFirstWeek; 4680 /** 4681 * the onset day, where 1 = {@link #SUNDAY} and 7 = {@link #SATURDAY} 4682 * 4683 * @draft ICU 54 4684 * @provisional This is a draft API and might change in a future release of ICU. 4685 */ 4686 public final int weekendOnset; 4687 /** 4688 * the onset time in millis during the onset day 4689 * 4690 * @draft ICU 54 4691 * @provisional This is a draft API and might change in a future release of ICU. 4692 */ 4693 public final int weekendOnsetMillis; 4694 /** 4695 * the cease day, where 1 = {@link #SUNDAY} and 7 = {@link #SATURDAY} 4696 * 4697 * @draft ICU 54 4698 * @provisional This is a draft API and might change in a future release of ICU. 4699 */ 4700 public final int weekendCease; 4701 /** 4702 * the cease time in millis during the cease day. Exclusive, so the max is 24:00:00.000. 4703 * Note that this will format as 00:00 the next day. 4704 * 4705 * @draft ICU 54 4706 * @provisional This is a draft API and might change in a future release of ICU. 4707 */ 4708 public final int weekendCeaseMillis; 4709 4710 /** 4711 * Constructor 4712 * 4713 * @param fdow the first day of the week, where 1 = {@link #SUNDAY} and 7 = {@link #SATURDAY} 4714 * @param mdifw the minimal number of days in the first week 4715 * @param weekendOnset the onset day, where 1 = Sunday and 7 = Saturday 4716 * @param weekendOnsetMillis the onset time in millis during the onset day 4717 * @param weekendCease the cease day, where 1 = Sunday and 7 = Saturday 4718 * @param weekendCeaseMillis the cease time in millis during the cease day. 4719 * 4720 * @draft ICU 54 4721 * @provisional This is a draft API and might change in a future release of ICU. 4722 */ WeekData(int fdow, int mdifw, int weekendOnset, int weekendOnsetMillis, int weekendCease, int weekendCeaseMillis)4723 public WeekData(int fdow, int mdifw, 4724 int weekendOnset, int weekendOnsetMillis, 4725 int weekendCease, int weekendCeaseMillis) { 4726 this.firstDayOfWeek = fdow; 4727 this.minimalDaysInFirstWeek = mdifw; 4728 this.weekendOnset = weekendOnset; 4729 this.weekendOnsetMillis = weekendOnsetMillis; 4730 this.weekendCease = weekendCease; 4731 this.weekendCeaseMillis = weekendCeaseMillis; 4732 } 4733 4734 /** 4735 * {@inheritDoc} 4736 * 4737 * @draft ICU 54 4738 * @provisional This is a draft API and might change in a future release of ICU. 4739 */ 4740 @Override hashCode()4741 public int hashCode() { 4742 return ((((firstDayOfWeek * 37 + minimalDaysInFirstWeek) * 37 + weekendOnset) * 37 4743 + weekendOnsetMillis) * 37 + weekendCease) * 37 + weekendCeaseMillis; 4744 } 4745 4746 /** 4747 * {@inheritDoc} 4748 * 4749 * @draft ICU 54 4750 * @provisional This is a draft API and might change in a future release of ICU. 4751 */ 4752 @Override equals(Object other)4753 public boolean equals(Object other) { 4754 if (this == other) { 4755 return true; 4756 } 4757 if (!(other instanceof WeekData)) { 4758 return false; 4759 } 4760 WeekData that = (WeekData) other; 4761 return firstDayOfWeek == that.firstDayOfWeek 4762 && minimalDaysInFirstWeek == that.minimalDaysInFirstWeek 4763 && weekendOnset == that.weekendOnset 4764 && weekendOnsetMillis == that.weekendOnsetMillis 4765 && weekendCease == that.weekendCease 4766 && weekendCeaseMillis == that.weekendCeaseMillis; 4767 } 4768 4769 /** 4770 * {@inheritDoc} 4771 * 4772 * @draft ICU 54 4773 * @provisional This is a draft API and might change in a future release of ICU. 4774 */ 4775 @Override toString()4776 public String toString() { 4777 return "{" + firstDayOfWeek 4778 + ", " + minimalDaysInFirstWeek 4779 + ", " + weekendOnset 4780 + ", " + weekendOnsetMillis 4781 + ", " + weekendCease 4782 + ", " + weekendCeaseMillis 4783 + "}"; 4784 } 4785 } 4786 4787 /** 4788 * {@icu} Return simple, immutable struct-like class for access to the CLDR weekend data. 4789 * @param region The input region. The results are undefined if the region code is not valid. 4790 * @return the WeekData for the input region. It is never null. 4791 * 4792 * @draft ICU 54 4793 * @provisional This is a draft API and might change in a future release of ICU. 4794 */ getWeekDataForRegion(String region)4795 public static WeekData getWeekDataForRegion(String region) { 4796 return WEEK_DATA_CACHE.createInstance(region, region); 4797 } 4798 4799 /** 4800 * {@icu} Return simple, immutable struct-like class for access to the weekend data in this calendar. 4801 * @return the WeekData for this calendar. 4802 * 4803 * @draft ICU 54 4804 * @provisional This is a draft API and might change in a future release of ICU. 4805 */ getWeekData()4806 public WeekData getWeekData() { 4807 return new WeekData(firstDayOfWeek, minimalDaysInFirstWeek, weekendOnset, weekendOnsetMillis, weekendCease, weekendCeaseMillis); 4808 } 4809 4810 /** 4811 * {@icu} Set data in this calendar based on the WeekData input. 4812 * @param wdata The week data to use 4813 * @return this, for chaining 4814 * 4815 * @draft ICU 54 4816 * @provisional This is a draft API and might change in a future release of ICU. 4817 */ setWeekData(WeekData wdata)4818 public Calendar setWeekData(WeekData wdata) { 4819 setFirstDayOfWeek(wdata.firstDayOfWeek); 4820 setMinimalDaysInFirstWeek(wdata.minimalDaysInFirstWeek); 4821 4822 weekendOnset = wdata.weekendOnset; 4823 weekendOnsetMillis = wdata.weekendOnsetMillis; 4824 weekendCease = wdata.weekendCease; 4825 weekendCeaseMillis = wdata.weekendCeaseMillis; 4826 return this; 4827 } 4828 getWeekDataForRegionInternal(String region)4829 private static WeekData getWeekDataForRegionInternal(String region) { 4830 if (region == null) { 4831 region = "001"; 4832 } 4833 4834 UResourceBundle rb = UResourceBundle.getBundleInstance( 4835 ICUResourceBundle.ICU_BASE_NAME, 4836 "supplementalData", 4837 ICUResourceBundle.ICU_DATA_CLASS_LOADER); 4838 UResourceBundle weekDataInfo = rb.get("weekData"); 4839 UResourceBundle weekDataBundle = null; 4840 4841 try { 4842 weekDataBundle = weekDataInfo.get(region); 4843 } catch (MissingResourceException mre) { 4844 if (!region.equals("001")) { 4845 // use "001" as fallback 4846 weekDataBundle = weekDataInfo.get("001"); 4847 } else { 4848 throw mre; 4849 } 4850 } 4851 4852 int[] wdi = weekDataBundle.getIntVector(); 4853 return new WeekData(wdi[0],wdi[1],wdi[2],wdi[3],wdi[4],wdi[5]); 4854 } 4855 4856 /* 4857 * Cache to hold week data by region 4858 */ 4859 private static class WeekDataCache extends SoftCache<String, WeekData, String> { 4860 4861 /* (non-Javadoc) 4862 * @see com.ibm.icu.impl.CacheBase#createInstance(java.lang.Object, java.lang.Object) 4863 */ 4864 @Override createInstance(String key, String data)4865 protected WeekData createInstance(String key, String data) { 4866 return getWeekDataForRegionInternal(key); 4867 } 4868 } 4869 4870 private static final WeekDataCache WEEK_DATA_CACHE = new WeekDataCache(); 4871 4872 /* 4873 * Set this calendar to contain week and weekend data for the given region. 4874 */ setWeekData(String region)4875 private void setWeekData(String region) { 4876 if (region == null) { 4877 region = "001"; 4878 } 4879 WeekData wdata = WEEK_DATA_CACHE.getInstance(region, region); 4880 setWeekData(wdata); 4881 } 4882 4883 /** 4884 * Recompute the time and update the status fields isTimeSet 4885 * and areFieldsSet. Callers should check isTimeSet and only 4886 * call this method if isTimeSet is false. 4887 */ updateTime()4888 private void updateTime() { 4889 computeTime(); 4890 // If we are lenient, we need to recompute the fields to normalize 4891 // the values. Also, if we haven't set all the fields yet (i.e., 4892 // in a newly-created object), we need to fill in the fields. [LIU] 4893 if (isLenient() || !areAllFieldsSet) areFieldsSet = false; 4894 isTimeSet = true; 4895 areFieldsVirtuallySet = false; 4896 } 4897 4898 /** 4899 * Save the state of this object to a stream (i.e., serialize it). 4900 */ writeObject(ObjectOutputStream stream)4901 private void writeObject(ObjectOutputStream stream) 4902 throws IOException 4903 { 4904 // Try to compute the time correctly, for the future (stream 4905 // version 2) in which we don't write out fields[] or isSet[]. 4906 if (!isTimeSet) { 4907 try { 4908 updateTime(); 4909 } 4910 catch (IllegalArgumentException e) {} 4911 } 4912 4913 // Write out the 1.1 FCS object. 4914 stream.defaultWriteObject(); 4915 } 4916 4917 /** 4918 * Reconstitute this object from a stream (i.e., deserialize it). 4919 */ readObject(ObjectInputStream stream)4920 private void readObject(ObjectInputStream stream) 4921 throws IOException, ClassNotFoundException { 4922 4923 stream.defaultReadObject(); 4924 4925 initInternal(); 4926 4927 isTimeSet = true; 4928 areFieldsSet = areAllFieldsSet = false; 4929 areFieldsVirtuallySet = true; // cause fields to be recalculated if requested. 4930 nextStamp = MINIMUM_USER_STAMP; 4931 } 4932 4933 4934 //---------------------------------------------------------------------- 4935 // Time -> Fields 4936 //---------------------------------------------------------------------- 4937 4938 /** 4939 * Converts the current millisecond time value <code>time</code> to 4940 * field values in <code>fields[]</code>. This synchronizes the time 4941 * field values with a new time that is set for the calendar. The time 4942 * is <em>not</em> recomputed first; to recompute the time, then the 4943 * fields, call the <code>complete</code> method. 4944 * @see #complete 4945 * @stable ICU 2.0 4946 */ computeFields()4947 protected void computeFields() { 4948 int offsets[] = new int[2]; 4949 getTimeZone().getOffset(time, false, offsets); 4950 long localMillis = time + offsets[0] + offsets[1]; 4951 4952 // Mark fields as set. Do this before calling handleComputeFields(). 4953 int mask = internalSetMask; 4954 for (int i=0; i<fields.length; ++i) { 4955 if ((mask & 1) == 0) { 4956 stamp[i] = INTERNALLY_SET; 4957 } else { 4958 stamp[i] = UNSET; 4959 } 4960 mask >>= 1; 4961 } 4962 4963 // We used to check for and correct extreme millis values (near 4964 // Long.MIN_VALUE or Long.MAX_VALUE) here. Such values would cause 4965 // overflows from positive to negative (or vice versa) and had to 4966 // be manually tweaked. We no longer need to do this because we 4967 // have limited the range of supported dates to those that have a 4968 // Julian day that fits into an int. This allows us to implement a 4969 // JULIAN_DAY field and also removes some inelegant code. - Liu 4970 // 11/6/00 4971 4972 long days = floorDivide(localMillis, ONE_DAY); 4973 4974 fields[JULIAN_DAY] = (int) days + EPOCH_JULIAN_DAY; 4975 4976 computeGregorianAndDOWFields(fields[JULIAN_DAY]); 4977 4978 // Call framework method to have subclass compute its fields. 4979 // These must include, at a minimum, MONTH, DAY_OF_MONTH, 4980 // EXTENDED_YEAR, YEAR, DAY_OF_YEAR. This method will call internalSet(), 4981 // which will update stamp[]. 4982 handleComputeFields(fields[JULIAN_DAY]); 4983 4984 // Compute week-related fields, based on the subclass-computed 4985 // fields computed by handleComputeFields(). 4986 computeWeekFields(); 4987 4988 // Compute time-related fields. These are indepent of the date and 4989 // of the subclass algorithm. They depend only on the local zone 4990 // wall milliseconds in day. 4991 int millisInDay = (int) (localMillis - (days * ONE_DAY)); 4992 fields[MILLISECONDS_IN_DAY] = millisInDay; 4993 fields[MILLISECOND] = millisInDay % 1000; 4994 millisInDay /= 1000; 4995 fields[SECOND] = millisInDay % 60; 4996 millisInDay /= 60; 4997 fields[MINUTE] = millisInDay % 60; 4998 millisInDay /= 60; 4999 fields[HOUR_OF_DAY] = millisInDay; 5000 fields[AM_PM] = millisInDay / 12; // Assume AM == 0 5001 fields[HOUR] = millisInDay % 12; 5002 fields[ZONE_OFFSET] = offsets[0]; 5003 fields[DST_OFFSET] = offsets[1]; 5004 } 5005 5006 /** 5007 * Compute the Gregorian calendar year, month, and day of month from 5008 * the given Julian day. These values are not stored in fields, but in 5009 * member variables gregorianXxx. Also compute the DAY_OF_WEEK and 5010 * DOW_LOCAL fields. 5011 */ computeGregorianAndDOWFields(int julianDay)5012 private final void computeGregorianAndDOWFields(int julianDay) { 5013 computeGregorianFields(julianDay); 5014 5015 // Compute day of week: JD 0 = Monday 5016 int dow = fields[DAY_OF_WEEK] = julianDayToDayOfWeek(julianDay); 5017 5018 // Calculate 1-based localized day of week 5019 int dowLocal = dow - getFirstDayOfWeek() + 1; 5020 if (dowLocal < 1) { 5021 dowLocal += 7; 5022 } 5023 fields[DOW_LOCAL] = dowLocal; 5024 } 5025 5026 /** 5027 * Compute the Gregorian calendar year, month, and day of month from the 5028 * Julian day. These values are not stored in fields, but in member 5029 * variables gregorianXxx. They are used for time zone computations and by 5030 * subclasses that are Gregorian derivatives. Subclasses may call this 5031 * method to perform a Gregorian calendar millis->fields computation. 5032 * To perform a Gregorian calendar fields->millis computation, call 5033 * computeGregorianMonthStart(). 5034 * @see #computeGregorianMonthStart 5035 * @stable ICU 2.0 5036 */ computeGregorianFields(int julianDay)5037 protected final void computeGregorianFields(int julianDay) { 5038 int year, month, dayOfMonth, dayOfYear; 5039 5040 // The Gregorian epoch day is zero for Monday January 1, year 1. 5041 long gregorianEpochDay = julianDay - JAN_1_1_JULIAN_DAY; 5042 5043 // Here we convert from the day number to the multiple radix 5044 // representation. We use 400-year, 100-year, and 4-year cycles. 5045 // For example, the 4-year cycle has 4 years + 1 leap day; giving 5046 // 1461 == 365*4 + 1 days. 5047 int[] rem = new int[1]; 5048 int n400 = floorDivide(gregorianEpochDay, 146097, rem); // 400-year cycle length 5049 int n100 = floorDivide(rem[0], 36524, rem); // 100-year cycle length 5050 int n4 = floorDivide(rem[0], 1461, rem); // 4-year cycle length 5051 int n1 = floorDivide(rem[0], 365, rem); 5052 year = 400*n400 + 100*n100 + 4*n4 + n1; 5053 dayOfYear = rem[0]; // zero-based day of year 5054 if (n100 == 4 || n1 == 4) { 5055 dayOfYear = 365; // Dec 31 at end of 4- or 400-yr cycle 5056 } else { 5057 ++year; 5058 } 5059 5060 boolean isLeap = ((year&0x3) == 0) && // equiv. to (year%4 == 0) 5061 (year%100 != 0 || year%400 == 0); 5062 5063 int correction = 0; 5064 int march1 = isLeap ? 60 : 59; // zero-based DOY for March 1 5065 if (dayOfYear >= march1) correction = isLeap ? 1 : 2; 5066 month = (12 * (dayOfYear + correction) + 6) / 367; // zero-based month 5067 dayOfMonth = dayOfYear - 5068 GREGORIAN_MONTH_COUNT[month][isLeap?3:2] + 1; // one-based DOM 5069 5070 gregorianYear = year; 5071 gregorianMonth = month; // 0-based already 5072 gregorianDayOfMonth = dayOfMonth; // 1-based already 5073 gregorianDayOfYear = dayOfYear + 1; // Convert from 0-based to 1-based 5074 } 5075 5076 /** 5077 * Compute the fields WEEK_OF_YEAR, YEAR_WOY, WEEK_OF_MONTH, 5078 * DAY_OF_WEEK_IN_MONTH, and DOW_LOCAL from EXTENDED_YEAR, YEAR, 5079 * DAY_OF_WEEK, and DAY_OF_YEAR. The latter fields are computed by the 5080 * subclass based on the calendar system. 5081 * 5082 * <p>The YEAR_WOY field is computed simplistically. It is equal to YEAR 5083 * most of the time, but at the year boundary it may be adjusted to YEAR-1 5084 * or YEAR+1 to reflect the overlap of a week into an adjacent year. In 5085 * this case, a simple increment or decrement is performed on YEAR, even 5086 * though this may yield an invalid YEAR value. For instance, if the YEAR 5087 * is part of a calendar system with an N-year cycle field CYCLE, then 5088 * incrementing the YEAR may involve incrementing CYCLE and setting YEAR 5089 * back to 0 or 1. This is not handled by this code, and in fact cannot be 5090 * simply handled without having subclasses define an entire parallel set of 5091 * fields for fields larger than or equal to a year. This additional 5092 * complexity is not warranted, since the intention of the YEAR_WOY field is 5093 * to support ISO 8601 notation, so it will typically be used with a 5094 * proleptic Gregorian calendar, which has no field larger than a year. 5095 */ computeWeekFields()5096 private final void computeWeekFields() { 5097 int eyear = fields[EXTENDED_YEAR]; 5098 int dayOfWeek = fields[DAY_OF_WEEK]; 5099 int dayOfYear = fields[DAY_OF_YEAR]; 5100 5101 // WEEK_OF_YEAR start 5102 // Compute the week of the year. For the Gregorian calendar, valid week 5103 // numbers run from 1 to 52 or 53, depending on the year, the first day 5104 // of the week, and the minimal days in the first week. For other 5105 // calendars, the valid range may be different -- it depends on the year 5106 // length. Days at the start of the year may fall into the last week of 5107 // the previous year; days at the end of the year may fall into the 5108 // first week of the next year. ASSUME that the year length is less than 5109 // 7000 days. 5110 int yearOfWeekOfYear = eyear; 5111 int relDow = (dayOfWeek + 7 - getFirstDayOfWeek()) % 7; // 0..6 5112 int relDowJan1 = (dayOfWeek - dayOfYear + 7001 - getFirstDayOfWeek()) % 7; // 0..6 5113 int woy = (dayOfYear - 1 + relDowJan1) / 7; // 0..53 5114 if ((7 - relDowJan1) >= getMinimalDaysInFirstWeek()) { 5115 ++woy; 5116 } 5117 5118 // Adjust for weeks at the year end that overlap into the previous or 5119 // next calendar year. 5120 if (woy == 0) { 5121 // We are the last week of the previous year. 5122 // Check to see if we are in the last week; if so, we need 5123 // to handle the case in which we are the first week of the 5124 // next year. 5125 5126 int prevDoy = dayOfYear + handleGetYearLength(eyear - 1); 5127 woy = weekNumber(prevDoy, dayOfWeek); 5128 yearOfWeekOfYear--; 5129 } else { 5130 int lastDoy = handleGetYearLength(eyear); 5131 // Fast check: For it to be week 1 of the next year, the DOY 5132 // must be on or after L-5, where L is yearLength(), then it 5133 // cannot possibly be week 1 of the next year: 5134 // L-5 L 5135 // doy: 359 360 361 362 363 364 365 001 5136 // dow: 1 2 3 4 5 6 7 5137 if (dayOfYear >= (lastDoy - 5)) { 5138 int lastRelDow = (relDow + lastDoy - dayOfYear) % 7; 5139 if (lastRelDow < 0) { 5140 lastRelDow += 7; 5141 } 5142 if (((6 - lastRelDow) >= getMinimalDaysInFirstWeek()) && 5143 ((dayOfYear + 7 - relDow) > lastDoy)) { 5144 woy = 1; 5145 yearOfWeekOfYear++; 5146 } 5147 } 5148 } 5149 fields[WEEK_OF_YEAR] = woy; 5150 fields[YEAR_WOY] = yearOfWeekOfYear; 5151 // WEEK_OF_YEAR end 5152 5153 int dayOfMonth = fields[DAY_OF_MONTH]; 5154 fields[WEEK_OF_MONTH] = weekNumber(dayOfMonth, dayOfWeek); 5155 fields[DAY_OF_WEEK_IN_MONTH] = (dayOfMonth-1) / 7 + 1; 5156 } 5157 5158 //---------------------------------------------------------------------- 5159 // Fields -> Time 5160 //---------------------------------------------------------------------- 5161 5162 /** 5163 * Value to OR against resolve table field values for remapping. 5164 * @see #resolveFields 5165 * @stable ICU 2.0 5166 */ 5167 protected static final int RESOLVE_REMAP = 32; 5168 // A power of 2 greater than or equal to MAX_FIELD_COUNT 5169 5170 // Default table for day in year 5171 static final int[][][] DATE_PRECEDENCE = { 5172 { 5173 { DAY_OF_MONTH }, 5174 { WEEK_OF_YEAR, DAY_OF_WEEK }, 5175 { WEEK_OF_MONTH, DAY_OF_WEEK }, 5176 { DAY_OF_WEEK_IN_MONTH, DAY_OF_WEEK }, 5177 { WEEK_OF_YEAR, DOW_LOCAL }, 5178 { WEEK_OF_MONTH, DOW_LOCAL }, 5179 { DAY_OF_WEEK_IN_MONTH, DOW_LOCAL }, 5180 { DAY_OF_YEAR }, 5181 { RESOLVE_REMAP | DAY_OF_MONTH, YEAR }, // if YEAR is set over YEAR_WOY use DAY_OF_MONTH 5182 { RESOLVE_REMAP | WEEK_OF_YEAR, YEAR_WOY }, // if YEAR_WOY is set, calc based on WEEK_OF_YEAR 5183 }, 5184 { 5185 { WEEK_OF_YEAR }, 5186 { WEEK_OF_MONTH }, 5187 { DAY_OF_WEEK_IN_MONTH }, 5188 { RESOLVE_REMAP | DAY_OF_WEEK_IN_MONTH, DAY_OF_WEEK }, 5189 { RESOLVE_REMAP | DAY_OF_WEEK_IN_MONTH, DOW_LOCAL }, 5190 }, 5191 }; 5192 5193 static final int[][][] DOW_PRECEDENCE = { 5194 { 5195 { DAY_OF_WEEK }, 5196 { DOW_LOCAL }, 5197 }, 5198 }; 5199 5200 /** 5201 * Given a precedence table, return the newest field combination in 5202 * the table, or -1 if none is found. 5203 * 5204 * <p>The precedence table is a 3-dimensional array of integers. It 5205 * may be thought of as an array of groups. Each group is an array of 5206 * lines. Each line is an array of field numbers. Within a line, if 5207 * all fields are set, then the time stamp of the line is taken to be 5208 * the stamp of the most recently set field. If any field of a line is 5209 * unset, then the line fails to match. Within a group, the line with 5210 * the newest time stamp is selected. The first field of the line is 5211 * returned to indicate which line matched. 5212 * 5213 * <p>In some cases, it may be desirable to map a line to field that 5214 * whose stamp is NOT examined. For example, if the best field is 5215 * DAY_OF_WEEK then the DAY_OF_WEEK_IN_MONTH algorithm may be used. In 5216 * order to do this, insert the value <code>REMAP_RESOLVE | F</code> at 5217 * the start of the line, where <code>F</code> is the desired return 5218 * field value. This field will NOT be examined; it only determines 5219 * the return value if the other fields in the line are the newest. 5220 * 5221 * <p>If all lines of a group contain at least one unset field, then no 5222 * line will match, and the group as a whole will fail to match. In 5223 * that case, the next group will be processed. If all groups fail to 5224 * match, then -1 is returned. 5225 * @stable ICU 2.0 5226 */ resolveFields(int[][][] precedenceTable)5227 protected int resolveFields(int[][][] precedenceTable) { 5228 int bestField = -1; 5229 int tempBestField; 5230 for (int g=0; g<precedenceTable.length && bestField < 0; ++g) { 5231 int[][] group = precedenceTable[g]; 5232 int bestStamp = UNSET; 5233 linesInGroup: 5234 for (int l=0; l<group.length; ++l) { 5235 int[] line= group[l]; 5236 int lineStamp = UNSET; 5237 // Skip over first entry if it is negative 5238 for (int i=(line[0]>=RESOLVE_REMAP)?1:0; i<line.length; ++i) { 5239 int s = stamp[line[i]]; 5240 // If any field is unset then don't use this line 5241 if (s == UNSET) { 5242 continue linesInGroup; 5243 } else { 5244 lineStamp = Math.max(lineStamp, s); 5245 } 5246 } 5247 // Record new maximum stamp & field no. 5248 if (lineStamp > bestStamp) { 5249 tempBestField = line[0]; // First field refers to entire line 5250 if (tempBestField >= RESOLVE_REMAP) { 5251 tempBestField &= (RESOLVE_REMAP-1); 5252 // This check is needed to resolve some issues with UCAL_YEAR precedence mapping 5253 if (tempBestField != DATE || (stamp[WEEK_OF_MONTH] < stamp[tempBestField])) { 5254 bestField = tempBestField; 5255 } 5256 } else { 5257 bestField = tempBestField; 5258 } 5259 5260 if (bestField == tempBestField) { 5261 bestStamp = lineStamp; 5262 } 5263 } 5264 } 5265 } 5266 return (bestField>=RESOLVE_REMAP)?(bestField&(RESOLVE_REMAP-1)):bestField; 5267 } 5268 5269 /** 5270 * Returns the newest stamp of a given range of fields. 5271 * @stable ICU 2.0 5272 */ newestStamp(int first, int last, int bestStampSoFar)5273 protected int newestStamp(int first, int last, int bestStampSoFar) { 5274 int bestStamp = bestStampSoFar; 5275 for (int i=first; i<=last; ++i) { 5276 if (stamp[i] > bestStamp) { 5277 bestStamp = stamp[i]; 5278 } 5279 } 5280 return bestStamp; 5281 } 5282 5283 /** 5284 * Returns the timestamp of a field. 5285 * @stable ICU 2.0 5286 */ getStamp(int field)5287 protected final int getStamp(int field) { 5288 return stamp[field]; 5289 } 5290 5291 /** 5292 * Returns the field that is newer, either defaultField, or 5293 * alternateField. If neither is newer or neither is set, return defaultField. 5294 * @stable ICU 2.0 5295 */ newerField(int defaultField, int alternateField)5296 protected int newerField(int defaultField, int alternateField) { 5297 if (stamp[alternateField] > stamp[defaultField]) { 5298 return alternateField; 5299 } 5300 return defaultField; 5301 } 5302 5303 /** 5304 * Ensure that each field is within its valid range by calling {@link 5305 * #validateField(int)} on each field that has been set. This method 5306 * should only be called if this calendar is not lenient. 5307 * @see #isLenient 5308 * @see #validateField(int) 5309 * @stable ICU 2.0 5310 */ validateFields()5311 protected void validateFields() { 5312 for (int field = 0; field < fields.length; field++) { 5313 if (stamp[field] >= MINIMUM_USER_STAMP) { 5314 validateField(field); 5315 } 5316 } 5317 } 5318 5319 /** 5320 * Validate a single field of this calendar. Subclasses should 5321 * override this method to validate any calendar-specific fields. 5322 * Generic fields can be handled by 5323 * <code>Calendar.validateField()</code>. 5324 * @see #validateField(int, int, int) 5325 * @stable ICU 2.0 5326 */ validateField(int field)5327 protected void validateField(int field) { 5328 int y; 5329 switch (field) { 5330 case DAY_OF_MONTH: 5331 y = handleGetExtendedYear(); 5332 validateField(field, 1, handleGetMonthLength(y, internalGet(MONTH))); 5333 break; 5334 case DAY_OF_YEAR: 5335 y = handleGetExtendedYear(); 5336 validateField(field, 1, handleGetYearLength(y)); 5337 break; 5338 case DAY_OF_WEEK_IN_MONTH: 5339 if (internalGet(field) == 0) { 5340 throw new IllegalArgumentException("DAY_OF_WEEK_IN_MONTH cannot be zero"); 5341 } 5342 validateField(field, getMinimum(field), getMaximum(field)); 5343 break; 5344 default: 5345 validateField(field, getMinimum(field), getMaximum(field)); 5346 break; 5347 } 5348 } 5349 5350 /** 5351 * Validate a single field of this calendar given its minimum and 5352 * maximum allowed value. If the field is out of range, throw a 5353 * descriptive <code>IllegalArgumentException</code>. Subclasses may 5354 * use this method in their implementation of {@link 5355 * #validateField(int)}. 5356 * @stable ICU 2.0 5357 */ validateField(int field, int min, int max)5358 protected final void validateField(int field, int min, int max) { 5359 int value = fields[field]; 5360 if (value < min || value > max) { 5361 throw new IllegalArgumentException(fieldName(field) + 5362 '=' + value + ", valid range=" + 5363 min + ".." + max); 5364 } 5365 } 5366 5367 /** 5368 * Converts the current field values in <code>fields[]</code> to the 5369 * millisecond time value <code>time</code>. 5370 * @stable ICU 2.0 5371 */ computeTime()5372 protected void computeTime() { 5373 if (!isLenient()) { 5374 validateFields(); 5375 } 5376 5377 // Compute the Julian day 5378 int julianDay = computeJulianDay(); 5379 5380 long millis = julianDayToMillis(julianDay); 5381 5382 int millisInDay; 5383 5384 // We only use MILLISECONDS_IN_DAY if it has been set by the user. 5385 // This makes it possible for the caller to set the calendar to a 5386 // time and call clear(MONTH) to reset the MONTH to January. This 5387 // is legacy behavior. Without this, clear(MONTH) has no effect, 5388 // since the internally set JULIAN_DAY is used. 5389 if (stamp[MILLISECONDS_IN_DAY] >= MINIMUM_USER_STAMP && 5390 newestStamp(AM_PM, MILLISECOND, UNSET) <= stamp[MILLISECONDS_IN_DAY]) { 5391 millisInDay = internalGet(MILLISECONDS_IN_DAY); 5392 } else { 5393 millisInDay = computeMillisInDay(); 5394 } 5395 5396 if (stamp[ZONE_OFFSET] >= MINIMUM_USER_STAMP || 5397 stamp[DST_OFFSET] >= MINIMUM_USER_STAMP) { 5398 time = millis + millisInDay - (internalGet(ZONE_OFFSET) + internalGet(DST_OFFSET)); 5399 } else { 5400 // Compute the time zone offset and DST offset. There are two potential 5401 // ambiguities here. We'll assume a 2:00 am (wall time) switchover time 5402 // for discussion purposes here. 5403 // 5404 // 1. The positive offset change such as transition into DST. 5405 // Here, a designated time of 2:00 am - 2:59 am does not actually exist. 5406 // For this case, skippedWallTime option specifies the behavior. 5407 // For example, 2:30 am is interpreted as; 5408 // - WALLTIME_LAST(default): 3:30 am (DST) (interpreting 2:30 am as 31 minutes after 1:59 am (STD)) 5409 // - WALLTIME_FIRST: 1:30 am (STD) (interpreting 2:30 am as 30 minutes before 3:00 am (DST)) 5410 // - WALLTIME_NEXT_VALID: 3:00 am (DST) (next valid time after 2:30 am on a wall clock) 5411 // 2. The negative offset change such as transition out of DST. 5412 // Here, a designated time of 1:00 am - 1:59 am can be in standard or DST. Both are valid 5413 // representations (the rep jumps from 1:59:59 DST to 1:00:00 Std). 5414 // For this case, repeatedWallTime option specifies the behavior. 5415 // For example, 1:30 am is interpreted as; 5416 // - WALLTIME_LAST(default): 1:30 am (STD) - latter occurrence 5417 // - WALLTIME_FIRST: 1:30 am (DST) - former occurrence 5418 // 5419 // In addition to above, when calendar is strict (not default), wall time falls into 5420 // the skipped time range will be processed as an error case. 5421 // 5422 // These special cases are mostly handled in #computeZoneOffset(long), except WALLTIME_NEXT_VALID 5423 // at positive offset change. The protected method computeZoneOffset(long) is exposed to Calendar 5424 // subclass implementations and marked as @stable. Strictly speaking, WALLTIME_NEXT_VALID 5425 // should be also handled in the same place, but we cannot change the code flow without deprecating 5426 // the protected method. 5427 // 5428 // We use the TimeZone object, unless the user has explicitly set the ZONE_OFFSET 5429 // or DST_OFFSET fields; then we use those fields. 5430 5431 if (!lenient || skippedWallTime == WALLTIME_NEXT_VALID) { 5432 // When strict, invalidate a wall time falls into a skipped wall time range. 5433 // When lenient and skipped wall time option is WALLTIME_NEXT_VALID, 5434 // the result time will be adjusted to the next valid time (on wall clock). 5435 int zoneOffset = computeZoneOffset(millis, millisInDay); 5436 long tmpTime = millis + millisInDay - zoneOffset; 5437 5438 int zoneOffset1 = zone.getOffset(tmpTime); 5439 5440 // zoneOffset != zoneOffset1 only when the given wall time fall into 5441 // a skipped wall time range caused by positive zone offset transition. 5442 if (zoneOffset != zoneOffset1) { 5443 if (!lenient) { 5444 throw new IllegalArgumentException("The specified wall time does not exist due to time zone offset transition."); 5445 } 5446 5447 assert skippedWallTime == WALLTIME_NEXT_VALID : skippedWallTime; 5448 // Adjust time to the next valid wall clock time. 5449 // At this point, tmpTime is on or after the zone offset transition causing 5450 // the skipped time range. 5451 Long immediatePrevTransition = getImmediatePreviousZoneTransition(tmpTime); 5452 if (immediatePrevTransition == null) { 5453 throw new RuntimeException("Could not locate a time zone transition before " + tmpTime); 5454 } 5455 time = immediatePrevTransition; 5456 } else { 5457 time = tmpTime; 5458 } 5459 } else { 5460 time = millis + millisInDay - computeZoneOffset(millis, millisInDay); 5461 } 5462 } 5463 } 5464 5465 /** 5466 * Find the previous zone transtion near the given time. 5467 * 5468 * @param base The base time, inclusive. 5469 * @return The time of the previous transition, or null if not found. 5470 */ getImmediatePreviousZoneTransition(long base)5471 private Long getImmediatePreviousZoneTransition(long base) { 5472 Long transitionTime = null; 5473 5474 if (zone instanceof BasicTimeZone) { 5475 TimeZoneTransition transition = ((BasicTimeZone) zone).getPreviousTransition(base, true); 5476 if (transition != null) { 5477 transitionTime = transition.getTime(); 5478 } 5479 } else { 5480 // Usually, it is enough to check past one hour because such transition is most 5481 // likely +1 hour shift. However, there is an example jumped +24 hour in the tz database. 5482 transitionTime = getPreviousZoneTransitionTime(zone, base, 2 * 60 * 60 * 1000); // check last 2 hours 5483 if (transitionTime == null) { 5484 transitionTime = getPreviousZoneTransitionTime(zone, base, 30 * 60 * 60 * 1000); // try last 30 hours 5485 } 5486 } 5487 return transitionTime; 5488 } 5489 5490 /** 5491 * Find the previous zone transition within the specified duration. 5492 * Note: This method is only used when TimeZone is NOT a BasicTimeZone. 5493 * @param tz The time zone. 5494 * @param base The base time, inclusive. 5495 * @param duration The range of time evaluated. 5496 * @return The time of the previous zone transition, or null if not available. 5497 */ getPreviousZoneTransitionTime(TimeZone tz, long base, long duration)5498 private static Long getPreviousZoneTransitionTime(TimeZone tz, long base, long duration) { 5499 assert duration > 0; 5500 5501 long upper = base; 5502 long lower = base - duration - 1; 5503 int offsetU = tz.getOffset(upper); 5504 int offsetL = tz.getOffset(lower); 5505 if (offsetU == offsetL) { 5506 return null; 5507 } 5508 return findPreviousZoneTransitionTime(tz, offsetU, upper, lower); 5509 } 5510 5511 /** 5512 * The time units used by {@link #findPreviousZoneTransitionTime(TimeZone, int, long, long)} 5513 * for optimizing transition time binary search. 5514 */ 5515 private static final int[] FIND_ZONE_TRANSITION_TIME_UNITS = { 5516 60*60*1000, // 1 hour 5517 30*60*1000, // 30 minutes 5518 60*1000, // 1 minute 5519 1000, // 1 second 5520 }; 5521 5522 /** 5523 * Implementing binary search for zone transtion detection, used by {@link #getPreviousZoneTransitionTime(TimeZone, long, long)} 5524 * @param tz The time zone. 5525 * @param upperOffset The zone offset at <code>upper</code> 5526 * @param upper The upper bound, inclusive. 5527 * @param lower The lower bound, exclusive. 5528 * @return The time of the previous zone transition, or null if not available. 5529 */ findPreviousZoneTransitionTime(TimeZone tz, int upperOffset, long upper, long lower)5530 private static Long findPreviousZoneTransitionTime(TimeZone tz, int upperOffset, long upper, long lower) { 5531 boolean onUnitTime = false; 5532 long mid = 0; 5533 5534 for (int unit : FIND_ZONE_TRANSITION_TIME_UNITS) { 5535 long lunits = lower/unit; 5536 long uunits = upper/unit; 5537 if (uunits > lunits) { 5538 mid = ((lunits + uunits + 1) >>> 1) * unit; 5539 onUnitTime = true; 5540 break; 5541 } 5542 } 5543 5544 int midOffset; 5545 if (!onUnitTime) { 5546 mid = (upper + lower) >>> 1; 5547 } 5548 5549 if (onUnitTime) { 5550 if (mid != upper) { 5551 midOffset = tz.getOffset(mid); 5552 if (midOffset != upperOffset) { 5553 return findPreviousZoneTransitionTime(tz, upperOffset, upper, mid); 5554 } 5555 upper = mid; 5556 } 5557 // check mid-1 5558 mid--; 5559 } else { 5560 mid = (upper + lower) >>> 1; 5561 } 5562 5563 if (mid == lower) { 5564 return Long.valueOf(upper); 5565 } 5566 midOffset = tz.getOffset(mid); 5567 if (midOffset != upperOffset) { 5568 if (onUnitTime) { 5569 return Long.valueOf(upper); 5570 } 5571 return findPreviousZoneTransitionTime(tz, upperOffset, upper, mid); 5572 } 5573 return findPreviousZoneTransitionTime(tz, upperOffset, mid, lower); 5574 } 5575 5576 /** 5577 * Compute the milliseconds in the day from the fields. This is a 5578 * value from 0 to 23:59:59.999 inclusive, unless fields are out of 5579 * range, in which case it can be an arbitrary value. This value 5580 * reflects local zone wall time. 5581 * @stable ICU 2.0 5582 */ computeMillisInDay()5583 protected int computeMillisInDay() { 5584 // Do the time portion of the conversion. 5585 5586 int millisInDay = 0; 5587 5588 // Find the best set of fields specifying the time of day. There 5589 // are only two possibilities here; the HOUR_OF_DAY or the 5590 // AM_PM and the HOUR. 5591 int hourOfDayStamp = stamp[HOUR_OF_DAY]; 5592 int hourStamp = Math.max(stamp[HOUR], stamp[AM_PM]); 5593 int bestStamp = (hourStamp > hourOfDayStamp) ? hourStamp : hourOfDayStamp; 5594 5595 // Hours 5596 if (bestStamp != UNSET) { 5597 if (bestStamp == hourOfDayStamp) { 5598 // Don't normalize here; let overflow bump into the next period. 5599 // This is consistent with how we handle other fields. 5600 millisInDay += internalGet(HOUR_OF_DAY); 5601 } else { 5602 // Don't normalize here; let overflow bump into the next period. 5603 // This is consistent with how we handle other fields. 5604 millisInDay += internalGet(HOUR); 5605 millisInDay += 12 * internalGet(AM_PM); // Default works for unset AM_PM 5606 } 5607 } 5608 5609 // We use the fact that unset == 0; we start with millisInDay 5610 // == HOUR_OF_DAY. 5611 millisInDay *= 60; 5612 millisInDay += internalGet(MINUTE); // now have minutes 5613 millisInDay *= 60; 5614 millisInDay += internalGet(SECOND); // now have seconds 5615 millisInDay *= 1000; 5616 millisInDay += internalGet(MILLISECOND); // now have millis 5617 5618 return millisInDay; 5619 } 5620 5621 /** 5622 * This method can assume EXTENDED_YEAR has been set. 5623 * @param millis milliseconds of the date fields (local midnight millis) 5624 * @param millisInDay milliseconds of the time fields; may be out 5625 * or range. 5626 * @return total zone offset (raw + DST) for the given moment 5627 * @stable ICU 2.0 5628 */ computeZoneOffset(long millis, int millisInDay)5629 protected int computeZoneOffset(long millis, int millisInDay) { 5630 int[] offsets = new int[2]; 5631 long wall = millis + millisInDay; 5632 if (zone instanceof BasicTimeZone) { 5633 int duplicatedTimeOpt = (repeatedWallTime == WALLTIME_FIRST) ? BasicTimeZone.LOCAL_FORMER : BasicTimeZone.LOCAL_LATTER; 5634 int nonExistingTimeOpt = (skippedWallTime == WALLTIME_FIRST) ? BasicTimeZone.LOCAL_LATTER : BasicTimeZone.LOCAL_FORMER; 5635 ((BasicTimeZone)zone).getOffsetFromLocal(wall, nonExistingTimeOpt, duplicatedTimeOpt, offsets); 5636 } else { 5637 // By default, TimeZone#getOffset behaves WALLTIME_LAST for both. 5638 zone.getOffset(wall, true, offsets); 5639 5640 boolean sawRecentNegativeShift = false; 5641 if (repeatedWallTime == WALLTIME_FIRST) { 5642 // Check if the given wall time falls into repeated time range 5643 long tgmt = wall - (offsets[0] + offsets[1]); 5644 5645 // Any negative zone transition within last 6 hours? 5646 // Note: The maximum historic negative zone transition is -3 hours in the tz database. 5647 // 6 hour window would be sufficient for this purpose. 5648 int offsetBefore6 = zone.getOffset(tgmt - 6*60*60*1000); 5649 int offsetDelta = (offsets[0] + offsets[1]) - offsetBefore6; 5650 5651 assert offsetDelta < -6*60*60*1000 : offsetDelta; 5652 if (offsetDelta < 0) { 5653 sawRecentNegativeShift = true; 5654 // Negative shift within last 6 hours. When WALLTIME_FIRST is used and the given wall time falls 5655 // into the repeated time range, use offsets before the transition. 5656 // Note: If it does not fall into the repeated time range, offsets remain unchanged below. 5657 zone.getOffset(wall + offsetDelta, true, offsets); 5658 } 5659 } 5660 if (!sawRecentNegativeShift && skippedWallTime == WALLTIME_FIRST) { 5661 // When skipped wall time option is WALLTIME_FIRST, 5662 // recalculate offsets from the resolved time (non-wall). 5663 // When the given wall time falls into skipped wall time, 5664 // the offsets will be based on the zone offsets AFTER 5665 // the transition (which means, earliest possibe interpretation). 5666 long tgmt = wall - (offsets[0] + offsets[1]); 5667 zone.getOffset(tgmt, false, offsets); 5668 } 5669 } 5670 return offsets[0] + offsets[1]; 5671 } 5672 5673 /** 5674 * Compute the Julian day number as specified by this calendar's fields. 5675 * @stable ICU 2.0 5676 */ 5677 protected int computeJulianDay() { 5678 5679 // We want to see if any of the date fields is newer than the 5680 // JULIAN_DAY. If not, then we use JULIAN_DAY. If so, then we do 5681 // the normal resolution. We only use JULIAN_DAY if it has been 5682 // set by the user. This makes it possible for the caller to set 5683 // the calendar to a time and call clear(MONTH) to reset the MONTH 5684 // to January. This is legacy behavior. Without this, 5685 // clear(MONTH) has no effect, since the internally set JULIAN_DAY 5686 // is used. 5687 if (stamp[JULIAN_DAY] >= MINIMUM_USER_STAMP) { 5688 int bestStamp = newestStamp(ERA, DAY_OF_WEEK_IN_MONTH, UNSET); 5689 bestStamp = newestStamp(YEAR_WOY, EXTENDED_YEAR, bestStamp); 5690 if (bestStamp <= stamp[JULIAN_DAY]) { 5691 return internalGet(JULIAN_DAY); 5692 } 5693 } 5694 5695 int bestField = resolveFields(getFieldResolutionTable()); 5696 if (bestField < 0) { 5697 bestField = DAY_OF_MONTH; 5698 } 5699 5700 return handleComputeJulianDay(bestField); 5701 } 5702 5703 /** 5704 * Returns the field resolution array for this calendar. Calendars that 5705 * define additional fields or change the semantics of existing fields 5706 * should override this method to adjust the field resolution semantics 5707 * accordingly. Other subclasses should not override this method. 5708 * @see #resolveFields 5709 * @stable ICU 2.0 5710 */ 5711 protected int[][][] getFieldResolutionTable() { 5712 return DATE_PRECEDENCE; 5713 } 5714 5715 /** 5716 * Returns the Julian day number of day before the first day of the 5717 * given month in the given extended year. Subclasses should override 5718 * this method to implement their calendar system. 5719 * @param eyear the extended year 5720 * @param month the zero-based month, or 0 if useMonth is false 5721 * @param useMonth if false, compute the day before the first day of 5722 * the given year, otherwise, compute the day before the first day of 5723 * the given month 5724 * @return the Julian day number of the day before the first 5725 * day of the given month and year 5726 * @stable ICU 2.0 5727 */ 5728 abstract protected int handleComputeMonthStart(int eyear, int month, 5729 boolean useMonth); 5730 5731 /** 5732 * Returns the extended year defined by the current fields. This will 5733 * use the EXTENDED_YEAR field or the YEAR and supra-year fields (such 5734 * as ERA) specific to the calendar system, depending on which set of 5735 * fields is newer. 5736 * @return the extended year 5737 * @stable ICU 2.0 5738 */ 5739 abstract protected int handleGetExtendedYear(); 5740 5741 // (The following method is not called because all existing subclasses 5742 // override it. 2003-06-11 ICU 2.6 Alan) 5743 ///CLOVER:OFF 5744 /** 5745 * Returns the number of days in the given month of the given extended 5746 * year of this calendar system. Subclasses should override this 5747 * method if they can provide a more correct or more efficient 5748 * implementation than the default implementation in Calendar. 5749 * @stable ICU 2.0 5750 */ 5751 protected int handleGetMonthLength(int extendedYear, int month) { 5752 return handleComputeMonthStart(extendedYear, month+1, true) - 5753 handleComputeMonthStart(extendedYear, month, true); 5754 } 5755 ///CLOVER:ON 5756 5757 /** 5758 * Returns the number of days in the given extended year of this 5759 * calendar system. Subclasses should override this method if they can 5760 * provide a more correct or more efficient implementation than the 5761 * default implementation in Calendar. 5762 * @stable ICU 2.0 5763 */ 5764 protected int handleGetYearLength(int eyear) { 5765 return handleComputeMonthStart(eyear+1, 0, false) - 5766 handleComputeMonthStart(eyear, 0, false); 5767 } 5768 5769 /** 5770 * Subclasses that use additional fields beyond those defined in 5771 * <code>Calendar</code> should override this method to return an 5772 * <code>int[]</code> array of the appropriate length. The length 5773 * must be at least <code>BASE_FIELD_COUNT</code> and no more than 5774 * <code>MAX_FIELD_COUNT</code>. 5775 * @stable ICU 2.0 5776 */ 5777 protected int[] handleCreateFields() { 5778 return new int[BASE_FIELD_COUNT]; 5779 } 5780 5781 /** 5782 * Subclasses may override this. 5783 * Called by handleComputeJulianDay. Returns the default month (0-based) for the year, 5784 * taking year and era into account. Defaults to 0 (JANUARY) for Gregorian. 5785 * @param extendedYear the extendedYear, as returned by handleGetExtendedYear 5786 * @return the default month 5787 * @draft ICU 3.6 (retain) 5788 * @provisional This API might change or be removed in a future release. 5789 * @see #MONTH 5790 */ 5791 protected int getDefaultMonthInYear(int extendedYear) { 5792 return Calendar.JANUARY; 5793 } 5794 5795 /** 5796 * Subclasses may override this. 5797 * Called by handleComputeJulianDay. Returns the default day (1-based) for the month, 5798 * taking currently-set year and era into account. Defaults to 1 for Gregorian. 5799 * @param extendedYear the extendedYear, as returned by handleGetExtendedYear 5800 * @param month the month, as returned by getDefaultMonthInYear 5801 * @return the default day of the month 5802 * @draft ICU 3.6 (retain) 5803 * @provisional This API might change or be removed in a future release. 5804 * @see #DAY_OF_MONTH 5805 */ 5806 protected int getDefaultDayInMonth(int extendedYear, int month) { 5807 return 1; 5808 } 5809 5810 5811 /** 5812 * Subclasses may override this. This method calls 5813 * handleGetMonthLength() to obtain the calendar-specific month 5814 * length. 5815 * @stable ICU 2.0 5816 */ 5817 protected int handleComputeJulianDay(int bestField) { 5818 5819 boolean useMonth = (bestField == DAY_OF_MONTH || 5820 bestField == WEEK_OF_MONTH || 5821 bestField == DAY_OF_WEEK_IN_MONTH); 5822 5823 int year; 5824 5825 if (bestField == WEEK_OF_YEAR) { 5826 // Nota Bene! It is critical that YEAR_WOY be used as the year here, if it is 5827 // set. Otherwise, when WOY is the best field, the year may be wrong at the 5828 // extreme limits of the year. If YEAR_WOY is not set then it will fall back. 5829 // TODO: Should resolveField(YEAR_PRECEDENCE) be brought to bear? 5830 year = internalGet(YEAR_WOY, handleGetExtendedYear()); 5831 } else { 5832 year = handleGetExtendedYear(); 5833 } 5834 5835 internalSet(EXTENDED_YEAR, year); 5836 5837 int month = useMonth ? internalGet(MONTH, getDefaultMonthInYear(year)) : 0; 5838 5839 // Get the Julian day of the day BEFORE the start of this year. 5840 // If useMonth is true, get the day before the start of the month. 5841 int julianDay = handleComputeMonthStart(year, month, useMonth); 5842 5843 if (bestField == DAY_OF_MONTH) { 5844 if(isSet(DAY_OF_MONTH)) { 5845 return julianDay + internalGet(DAY_OF_MONTH, getDefaultDayInMonth(year, month)); 5846 } else { 5847 return julianDay + getDefaultDayInMonth(year, month); 5848 } 5849 } 5850 5851 if (bestField == DAY_OF_YEAR) { 5852 return julianDay + internalGet(DAY_OF_YEAR); 5853 } 5854 5855 int firstDOW = getFirstDayOfWeek(); // Localized fdw 5856 5857 // At this point julianDay is the 0-based day BEFORE the first day of 5858 // January 1, year 1 of the given calendar. If julianDay == 0, it 5859 // specifies (Jan. 1, 1) - 1, in whatever calendar we are using (Julian 5860 // or Gregorian). 5861 5862 // At this point we need to process the WEEK_OF_MONTH or 5863 // WEEK_OF_YEAR, which are similar, or the DAY_OF_WEEK_IN_MONTH. 5864 // First, perform initial shared computations. These locate the 5865 // first week of the period. 5866 5867 // Get the 0-based localized DOW of day one of the month or year. 5868 // Valid range 0..6. 5869 int first = julianDayToDayOfWeek(julianDay + 1) - firstDOW; 5870 if (first < 0) { 5871 first += 7; 5872 } 5873 5874 // Get zero-based localized DOW, valid range 0..6. This is the DOW 5875 // we are looking for. 5876 int dowLocal = 0; 5877 switch (resolveFields(DOW_PRECEDENCE)) { 5878 case DAY_OF_WEEK: 5879 dowLocal = internalGet(DAY_OF_WEEK) - firstDOW; 5880 break; 5881 case DOW_LOCAL: 5882 dowLocal = internalGet(DOW_LOCAL) - 1; 5883 break; 5884 } 5885 dowLocal = dowLocal % 7; 5886 if (dowLocal < 0) { 5887 dowLocal += 7; 5888 } 5889 5890 // Find the first target DOW (dowLocal) in the month or year. 5891 // Actually, it may be just before the first of the month or year. 5892 // It will be an integer from -5..7. 5893 int date = 1 - first + dowLocal; 5894 5895 if (bestField == DAY_OF_WEEK_IN_MONTH) { 5896 5897 // Adjust the target DOW to be in the month or year. 5898 if (date < 1) { 5899 date += 7; 5900 } 5901 5902 // The only trickiness occurs if the day-of-week-in-month is 5903 // negative. 5904 int dim = internalGet(DAY_OF_WEEK_IN_MONTH, 1); 5905 if (dim >= 0) { 5906 date += 7*(dim - 1); 5907 5908 } else { 5909 // Move date to the last of this day-of-week in this month, 5910 // then back up as needed. If dim==-1, we don't back up at 5911 // all. If dim==-2, we back up once, etc. Don't back up 5912 // past the first of the given day-of-week in this month. 5913 // Note that we handle -2, -3, etc. correctly, even though 5914 // values < -1 are technically disallowed. 5915 int m = internalGet(MONTH, JANUARY); 5916 int monthLength = handleGetMonthLength(year, m); 5917 date += ((monthLength - date) / 7 + dim + 1) * 7; 5918 } 5919 } else { 5920 // assert(bestField == WEEK_OF_MONTH || bestField == WEEK_OF_YEAR) 5921 5922 // Adjust for minimal days in first week 5923 if ((7 - first) < getMinimalDaysInFirstWeek()) { 5924 date += 7; 5925 } 5926 5927 // Now adjust for the week number. 5928 date += 7 * (internalGet(bestField) - 1); 5929 } 5930 5931 return julianDay + date; 5932 } 5933 5934 /** 5935 * Compute the Julian day of a month of the Gregorian calendar. 5936 * Subclasses may call this method to perform a Gregorian calendar 5937 * fields->millis computation. To perform a Gregorian calendar 5938 * millis->fields computation, call computeGregorianFields(). 5939 * @param year extended Gregorian year 5940 * @param month zero-based Gregorian month 5941 * @return the Julian day number of the day before the first 5942 * day of the given month in the given extended year 5943 * @see #computeGregorianFields 5944 * @stable ICU 2.0 5945 */ 5946 protected int computeGregorianMonthStart(int year, int month) { 5947 5948 // If the month is out of range, adjust it into range, and 5949 // modify the extended year value accordingly. 5950 if (month < 0 || month > 11) { 5951 int[] rem = new int[1]; 5952 year += floorDivide(month, 12, rem); 5953 month = rem[0]; 5954 } 5955 5956 boolean isLeap = (year%4 == 0) && ((year%100 != 0) || (year%400 == 0)); 5957 int y = year - 1; 5958 // This computation is actually ... + (JAN_1_1_JULIAN_DAY - 3) + 2. 5959 // Add 2 because Gregorian calendar starts 2 days after Julian 5960 // calendar. 5961 int julianDay = 365*y + floorDivide(y, 4) - floorDivide(y, 100) + 5962 floorDivide(y, 400) + JAN_1_1_JULIAN_DAY - 1; 5963 5964 // At this point julianDay indicates the day BEFORE the first day 5965 // of January 1, <eyear> of the Gregorian calendar. 5966 if (month != 0) { 5967 julianDay += GREGORIAN_MONTH_COUNT[month][isLeap?3:2]; 5968 } 5969 5970 return julianDay; 5971 } 5972 5973 //---------------------------------------------------------------------- 5974 // Subclass API 5975 // For subclasses to override 5976 //---------------------------------------------------------------------- 5977 5978 // (The following method is not called because all existing subclasses 5979 // override it. 2003-06-11 ICU 2.6 Alan) 5980 ///CLOVER:OFF 5981 /** 5982 * Subclasses may override this method to compute several fields 5983 * specific to each calendar system. These are: 5984 * 5985 * <ul><li>ERA 5986 * <li>YEAR 5987 * <li>MONTH 5988 * <li>DAY_OF_MONTH 5989 * <li>DAY_OF_YEAR 5990 * <li>EXTENDED_YEAR</ul> 5991 * 5992 * Subclasses can refer to the DAY_OF_WEEK and DOW_LOCAL fields, which 5993 * will be set when this method is called. Subclasses can also call 5994 * the getGregorianXxx() methods to obtain Gregorian calendar 5995 * equivalents for the given Julian day. 5996 * 5997 * <p>In addition, subclasses should compute any subclass-specific 5998 * fields, that is, fields from BASE_FIELD_COUNT to 5999 * getFieldCount() - 1. 6000 * 6001 * <p>The default implementation in <code>Calendar</code> implements 6002 * a pure proleptic Gregorian calendar. 6003 * @stable ICU 2.0 6004 */ 6005 protected void handleComputeFields(int julianDay) { 6006 internalSet(MONTH, getGregorianMonth()); 6007 internalSet(DAY_OF_MONTH, getGregorianDayOfMonth()); 6008 internalSet(DAY_OF_YEAR, getGregorianDayOfYear()); 6009 int eyear = getGregorianYear(); 6010 internalSet(EXTENDED_YEAR, eyear); 6011 int era = GregorianCalendar.AD; 6012 if (eyear < 1) { 6013 era = GregorianCalendar.BC; 6014 eyear = 1 - eyear; 6015 } 6016 internalSet(ERA, era); 6017 internalSet(YEAR, eyear); 6018 } 6019 ///CLOVER:ON 6020 6021 //---------------------------------------------------------------------- 6022 // Subclass API 6023 // For subclasses to call 6024 //---------------------------------------------------------------------- 6025 6026 /** 6027 * Returns the extended year on the Gregorian calendar as computed by 6028 * <code>computeGregorianFields()</code>. 6029 * @see #computeGregorianFields 6030 * @stable ICU 2.0 6031 */ 6032 protected final int getGregorianYear() { 6033 return gregorianYear; 6034 } 6035 6036 /** 6037 * Returns the month (0-based) on the Gregorian calendar as computed by 6038 * <code>computeGregorianFields()</code>. 6039 * @see #computeGregorianFields 6040 * @stable ICU 2.0 6041 */ 6042 protected final int getGregorianMonth() { 6043 return gregorianMonth; 6044 } 6045 6046 /** 6047 * Returns the day of year (1-based) on the Gregorian calendar as 6048 * computed by <code>computeGregorianFields()</code>. 6049 * @see #computeGregorianFields 6050 * @stable ICU 2.0 6051 */ 6052 protected final int getGregorianDayOfYear() { 6053 return gregorianDayOfYear; 6054 } 6055 6056 /** 6057 * Returns the day of month (1-based) on the Gregorian calendar as 6058 * computed by <code>computeGregorianFields()</code>. 6059 * @see #computeGregorianFields 6060 * @stable ICU 2.0 6061 */ 6062 protected final int getGregorianDayOfMonth() { 6063 return gregorianDayOfMonth; 6064 } 6065 6066 /** 6067 * {@icu} Returns the number of fields defined by this calendar. Valid field 6068 * arguments to <code>set()</code> and <code>get()</code> are 6069 * <code>0..getFieldCount()-1</code>. 6070 * @stable ICU 2.0 6071 */ 6072 public final int getFieldCount() { 6073 return fields.length; 6074 } 6075 6076 /** 6077 * Set a field to a value. Subclasses should use this method when 6078 * computing fields. It sets the time stamp in the 6079 * <code>stamp[]</code> array to <code>INTERNALLY_SET</code>. If a 6080 * field that may not be set by subclasses is passed in, an 6081 * <code>IllegalArgumentException</code> is thrown. This prevents 6082 * subclasses from modifying fields that are intended to be 6083 * calendar-system invariant. 6084 * @stable ICU 2.0 6085 */ 6086 protected final void internalSet(int field, int value) { 6087 if (((1 << field) & internalSetMask) == 0) { 6088 throw new IllegalStateException("Subclass cannot set " + 6089 fieldName(field)); 6090 } 6091 fields[field] = value; 6092 stamp[field] = INTERNALLY_SET; 6093 } 6094 6095 private static final int[][] GREGORIAN_MONTH_COUNT = { 6096 //len len2 st st2 6097 { 31, 31, 0, 0 }, // Jan 6098 { 28, 29, 31, 31 }, // Feb 6099 { 31, 31, 59, 60 }, // Mar 6100 { 30, 30, 90, 91 }, // Apr 6101 { 31, 31, 120, 121 }, // May 6102 { 30, 30, 151, 152 }, // Jun 6103 { 31, 31, 181, 182 }, // Jul 6104 { 31, 31, 212, 213 }, // Aug 6105 { 30, 30, 243, 244 }, // Sep 6106 { 31, 31, 273, 274 }, // Oct 6107 { 30, 30, 304, 305 }, // Nov 6108 { 31, 31, 334, 335 } // Dec 6109 // len length of month 6110 // len2 length of month in a leap year 6111 // st days in year before start of month 6112 // st2 days in year before month in leap year 6113 }; 6114 6115 /** 6116 * Determines if the given year is a leap year. Returns true if the 6117 * given year is a leap year. 6118 * @param year the given year. 6119 * @return true if the given year is a leap year; false otherwise. 6120 * @stable ICU 2.0 6121 */ 6122 protected static final boolean isGregorianLeapYear(int year) { 6123 return (year%4 == 0) && ((year%100 != 0) || (year%400 == 0)); 6124 } 6125 6126 /** 6127 * Returns the length of a month of the Gregorian calendar. 6128 * @param y the extended year 6129 * @param m the 0-based month number 6130 * @return the number of days in the given month 6131 * @stable ICU 2.0 6132 */ 6133 protected static final int gregorianMonthLength(int y, int m) { 6134 return GREGORIAN_MONTH_COUNT[m][isGregorianLeapYear(y)?1:0]; 6135 } 6136 6137 /** 6138 * Returns the length of a previous month of the Gregorian calendar. 6139 * @param y the extended year 6140 * @param m the 0-based month number 6141 * @return the number of days in the month previous to the given month 6142 * @stable ICU 2.0 6143 */ 6144 protected static final int gregorianPreviousMonthLength(int y, int m) { 6145 return (m > 0) ? gregorianMonthLength(y, m-1) : 31; 6146 } 6147 6148 /** 6149 * Divide two long integers, returning the floor of the quotient. 6150 * <p> 6151 * Unlike the built-in division, this is mathematically well-behaved. 6152 * E.g., <code>-1/4</code> => 0 6153 * but <code>floorDivide(-1,4)</code> => -1. 6154 * @param numerator the numerator 6155 * @param denominator a divisor which must be > 0 6156 * @return the floor of the quotient. 6157 * @stable ICU 2.0 6158 */ 6159 protected static final long floorDivide(long numerator, long denominator) { 6160 // We do this computation in order to handle 6161 // a numerator of Long.MIN_VALUE correctly 6162 return (numerator >= 0) ? 6163 numerator / denominator : 6164 ((numerator + 1) / denominator) - 1; 6165 } 6166 6167 /** 6168 * Divide two integers, returning the floor of the quotient. 6169 * <p> 6170 * Unlike the built-in division, this is mathematically well-behaved. 6171 * E.g., <code>-1/4</code> => 0 6172 * but <code>floorDivide(-1,4)</code> => -1. 6173 * @param numerator the numerator 6174 * @param denominator a divisor which must be > 0 6175 * @return the floor of the quotient. 6176 * @stable ICU 2.0 6177 */ 6178 protected static final int floorDivide(int numerator, int denominator) { 6179 // We do this computation in order to handle 6180 // a numerator of Integer.MIN_VALUE correctly 6181 return (numerator >= 0) ? 6182 numerator / denominator : 6183 ((numerator + 1) / denominator) - 1; 6184 } 6185 6186 /** 6187 * Divide two integers, returning the floor of the quotient, and 6188 * the modulus remainder. 6189 * <p> 6190 * Unlike the built-in division, this is mathematically well-behaved. 6191 * E.g., <code>-1/4</code> => 0 and <code>-1%4</code> => -1, 6192 * but <code>floorDivide(-1,4)</code> => -1 with <code>remainder[0]</code> => 3. 6193 * @param numerator the numerator 6194 * @param denominator a divisor which must be > 0 6195 * @param remainder an array of at least one element in which the value 6196 * <code>numerator mod denominator</code> is returned. Unlike <code>numerator 6197 * % denominator</code>, this will always be non-negative. 6198 * @return the floor of the quotient. 6199 * @stable ICU 2.0 6200 */ 6201 protected static final int floorDivide(int numerator, int denominator, int[] remainder) { 6202 if (numerator >= 0) { 6203 remainder[0] = numerator % denominator; 6204 return numerator / denominator; 6205 } 6206 int quotient = ((numerator + 1) / denominator) - 1; 6207 remainder[0] = numerator - (quotient * denominator); 6208 return quotient; 6209 } 6210 6211 /** 6212 * Divide two integers, returning the floor of the quotient, and 6213 * the modulus remainder. 6214 * <p> 6215 * Unlike the built-in division, this is mathematically well-behaved. 6216 * E.g., <code>-1/4</code> => 0 and <code>-1%4</code> => -1, 6217 * but <code>floorDivide(-1,4)</code> => -1 with <code>remainder[0]</code> => 3. 6218 * @param numerator the numerator 6219 * @param denominator a divisor which must be > 0 6220 * @param remainder an array of at least one element in which the value 6221 * <code>numerator mod denominator</code> is returned. Unlike <code>numerator 6222 * % denominator</code>, this will always be non-negative. 6223 * @return the floor of the quotient. 6224 * @stable ICU 2.0 6225 */ 6226 protected static final int floorDivide(long numerator, int denominator, int[] remainder) { 6227 if (numerator >= 0) { 6228 remainder[0] = (int)(numerator % denominator); 6229 return (int)(numerator / denominator); 6230 } 6231 int quotient = (int)(((numerator + 1) / denominator) - 1); 6232 remainder[0] = (int)(numerator - ((long)quotient * denominator)); 6233 return quotient; 6234 } 6235 6236 private static final String[] FIELD_NAME = { 6237 "ERA", "YEAR", "MONTH", "WEEK_OF_YEAR", "WEEK_OF_MONTH", 6238 "DAY_OF_MONTH", "DAY_OF_YEAR", "DAY_OF_WEEK", 6239 "DAY_OF_WEEK_IN_MONTH", "AM_PM", "HOUR", "HOUR_OF_DAY", 6240 "MINUTE", "SECOND", "MILLISECOND", "ZONE_OFFSET", 6241 "DST_OFFSET", "YEAR_WOY", "DOW_LOCAL", "EXTENDED_YEAR", 6242 "JULIAN_DAY", "MILLISECONDS_IN_DAY", 6243 }; 6244 6245 /** 6246 * Returns a string name for a field, for debugging and exceptions. 6247 * @stable ICU 2.0 6248 */ 6249 protected String fieldName(int field) { 6250 try { 6251 return FIELD_NAME[field]; 6252 } catch (ArrayIndexOutOfBoundsException e) { 6253 return "Field " + field; 6254 } 6255 } 6256 6257 /** 6258 * Converts time as milliseconds to Julian day. 6259 * @param millis the given milliseconds. 6260 * @return the Julian day number. 6261 * @stable ICU 2.0 6262 */ 6263 protected static final int millisToJulianDay(long millis) { 6264 return (int) (EPOCH_JULIAN_DAY + floorDivide(millis, ONE_DAY)); 6265 } 6266 6267 /** 6268 * Converts Julian day to time as milliseconds. 6269 * @param julian the given Julian day number. 6270 * @return time as milliseconds. 6271 * @stable ICU 2.0 6272 */ 6273 protected static final long julianDayToMillis(int julian) { 6274 return (julian - EPOCH_JULIAN_DAY) * ONE_DAY; 6275 } 6276 6277 /** 6278 * Returns the day of week, from SUNDAY to SATURDAY, given a Julian day. 6279 * @stable ICU 2.0 6280 */ 6281 protected static final int julianDayToDayOfWeek(int julian) { 6282 // If julian is negative, then julian%7 will be negative, so we adjust 6283 // accordingly. Julian day 0 is Monday. 6284 int dayOfWeek = (julian + MONDAY) % 7; 6285 if (dayOfWeek < SUNDAY) { 6286 dayOfWeek += 7; 6287 } 6288 return dayOfWeek; 6289 } 6290 6291 /** 6292 * Returns the current milliseconds without recomputing. 6293 * @stable ICU 2.0 6294 */ 6295 protected final long internalGetTimeInMillis() { 6296 return time; 6297 } 6298 6299 /** 6300 * {@icu} Returns the calendar type name string for this Calendar object. 6301 * The returned string is the legacy ICU calendar attribute value, 6302 * for example, "gregorian" or "japanese". 6303 * 6304 * <p>See type="old type name" for the calendar attribute of locale IDs 6305 * at http://www.unicode.org/reports/tr35/#Key_Type_Definitions 6306 * 6307 * @return legacy calendar type name string 6308 * @stable ICU 3.8 6309 */ 6310 public String getType() { 6311 return "unknown"; 6312 } 6313 6314 /** 6315 * Returns if two digit representation of year in this calendar type 6316 * customarily implies a default century (i.e. 03 -> 2003). 6317 * The default implementation returns <code>true</code>. A subclass may 6318 * return <code>false</code> if such practice is not applicable (for example, 6319 * Chinese calendar and Japanese calendar). 6320 * 6321 * @return <code>true<code> if this calendar has a default century. 6322 * @internal 6323 * @deprecated This API is ICU internal only. 6324 */ 6325 @Deprecated 6326 public boolean haveDefaultCentury() { 6327 return true; 6328 } 6329 6330 // -------- BEGIN ULocale boilerplate -------- 6331 6332 /** 6333 * {@icu} Returns the locale that was used to create this object, or null. 6334 * This may may differ from the locale requested at the time of 6335 * this object's creation. For example, if an object is created 6336 * for locale <tt>en_US_CALIFORNIA</tt>, the actual data may be 6337 * drawn from <tt>en</tt> (the <i>actual</i> locale), and 6338 * <tt>en_US</tt> may be the most specific locale that exists (the 6339 * <i>valid</i> locale). 6340 * 6341 * <p>Note: This method will be implemented in ICU 3.0; ICU 2.8 6342 * contains a partial preview implementation. The * <i>actual</i> 6343 * locale is returned correctly, but the <i>valid</i> locale is 6344 * not, in most cases. 6345 * @param type type of information requested, either {@link 6346 * com.ibm.icu.util.ULocale#VALID_LOCALE} or {@link 6347 * com.ibm.icu.util.ULocale#ACTUAL_LOCALE}. 6348 * @return the information specified by <i>type</i>, or null if 6349 * this object was not constructed from locale data. 6350 * @see com.ibm.icu.util.ULocale 6351 * @see com.ibm.icu.util.ULocale#VALID_LOCALE 6352 * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE 6353 * @draft ICU 2.8 (retain) 6354 * @provisional This API might change or be removed in a future release. 6355 */ 6356 public final ULocale getLocale(ULocale.Type type) { 6357 return type == ULocale.ACTUAL_LOCALE ? 6358 this.actualLocale : this.validLocale; 6359 } 6360 6361 /** 6362 * Set information about the locales that were used to create this 6363 * object. If the object was not constructed from locale data, 6364 * both arguments should be set to null. Otherwise, neither 6365 * should be null. The actual locale must be at the same level or 6366 * less specific than the valid locale. This method is intended 6367 * for use by factories or other entities that create objects of 6368 * this class. 6369 * @param valid the most specific locale containing any resource 6370 * data, or null 6371 * @param actual the locale containing data used to construct this 6372 * object, or null 6373 * @see com.ibm.icu.util.ULocale 6374 * @see com.ibm.icu.util.ULocale#VALID_LOCALE 6375 * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE 6376 */ 6377 final void setLocale(ULocale valid, ULocale actual) { 6378 // Change the following to an assertion later 6379 if ((valid == null) != (actual == null)) { 6380 ///CLOVER:OFF 6381 throw new IllegalArgumentException(); 6382 ///CLOVER:ON 6383 } 6384 // Another check we could do is that the actual locale is at 6385 // the same level or less specific than the valid locale. 6386 this.validLocale = valid; 6387 this.actualLocale = actual; 6388 } 6389 6390 /** 6391 * The most specific locale containing any resource data, or null. 6392 * @see com.ibm.icu.util.ULocale 6393 */ 6394 private ULocale validLocale; 6395 6396 /** 6397 * The locale containing data used to construct this object, or 6398 * null. 6399 * @see com.ibm.icu.util.ULocale 6400 */ 6401 private ULocale actualLocale; 6402 6403 // -------- END ULocale boilerplate -------- 6404 } 6405