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