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