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