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