1 /* 2 * hunt-time: A time library for D programming language. 3 * 4 * Copyright (C) 2015-2018 HuntLabs 5 * 6 * Website: https://www.huntlabs.net/ 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module hunt.time.util.Calendar; 13 14 import hunt.Exceptions; 15 // import hunt.stream.Common; 16 // import java.security.AccessControlContext; 17 // import java.security.AccessController; 18 // import java.security.PermissionCollection; 19 // import java.security.PrivilegedActionException; 20 // import java.security.PrivilegedExceptionAction; 21 // import java.security.ProtectionDomain; 22 // import java.text.DateFormat; 23 // import java.text.DateFormatSymbols; 24 import hunt.time.Instant; 25 import hunt.collection; 26 import hunt.time.util.Common; 27 import hunt.util.Locale; 28 // import java.util.concurrent.ConcurrentHashMap; 29 // import java.util.concurrent.ConcurrentMap; 30 // import sun.util.BuddhistCalendar; 31 // import sun.util.calendar.ZoneInfo; 32 // import sun.util.locale.provider.CalendarDataUtility; 33 // import sun.util.locale.provider.LocaleProviderAdapter; 34 // import sun.util.locale.provider.TimeZoneNameUtility; 35 // import sun.util.spi.CalendarProvider; 36 37 import std.datetime; 38 39 /** 40 * The <code>Calendar</code> class is an abstract class that provides methods 41 * for converting between a specific instant in time and a set of {@link 42 * #fields calendar fields} such as <code>YEAR</code>, <code>MONTH</code>, 43 * <code>DAY_OF_MONTH</code>, <code>HOUR</code>, and so on, and for 44 * manipulating the calendar fields, such as getting the date of the next 45 * week. An instant in time can be represented by a millisecond value that is 46 * an offset from the <a id="Epoch"><em>Epoch</em></a>, January 1, 1970 47 * 00:00:00.000 GMT (Gregorian). 48 * 49 * <p>The class also provides additional fields and methods for 50 * implementing a concrete calendar system outside the package. Those 51 * fields and methods are defined as <code>protected</code>. 52 * 53 * <p> 54 * Like other locale-sensitive classes, <code>Calendar</code> provides a 55 * class method, <code>getInstance</code>, for getting a generally useful 56 * object of this type. <code>Calendar</code>'s <code>getInstance</code> method 57 * returns a <code>Calendar</code> object whose 58 * calendar fields have been initialized with the current date and time: 59 * <blockquote> 60 * <pre> 61 * Calendar rightNow = Calendar.getInstance(); 62 * </pre> 63 * </blockquote> 64 * 65 * <p>A <code>Calendar</code> object can produce all the calendar field values 66 * needed to implement the date-time formatting for a particular language and 67 * calendar style (for example, Japanese-Gregorian, Japanese-Traditional). 68 * <code>Calendar</code> defines the range of values returned by 69 * certain calendar fields, as well as their meaning. For example, 70 * the first month of the calendar system has value <code>MONTH == 71 * JANUARY</code> for all calendars. Other values are defined by the 72 * concrete subclass, such as <code>ERA</code>. See individual field 73 * documentation and subclass documentation for details. 74 * 75 * <h3>Getting and Setting Calendar Field Values</h3> 76 * 77 * <p>The calendar field values can be set by calling the <code>set</code> 78 * methods. Any field values set in a <code>Calendar</code> will not be 79 * interpreted until it needs to calculate its time value (milliseconds from 80 * the Epoch) or values of the calendar fields. Calling the 81 * <code>get</code>, <code>getTimeInMillis</code>, <code>getTime</code>, 82 * <code>add</code> and <code>roll</code> involves such calculation. 83 * 84 * <h4>Leniency</h4> 85 * 86 * <p><code>Calendar</code> has two modes for interpreting the calendar 87 * fields, <em>lenient</em> and <em>non-lenient</em>. When a 88 * <code>Calendar</code> is in lenient mode, it accepts a wider range of 89 * calendar field values than it produces. When a <code>Calendar</code> 90 * recomputes calendar field values for return by <code>get()</code>, all of 91 * the calendar fields are normalized. For example, a lenient 92 * <code>GregorianCalendar</code> interprets <code>MONTH == JANUARY</code>, 93 * <code>DAY_OF_MONTH == 32</code> as February 1. 94 95 * <p>When a <code>Calendar</code> is in non-lenient mode, it throws an 96 * exception if there is any inconsistency in its calendar fields. For 97 * example, a <code>GregorianCalendar</code> always produces 98 * <code>DAY_OF_MONTH</code> values between 1 and the length of the month. A 99 * non-lenient <code>GregorianCalendar</code> throws an exception upon 100 * calculating its time or calendar field values if any out-of-range field 101 * value has been set. 102 * 103 * <h4><a id="first_week">First Week</a></h4> 104 * 105 * <code>Calendar</code> defines a locale-specific seven day week using two 106 * parameters: the first day of the week and the minimal days in first week 107 * (from 1 to 7). These numbers are taken from the locale resource data or the 108 * locale itself when a {@code Calendar} is constructed. If the designated 109 * locale contains "fw" and/or "rg" <a href="./Locale.html#def_locale_extension"> 110 * Unicode extensions</a>, the first day of the week will be obtained according to 111 * those extensions. If both "fw" and "rg" are specified, the value from the "fw" 112 * extension supersedes the implicit one from the "rg" extension. 113 * They may also be specified explicitly through the methods for setting their 114 * values. 115 * 116 * <p>When setting or getting the <code>WEEK_OF_MONTH</code> or 117 * <code>WEEK_OF_YEAR</code> fields, <code>Calendar</code> must determine the 118 * first week of the month or year as a reference point. The first week of a 119 * month or year is defined as the earliest seven day period beginning on 120 * <code>getFirstDayOfWeek()</code> and containing at least 121 * <code>getMinimalDaysInFirstWeek()</code> days of that month or year. Weeks 122 * numbered ..., -1, 0 precede the first week; weeks numbered 2, 3,... follow 123 * it. Note that the normalized numbering returned by <code>get()</code> may be 124 * different. For example, a specific <code>Calendar</code> subclass may 125 * designate the week before week 1 of a year as week <code><i>n</i></code> of 126 * the previous year. 127 * 128 * <h4>Calendar Fields Resolution</h4> 129 * 130 * When computing a date and time from the calendar fields, there 131 * may be insufficient information for the computation (such as only 132 * year and month with no day of month), or there may be inconsistent 133 * information (such as Tuesday, July 15, 1996 (Gregorian) -- July 15, 134 * 1996 is actually a Monday). <code>Calendar</code> will resolve 135 * calendar field values to determine the date and time in the 136 * following way. 137 * 138 * <p><a id="resolution">If there is any conflict in calendar field values, 139 * <code>Calendar</code> gives priorities to calendar fields that have been set 140 * more recently.</a> The following are the default combinations of the 141 * calendar fields. The most recent combination, as determined by the 142 * most recently set single field, will be used. 143 * 144 * <p><a id="date_resolution">For the date fields</a>: 145 * <blockquote> 146 * <pre> 147 * YEAR + MONTH + DAY_OF_MONTH 148 * YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK 149 * YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK 150 * YEAR + DAY_OF_YEAR 151 * YEAR + DAY_OF_WEEK + WEEK_OF_YEAR 152 * </pre></blockquote> 153 * 154 * <a id="time_resolution">For the time of day fields</a>: 155 * <blockquote> 156 * <pre> 157 * HOUR_OF_DAY 158 * AM_PM + HOUR 159 * </pre></blockquote> 160 * 161 * <p>If there are any calendar fields whose values haven't been set in the selected 162 * field combination, <code>Calendar</code> uses their default values. The default 163 * value of each field may vary by concrete calendar systems. For example, in 164 * <code>GregorianCalendar</code>, the default of a field is the same as that 165 * of the start of the Epoch: i.e., <code>YEAR = 1970</code>, <code>MONTH = 166 * JANUARY</code>, <code>DAY_OF_MONTH = 1</code>, etc. 167 * 168 * <p> 169 * <strong>Note:</strong> There are certain possible ambiguities in 170 * interpretation of certain singular times, which are resolved in the 171 * following ways: 172 * <ol> 173 * <li> 23:59 is the last minute of the day and 00:00 is the first 174 * minute of the next day. Thus, 23:59 on Dec 31, 1999 < 00:00 on 175 * Jan 1, 2000 < 00:01 on Jan 1, 2000. 176 * 177 * <li> Although historically not precise, midnight also belongs to "am", 178 * and noon belongs to "pm", so on the same day, 179 * 12:00 am (midnight) < 12:01 am, and 12:00 pm (noon) < 12:01 pm 180 * </ol> 181 * 182 * <p> 183 * The date or time format strings are not part of the definition of a 184 * calendar, as those must be modifiable or overridable by the user at 185 * runtime. Use {@link DateFormat} 186 * to format dates. 187 * 188 * <h4>Field Manipulation</h4> 189 * 190 * The calendar fields can be changed using three methods: 191 * <code>set()</code>, <code>add()</code>, and <code>roll()</code>. 192 * 193 * <p><strong><code>set(f, value)</code></strong> changes calendar field 194 * <code>f</code> to <code>value</code>. In addition, it sets an 195 * internal member variable to indicate that calendar field <code>f</code> has 196 * been changed. Although calendar field <code>f</code> is changed immediately, 197 * the calendar's time value in milliseconds is not recomputed until the next call to 198 * <code>get()</code>, <code>getTime()</code>, <code>getTimeInMillis()</code>, 199 * <code>add()</code>, or <code>roll()</code> is made. Thus, multiple calls to 200 * <code>set()</code> do not trigger multiple, unnecessary 201 * computations. As a result of changing a calendar field using 202 * <code>set()</code>, other calendar fields may also change, depending on the 203 * calendar field, the calendar field value, and the calendar system. In addition, 204 * <code>get(f)</code> will not necessarily return <code>value</code> set by 205 * the call to the <code>set</code> method 206 * after the calendar fields have been recomputed. The specifics are determined by 207 * the concrete calendar class.</p> 208 * 209 * <p><em>Example</em>: Consider a <code>GregorianCalendar</code> 210 * originally set to August 31, 1999. Calling <code>set(Calendar.MONTH, 211 * Calendar.SEPTEMBER)</code> sets the date to September 31, 212 * 1999. This is a temporary internal representation that resolves to 213 * October 1, 1999 if <code>getTime()</code>is then called. However, a 214 * call to <code>set(Calendar.DAY_OF_MONTH, 30)</code> before the call to 215 * <code>getTime()</code> sets the date to September 30, 1999, since 216 * no recomputation occurs after <code>set()</code> itself.</p> 217 * 218 * <p><strong><code>add(f, delta)</code></strong> adds <code>delta</code> 219 * to field <code>f</code>. This is equivalent to calling <code>set(f, 220 * get(f) + delta)</code> with two adjustments:</p> 221 * 222 * <blockquote> 223 * <p><strong>Add rule 1</strong>. The value of field <code>f</code> 224 * after the call minus the value of field <code>f</code> before the 225 * call is <code>delta</code>, modulo any overflow that has occurred in 226 * field <code>f</code>. Overflow occurs when a field value exceeds its 227 * range and, as a result, the next larger field is incremented or 228 * decremented and the field value is adjusted back into its range.</p> 229 * 230 * <p><strong>Add rule 2</strong>. If a smaller field is expected to be 231 * invariant, but it is impossible for it to be equal to its 232 * prior value because of changes in its minimum or maximum after field 233 * <code>f</code> is changed or other constraints, such as time zone 234 * offset changes, then its value is adjusted to be as close 235 * as possible to its expected value. A smaller field represents a 236 * smaller unit of time. <code>HOUR</code> is a smaller field than 237 * <code>DAY_OF_MONTH</code>. No adjustment is made to smaller fields 238 * that are not expected to be invariant. The calendar system 239 * determines what fields are expected to be invariant.</p> 240 * </blockquote> 241 * 242 * <p>In addition, unlike <code>set()</code>, <code>add()</code> forces 243 * an immediate recomputation of the calendar's milliseconds and all 244 * fields.</p> 245 * 246 * <p><em>Example</em>: Consider a <code>GregorianCalendar</code> 247 * originally set to August 31, 1999. Calling <code>add(Calendar.MONTH, 248 * 13)</code> sets the calendar to September 30, 2000. <strong>Add rule 249 * 1</strong> sets the <code>MONTH</code> field to September, since 250 * adding 13 months to August gives September of the next year. Since 251 * <code>DAY_OF_MONTH</code> cannot be 31 in September in a 252 * <code>GregorianCalendar</code>, <strong>add rule 2</strong> sets the 253 * <code>DAY_OF_MONTH</code> to 30, the closest possible value. Although 254 * it is a smaller field, <code>DAY_OF_WEEK</code> is not adjusted by 255 * rule 2, since it is expected to change when the month changes in a 256 * <code>GregorianCalendar</code>.</p> 257 * 258 * <p><strong><code>roll(f, delta)</code></strong> adds 259 * <code>delta</code> to field <code>f</code> without changing larger 260 * fields. This is equivalent to calling <code>add(f, delta)</code> with 261 * the following adjustment:</p> 262 * 263 * <blockquote> 264 * <p><strong>Roll rule</strong>. Larger fields are unchanged after the 265 * call. A larger field represents a larger unit of 266 * time. <code>DAY_OF_MONTH</code> is a larger field than 267 * <code>HOUR</code>.</p> 268 * </blockquote> 269 * 270 * <p><em>Example</em>: See {@link java.util.GregorianCalendar#roll(int, int)}. 271 * 272 * <p><strong>Usage model</strong>. To motivate the behavior of 273 * <code>add()</code> and <code>roll()</code>, consider a user interface 274 * component with increment and decrement buttons for the month, day, and 275 * year, and an underlying <code>GregorianCalendar</code>. If the 276 * interface reads January 31, 1999 and the user presses the month 277 * increment button, what should it read? If the underlying 278 * implementation uses <code>set()</code>, it might read March 3, 1999. A 279 * better result would be February 28, 1999. Furthermore, if the user 280 * presses the month increment button again, it should read March 31, 281 * 1999, not March 28, 1999. By saving the original date and using either 282 * <code>add()</code> or <code>roll()</code>, depending on whether larger 283 * fields should be affected, the user interface can behave as most users 284 * will intuitively expect.</p> 285 * 286 * @see java.lang.System#currentTimeMillis() 287 * @see LocalDateTime 288 * @see GregorianCalendar 289 * @see TimeZone 290 * @see java.text.DateFormat 291 * @author Mark Davis, David Goldsmith, Chen-Lieh Huang, Alan Liu 292 * @since 1.1 293 */ 294 295 import hunt.stream.Common; 296 import hunt.Functions; 297 import hunt.util.Common; 298 import std.datetime : TimeZone ; 299 300 301 alias HuntCalendar = Calendar; 302 303 abstract class Calendar : Cloneable, Comparable!(Calendar) { // Serializable, 304 305 // Data flow in Calendar 306 // --------------------- 307 308 // The current time is represented in two ways by Calendar: as UTC 309 // milliseconds from the epoch (1 January 1970 0:00 UTC), and as local 310 // fields such as MONTH, HOUR, AM_PM, etc. It is possible to compute the 311 // millis from the fields, and vice versa. The data needed to do this 312 // conversion is encapsulated by a TimeZone object owned by the Calendar. 313 // The data provided by the TimeZone object may also be overridden if the 314 // user sets the ZONE_OFFSET and/or DST_OFFSET fields directly. The class 315 // keeps track of what information was most recently set by the caller, and 316 // uses that to compute any other information as needed. 317 318 // If the user sets the fields using set(), the data flow is as follows. 319 // This is implemented by the Calendar subclass's computeTime() method. 320 // During this process, certain fields may be ignored. The disambiguation 321 // algorithm for resolving which fields to pay attention to is described 322 // in the class documentation. 323 324 // local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.) 325 // | 326 // | Using Calendar-specific algorithm 327 // V 328 // local standard millis 329 // | 330 // | Using TimeZone or user-set ZONE_OFFSET / DST_OFFSET 331 // V 332 // UTC millis (in time data member) 333 334 // If the user sets the UTC millis using setTime() or setTimeInMillis(), 335 // the data flow is as follows. This is implemented by the Calendar 336 // subclass's computeFields() method. 337 338 // UTC millis (in time data member) 339 // | 340 // | Using TimeZone getOffset() 341 // V 342 // local standard millis 343 // | 344 // | Using Calendar-specific algorithm 345 // V 346 // local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.) 347 348 // In general, a round trip from fields, through local and UTC millis, and 349 // back out to fields is made when necessary. This is implemented by the 350 // complete() method. Resolving a partial set of fields into a UTC millis 351 // value allows all remaining fields to be generated from that value. If 352 // the Calendar is lenient, the fields are also renormalized to standard 353 // ranges when they are regenerated. 354 355 /** 356 * Field number for <code>get</code> and <code>set</code> indicating the 357 * era, e.g., AD or BC in the Julian calendar. This is a calendar-specific 358 * value; see subclass documentation. 359 * 360 * @see GregorianCalendar#AD 361 * @see GregorianCalendar#BC 362 */ 363 enum int ERA = 0; 364 365 /** 366 * Field number for <code>get</code> and <code>set</code> indicating the 367 * year. This is a calendar-specific value; see subclass documentation. 368 */ 369 enum int YEAR = 1; 370 371 /** 372 * Field number for <code>get</code> and <code>set</code> indicating the 373 * month. This is a calendar-specific value. The first month of 374 * the year in the Gregorian and Julian calendars is 375 * <code>JANUARY</code> which is 0; the last depends on the number 376 * of months in a year. 377 * 378 * @see #JANUARY 379 * @see #FEBRUARY 380 * @see #MARCH 381 * @see #APRIL 382 * @see #MAY 383 * @see #JUNE 384 * @see #JULY 385 * @see #AUGUST 386 * @see #SEPTEMBER 387 * @see #OCTOBER 388 * @see #NOVEMBER 389 * @see #DECEMBER 390 * @see #UNDECIMBER 391 */ 392 enum int MONTH = 2; 393 394 /** 395 * Field number for <code>get</code> and <code>set</code> indicating the 396 * week number within the current year. The first week of the year, as 397 * defined by <code>getFirstDayOfWeek()</code> and 398 * <code>getMinimalDaysInFirstWeek()</code>, has value 1. Subclasses define 399 * the value of <code>WEEK_OF_YEAR</code> for days before the first week of 400 * the year. 401 * 402 * @see #getFirstDayOfWeek 403 * @see #getMinimalDaysInFirstWeek 404 */ 405 enum int WEEK_OF_YEAR = 3; 406 407 /** 408 * Field number for <code>get</code> and <code>set</code> indicating the 409 * week number within the current month. The first week of the month, as 410 * defined by <code>getFirstDayOfWeek()</code> and 411 * <code>getMinimalDaysInFirstWeek()</code>, has value 1. Subclasses define 412 * the value of <code>WEEK_OF_MONTH</code> for days before the first week of 413 * the month. 414 * 415 * @see #getFirstDayOfWeek 416 * @see #getMinimalDaysInFirstWeek 417 */ 418 enum int WEEK_OF_MONTH = 4; 419 420 /** 421 * Field number for <code>get</code> and <code>set</code> indicating the 422 * day of the month. This is a synonym for <code>DAY_OF_MONTH</code>. 423 * The first day of the month has value 1. 424 * 425 * @see #DAY_OF_MONTH 426 */ 427 enum int DATE = 5; 428 429 /** 430 * Field number for <code>get</code> and <code>set</code> indicating the 431 * day of the month. This is a synonym for <code>DATE</code>. 432 * The first day of the month has value 1. 433 * 434 * @see #DATE 435 */ 436 enum int DAY_OF_MONTH = 5; 437 438 /** 439 * Field number for <code>get</code> and <code>set</code> indicating the day 440 * number within the current year. The first day of the year has value 1. 441 */ 442 enum int DAY_OF_YEAR = 6; 443 444 /** 445 * Field number for <code>get</code> and <code>set</code> indicating the day 446 * of the week. This field takes values <code>SUNDAY</code>, 447 * <code>MONDAY</code>, <code>TUESDAY</code>, <code>WEDNESDAY</code>, 448 * <code>THURSDAY</code>, <code>FRIDAY</code>, and <code>SATURDAY</code>. 449 * 450 * @see #SUNDAY 451 * @see #MONDAY 452 * @see #TUESDAY 453 * @see #WEDNESDAY 454 * @see #THURSDAY 455 * @see #FRIDAY 456 * @see #SATURDAY 457 */ 458 enum int DAY_OF_WEEK = 7; 459 460 /** 461 * Field number for <code>get</code> and <code>set</code> indicating the 462 * ordinal number of the day of the week within the current month. Together 463 * with the <code>DAY_OF_WEEK</code> field, this uniquely specifies a day 464 * within a month. Unlike <code>WEEK_OF_MONTH</code> and 465 * <code>WEEK_OF_YEAR</code>, this field's value does <em>not</em> depend on 466 * <code>getFirstDayOfWeek()</code> or 467 * <code>getMinimalDaysInFirstWeek()</code>. <code>DAY_OF_MONTH 1</code> 468 * through <code>7</code> always correspond to <code>DAY_OF_WEEK_IN_MONTH 469 * 1</code>; <code>8</code> through <code>14</code> correspond to 470 * <code>DAY_OF_WEEK_IN_MONTH 2</code>, and so on. 471 * <code>DAY_OF_WEEK_IN_MONTH 0</code> indicates the week before 472 * <code>DAY_OF_WEEK_IN_MONTH 1</code>. Negative values count back from the 473 * end of the month, so the last Sunday of a month is specified as 474 * <code>DAY_OF_WEEK = SUNDAY, DAY_OF_WEEK_IN_MONTH = -1</code>. Because 475 * negative values count backward they will usually be aligned differently 476 * within the month than positive values. For example, if a month has 31 477 * days, <code>DAY_OF_WEEK_IN_MONTH -1</code> will overlap 478 * <code>DAY_OF_WEEK_IN_MONTH 5</code> and the end of <code>4</code>. 479 * 480 * @see #DAY_OF_WEEK 481 * @see #WEEK_OF_MONTH 482 */ 483 enum int DAY_OF_WEEK_IN_MONTH = 8; 484 485 /** 486 * Field number for <code>get</code> and <code>set</code> indicating 487 * whether the <code>HOUR</code> is before or after noon. 488 * E.g., at 10:04:15.250 PM the <code>AM_PM</code> is <code>PM</code>. 489 * 490 * @see #AM 491 * @see #PM 492 * @see #HOUR 493 */ 494 enum int AM_PM = 9; 495 496 /** 497 * Field number for <code>get</code> and <code>set</code> indicating the 498 * hour of the morning or afternoon. <code>HOUR</code> is used for the 499 * 12-hour clock (0 - 11). Noon and midnight are represented by 0, not by 12. 500 * E.g., at 10:04:15.250 PM the <code>HOUR</code> is 10. 501 * 502 * @see #AM_PM 503 * @see #HOUR_OF_DAY 504 */ 505 enum int HOUR = 10; 506 507 /** 508 * Field number for <code>get</code> and <code>set</code> indicating the 509 * hour of the day. <code>HOUR_OF_DAY</code> is used for the 24-hour clock. 510 * E.g., at 10:04:15.250 PM the <code>HOUR_OF_DAY</code> is 22. 511 * 512 * @see #HOUR 513 */ 514 enum int HOUR_OF_DAY = 11; 515 516 /** 517 * Field number for <code>get</code> and <code>set</code> indicating the 518 * minute within the hour. 519 * E.g., at 10:04:15.250 PM the <code>MINUTE</code> is 4. 520 */ 521 enum int MINUTE = 12; 522 523 /** 524 * Field number for <code>get</code> and <code>set</code> indicating the 525 * second within the minute. 526 * E.g., at 10:04:15.250 PM the <code>SECOND</code> is 15. 527 */ 528 enum int SECOND = 13; 529 530 /** 531 * Field number for <code>get</code> and <code>set</code> indicating the 532 * millisecond within the second. 533 * E.g., at 10:04:15.250 PM the <code>MILLISECOND</code> is 250. 534 */ 535 enum int MILLISECOND = 14; 536 537 /** 538 * Field number for <code>get</code> and <code>set</code> 539 * indicating the raw offset from GMT in milliseconds. 540 * <p> 541 * This field reflects the correct GMT offset value of the time 542 * zone of this <code>Calendar</code> if the 543 * <code>TimeZone</code> implementation subclass supports 544 * historical GMT offset changes. 545 */ 546 enum int ZONE_OFFSET = 15; 547 548 /** 549 * Field number for <code>get</code> and <code>set</code> indicating the 550 * daylight saving offset in milliseconds. 551 * <p> 552 * This field reflects the correct daylight saving offset value of 553 * the time zone of this <code>Calendar</code> if the 554 * <code>TimeZone</code> implementation subclass supports 555 * historical Daylight Saving Time schedule changes. 556 */ 557 enum int DST_OFFSET = 16; 558 559 /** 560 * The number of distinct fields recognized by <code>get</code> and <code>set</code>. 561 * Field numbers range from <code>0..FIELD_COUNT-1</code>. 562 */ 563 enum int FIELD_COUNT = 17; 564 565 /** 566 * Value of the {@link #DAY_OF_WEEK} field indicating 567 * Sunday. 568 */ 569 enum int SUNDAY = 1; 570 571 /** 572 * Value of the {@link #DAY_OF_WEEK} field indicating 573 * Monday. 574 */ 575 enum int MONDAY = 2; 576 577 /** 578 * Value of the {@link #DAY_OF_WEEK} field indicating 579 * Tuesday. 580 */ 581 enum int TUESDAY = 3; 582 583 /** 584 * Value of the {@link #DAY_OF_WEEK} field indicating 585 * Wednesday. 586 */ 587 enum int WEDNESDAY = 4; 588 589 /** 590 * Value of the {@link #DAY_OF_WEEK} field indicating 591 * Thursday. 592 */ 593 enum int THURSDAY = 5; 594 595 /** 596 * Value of the {@link #DAY_OF_WEEK} field indicating 597 * Friday. 598 */ 599 enum int FRIDAY = 6; 600 601 /** 602 * Value of the {@link #DAY_OF_WEEK} field indicating 603 * Saturday. 604 */ 605 enum int SATURDAY = 7; 606 607 /** 608 * Value of the {@link #MONTH} field indicating the 609 * first month of the year in the Gregorian and Julian calendars. 610 */ 611 enum int JANUARY = 0; 612 613 /** 614 * Value of the {@link #MONTH} field indicating the 615 * second month of the year in the Gregorian and Julian calendars. 616 */ 617 enum int FEBRUARY = 1; 618 619 /** 620 * Value of the {@link #MONTH} field indicating the 621 * third month of the year in the Gregorian and Julian calendars. 622 */ 623 enum int MARCH = 2; 624 625 /** 626 * Value of the {@link #MONTH} field indicating the 627 * fourth month of the year in the Gregorian and Julian calendars. 628 */ 629 enum int APRIL = 3; 630 631 /** 632 * Value of the {@link #MONTH} field indicating the 633 * fifth month of the year in the Gregorian and Julian calendars. 634 */ 635 enum int MAY = 4; 636 637 /** 638 * Value of the {@link #MONTH} field indicating the 639 * sixth month of the year in the Gregorian and Julian calendars. 640 */ 641 enum int JUNE = 5; 642 643 /** 644 * Value of the {@link #MONTH} field indicating the 645 * seventh month of the year in the Gregorian and Julian calendars. 646 */ 647 enum int JULY = 6; 648 649 /** 650 * Value of the {@link #MONTH} field indicating the 651 * eighth month of the year in the Gregorian and Julian calendars. 652 */ 653 enum int AUGUST = 7; 654 655 /** 656 * Value of the {@link #MONTH} field indicating the 657 * ninth month of the year in the Gregorian and Julian calendars. 658 */ 659 enum int SEPTEMBER = 8; 660 661 /** 662 * Value of the {@link #MONTH} field indicating the 663 * tenth month of the year in the Gregorian and Julian calendars. 664 */ 665 enum int OCTOBER = 9; 666 667 /** 668 * Value of the {@link #MONTH} field indicating the 669 * eleventh month of the year in the Gregorian and Julian calendars. 670 */ 671 enum int NOVEMBER = 10; 672 673 /** 674 * Value of the {@link #MONTH} field indicating the 675 * twelfth month of the year in the Gregorian and Julian calendars. 676 */ 677 enum int DECEMBER = 11; 678 679 /** 680 * Value of the {@link #MONTH} field indicating the 681 * thirteenth month of the year. Although <code>GregorianCalendar</code> 682 * does not use this value, lunar calendars do. 683 */ 684 enum int UNDECIMBER = 12; 685 686 /** 687 * Value of the {@link #AM_PM} field indicating the 688 * period of the day from midnight to just before noon. 689 */ 690 enum int AM = 0; 691 692 /** 693 * Value of the {@link #AM_PM} field indicating the 694 * period of the day from noon to just before midnight. 695 */ 696 enum int PM = 1; 697 698 /** 699 * A style specifier for {@link #getDisplayNames(int, int, Locale) 700 * getDisplayNames} indicating names in all styles, such as 701 * "January" and "Jan". 702 * 703 * @see #SHORT_FORMAT 704 * @see #LONG_FORMAT 705 * @see #SHORT_STANDALONE 706 * @see #LONG_STANDALONE 707 * @see #SHORT 708 * @see #LONG 709 * @since 1.6 710 */ 711 enum int ALL_STYLES = 0; 712 713 enum int STANDALONE_MASK = 0x8000; 714 715 /** 716 * A style specifier for {@link #getDisplayName(int, int, Locale) 717 * getDisplayName} and {@link #getDisplayNames(int, int, Locale) 718 * getDisplayNames} equivalent to {@link #SHORT_FORMAT}. 719 * 720 * @see #SHORT_STANDALONE 721 * @see #LONG 722 * @since 1.6 723 */ 724 enum int SHORT = 1; 725 726 /** 727 * A style specifier for {@link #getDisplayName(int, int, Locale) 728 * getDisplayName} and {@link #getDisplayNames(int, int, Locale) 729 * getDisplayNames} equivalent to {@link #LONG_FORMAT}. 730 * 731 * @see #LONG_STANDALONE 732 * @see #SHORT 733 * @since 1.6 734 */ 735 enum int LONG = 2; 736 737 /** 738 * A style specifier for {@link #getDisplayName(int, int, Locale) 739 * getDisplayName} and {@link #getDisplayNames(int, int, Locale) 740 * getDisplayNames} indicating a narrow name used for format. Narrow names 741 * are typically single character strings, such as "M" for Monday. 742 * 743 * @see #NARROW_STANDALONE 744 * @see #SHORT_FORMAT 745 * @see #LONG_FORMAT 746 * @since 1.8 747 */ 748 enum int NARROW_FORMAT = 4; 749 750 /** 751 * A style specifier for {@link #getDisplayName(int, int, Locale) 752 * getDisplayName} and {@link #getDisplayNames(int, int, Locale) 753 * getDisplayNames} indicating a narrow name independently. Narrow names 754 * are typically single character strings, such as "M" for Monday. 755 * 756 * @see #NARROW_FORMAT 757 * @see #SHORT_STANDALONE 758 * @see #LONG_STANDALONE 759 * @since 1.8 760 */ 761 enum int NARROW_STANDALONE = NARROW_FORMAT | STANDALONE_MASK; 762 763 /** 764 * A style specifier for {@link #getDisplayName(int, int, Locale) 765 * getDisplayName} and {@link #getDisplayNames(int, int, Locale) 766 * getDisplayNames} indicating a short name used for format. 767 * 768 * @see #SHORT_STANDALONE 769 * @see #LONG_FORMAT 770 * @see #LONG_STANDALONE 771 * @since 1.8 772 */ 773 enum int SHORT_FORMAT = 1; 774 775 /** 776 * A style specifier for {@link #getDisplayName(int, int, Locale) 777 * getDisplayName} and {@link #getDisplayNames(int, int, Locale) 778 * getDisplayNames} indicating a long name used for format. 779 * 780 * @see #LONG_STANDALONE 781 * @see #SHORT_FORMAT 782 * @see #SHORT_STANDALONE 783 * @since 1.8 784 */ 785 enum int LONG_FORMAT = 2; 786 787 /** 788 * A style specifier for {@link #getDisplayName(int, int, Locale) 789 * getDisplayName} and {@link #getDisplayNames(int, int, Locale) 790 * getDisplayNames} indicating a short name used independently, 791 * such as a month abbreviation as calendar headers. 792 * 793 * @see #SHORT_FORMAT 794 * @see #LONG_FORMAT 795 * @see #LONG_STANDALONE 796 * @since 1.8 797 */ 798 enum int SHORT_STANDALONE = SHORT | STANDALONE_MASK; 799 800 /** 801 * A style specifier for {@link #getDisplayName(int, int, Locale) 802 * getDisplayName} and {@link #getDisplayNames(int, int, Locale) 803 * getDisplayNames} indicating a long name used independently, 804 * such as a month name as calendar headers. 805 * 806 * @see #LONG_FORMAT 807 * @see #SHORT_FORMAT 808 * @see #SHORT_STANDALONE 809 * @since 1.8 810 */ 811 enum int LONG_STANDALONE = LONG | STANDALONE_MASK; 812 813 // Internal notes: 814 // Calendar contains two kinds of time representations: current "time" in 815 // milliseconds, and a set of calendar "fields" representing the current time. 816 // The two representations are usually in sync, but can get out of sync 817 // as follows. 818 // 1. Initially, no fields are set, and the time is invalid. 819 // 2. If the time is set, all fields are computed and in sync. 820 // 3. If a single field is set, the time is invalid. 821 // Recomputation of the time and fields happens when the object needs 822 // to return a result to the user, or use a result for a computation. 823 824 /** 825 * The calendar field values for the currently set time for this calendar. 826 * This is an array of <code>FIELD_COUNT</code> integers, with index values 827 * <code>ERA</code> through <code>DST_OFFSET</code>. 828 * @serial 829 */ 830 //@SuppressWarnings("ProtectedField") 831 protected int[] fields; 832 833 /** 834 * The flags which tell if a specified calendar field for the calendar is set. 835 * A new object has no fields set. After the first call to a method 836 * which generates the fields, they all remain set after that. 837 * This is an array of <code>FIELD_COUNT</code> bools, with index values 838 * <code>ERA</code> through <code>DST_OFFSET</code>. 839 * @serial 840 */ 841 //@SuppressWarnings("ProtectedField") 842 protected bool[] isSet; 843 844 /** 845 * Pseudo-time-stamps which specify when each field was set. There 846 * are two special values, UNSET and COMPUTED. Values from 847 * MINIMUM_USER_SET to Integer.MAX_VALUE are legal user set values. 848 */ 849 private int[] stamp; 850 851 /** 852 * The currently set time for this calendar, expressed in milliseconds after 853 * January 1, 1970, 0:00:00 GMT. 854 * @see #isTimeSet 855 * @serial 856 */ 857 //@SuppressWarnings("ProtectedField") 858 protected long time; 859 860 /** 861 * True if then the value of <code>time</code> is valid. 862 * The time is made invalid by a change to an item of <code>field[]</code>. 863 * @see #time 864 * @serial 865 */ 866 //@SuppressWarnings("ProtectedField") 867 protected bool isTimeSet; 868 869 /** 870 * True if <code>fields[]</code> are in sync with the currently set time. 871 * If false, then the next attempt to get the value of a field will 872 * force a recomputation of all fields from the current value of 873 * <code>time</code>. 874 * @serial 875 */ 876 //@SuppressWarnings("ProtectedField") 877 protected bool areFieldsSet; 878 879 /** 880 * True if all fields have been set. 881 * @serial 882 */ 883 bool areAllFieldsSet; 884 885 /** 886 * <code>True</code> if this calendar allows out-of-range field values during computation 887 * of <code>time</code> from <code>fields[]</code>. 888 * @see #setLenient 889 * @see #isLenient 890 * @serial 891 */ 892 private bool lenient = true; 893 894 /** 895 * The <code>TimeZone</code> used by this calendar. <code>Calendar</code> 896 * uses the time zone data to translate between locale and GMT time. 897 * @serial 898 */ 899 private TimeZone zone; 900 901 /** 902 * <code>True</code> if zone references to a shared TimeZone object. 903 */ 904 private bool sharedZone = false; 905 906 /** 907 * The first day of the week, with possible values <code>SUNDAY</code>, 908 * <code>MONDAY</code>, etc. This is a locale-dependent value. 909 * @serial 910 */ 911 private int firstDayOfWeek; 912 913 /** 914 * The number of days required for the first week in a month or year, 915 * with possible values from 1 to 7. This is a locale-dependent value. 916 * @serial 917 */ 918 private int minimalDaysInFirstWeek; 919 920 /** 921 * Cache to hold the firstDayOfWeek and minimalDaysInFirstWeek 922 * of a Locale. 923 */ 924 // private enum ConcurrentMap!(Locale, int[]) cachedLocaleData 925 // = new ConcurrentHashMap(3); 926 927 // __gshared Map!(Locale, int[]) cachedLocaleData; 928 // Special values of stamp[] 929 /** 930 * The corresponding fields[] has no value. 931 */ 932 private enum int UNSET = 0; 933 934 /** 935 * The value of the corresponding fields[] has been calculated internally. 936 */ 937 private enum int COMPUTED = 1; 938 939 /** 940 * The value of the corresponding fields[] has been set externally. Stamp 941 * values which are greater than 1 represents the (pseudo) time when the 942 * corresponding fields[] value was set. 943 */ 944 private enum int MINIMUM_USER_STAMP = 2; 945 946 /** 947 * The mask value that represents all of the fields. 948 */ 949 enum int ALL_FIELDS = (1 << FIELD_COUNT) - 1; 950 951 /** 952 * The next available value for <code>stamp[]</code>, an internal array. 953 * This actually should not be written out to the stream, and will probably 954 * be removed from the stream in the near future. In the meantime, 955 * a value of <code>MINIMUM_USER_STAMP</code> should be used. 956 * @serial 957 */ 958 private int nextStamp = MINIMUM_USER_STAMP; 959 960 // the internal serial version which says which version was written 961 // - 0 (default) for version up to JDK 1.1.5 962 // - 1 for version from JDK 1.1.6, which writes a correct 'time' value 963 // as well as compatible values for other fields. This is a 964 // transitional format. 965 // - 2 (not implemented yet) a future version, in which fields[], 966 // areFieldsSet, and isTimeSet become , and isSet[] is 967 // removed. In JDK 1.1.6 we write a format compatible with version 2. 968 enum int currentSerialVersion = 1; 969 970 /** 971 * The version of the serialized data on the stream. Possible values: 972 * <dl> 973 * <dt><b>0</b> or not present on stream</dt> 974 * <dd> 975 * JDK 1.1.5 or earlier. 976 * </dd> 977 * <dt><b>1</b></dt> 978 * <dd> 979 * JDK 1.1.6 or later. Writes a correct 'time' value 980 * as well as compatible values for other fields. This is a 981 * transitional format. 982 * </dd> 983 * </dl> 984 * When streaming out this class, the most recent format 985 * and the highest allowable <code>serialVersionOnStream</code> 986 * is written. 987 * @serial 988 * @since 1.1.6 989 */ 990 private int serialVersionOnStream = currentSerialVersion; 991 992 // Mask values for calendar fields 993 //@SuppressWarnings("PointlessBitwiseExpression") 994 enum int ERA_MASK = (1 << ERA); 995 enum int YEAR_MASK = (1 << YEAR); 996 enum int MONTH_MASK = (1 << MONTH); 997 enum int WEEK_OF_YEAR_MASK = (1 << WEEK_OF_YEAR); 998 enum int WEEK_OF_MONTH_MASK = (1 << WEEK_OF_MONTH); 999 enum int DAY_OF_MONTH_MASK = (1 << DAY_OF_MONTH); 1000 enum int DATE_MASK = DAY_OF_MONTH_MASK; 1001 enum int DAY_OF_YEAR_MASK = (1 << DAY_OF_YEAR); 1002 enum int DAY_OF_WEEK_MASK = (1 << DAY_OF_WEEK); 1003 enum int DAY_OF_WEEK_IN_MONTH_MASK = (1 << DAY_OF_WEEK_IN_MONTH); 1004 enum int AM_PM_MASK = (1 << AM_PM); 1005 enum int HOUR_MASK = (1 << HOUR); 1006 enum int HOUR_OF_DAY_MASK = (1 << HOUR_OF_DAY); 1007 enum int MINUTE_MASK = (1 << MINUTE); 1008 enum int SECOND_MASK = (1 << SECOND); 1009 enum int MILLISECOND_MASK = (1 << MILLISECOND); 1010 enum int ZONE_OFFSET_MASK = (1 << ZONE_OFFSET); 1011 enum int DST_OFFSET_MASK = (1 << DST_OFFSET); 1012 1013 // shared static this() 1014 // { 1015 // cachedLocaleData = new HashMap!(Locale, int[])(3); 1016 mixin(MakeGlobalVar!(Map!(Locale, int[]))("cachedLocaleData",`new HashMap!(Locale, int[])(3)`)); 1017 // } 1018 1019 /** 1020 * {@code Calendar.Builder} is used for creating a {@code Calendar} from 1021 * various date-time parameters. 1022 * 1023 * <p>There are two ways to set a {@code Calendar} to a date-time value. One 1024 * is to set the instant parameter to a millisecond offset from the <a 1025 * href="Calendar.html#Epoch">Epoch</a>. The other is to set individual 1026 * field parameters, such as {@link Calendar#YEAR YEAR}, to their desired 1027 * values. These two ways can't be mixed. Trying to set both the instant and 1028 * individual fields will cause an {@link IllegalStateException} to be 1029 * thrown. However, it is permitted to override previous values of the 1030 * instant or field parameters. 1031 * 1032 * <p>If no enough field parameters are given for determining date and/or 1033 * time, calendar specific default values are used when building a 1034 * {@code Calendar}. For example, if the {@link Calendar#YEAR YEAR} value 1035 * isn't given for the Gregorian calendar, 1970 will be used. If there are 1036 * any conflicts among field parameters, the <a 1037 * href="Calendar.html#resolution"> resolution rules</a> are applied. 1038 * Therefore, the order of field setting matters. 1039 * 1040 * <p>In addition to the date-time parameters, 1041 * the {@linkplain #setLocale(Locale) locale}, 1042 * {@linkplain #setTimeZone(TimeZone) time zone}, 1043 * {@linkplain #setWeekDefinition(int, int) week definition}, and 1044 * {@linkplain #setLenient(bool) leniency mode} parameters can be set. 1045 * 1046 * <p><b>Examples</b> 1047 * <p>The following are sample usages. Sample code assumes that the 1048 * {@code Calendar} constants are statically imported. 1049 * 1050 * <p>The following code produces a {@code Calendar} with date 2012-12-31 1051 * (Gregorian) because Monday is the first day of a week with the <a 1052 * href="GregorianCalendar.html#iso8601_compatible_setting"> ISO 8601 1053 * compatible week parameters</a>. 1054 * <pre> 1055 * Calendar cal = new Calendar.Builder().setCalendarType("iso8601") 1056 * .setWeekDate(2013, 1, MONDAY).build();</pre> 1057 * <p>The following code produces a Japanese {@code Calendar} with date 1058 * 1989-01-08 (Gregorian), assuming that the default {@link Calendar#ERA ERA} 1059 * is <em>Heisei</em> that started on that day. 1060 * <pre> 1061 * Calendar cal = new Calendar.Builder().setCalendarType("japanese") 1062 * .setFields(YEAR, 1, DAY_OF_YEAR, 1).build();</pre> 1063 * 1064 * @since 1.8 1065 * @see Calendar#getInstance(TimeZone, Locale) 1066 * @see Calendar#fields 1067 */ 1068 // static class Builder { 1069 // private enum int NFIELDS = FIELD_COUNT + 1; // +1 for WEEK_YEAR 1070 // private enum int WEEK_YEAR = FIELD_COUNT; 1071 1072 // private long instant; 1073 // // Calendar.stamp[] (lower half) and Calendar.fields[] (upper half) combined 1074 // private int[] fields; 1075 // // Pseudo timestamp starting from MINIMUM_USER_STAMP. 1076 // // (COMPUTED is used to indicate that the instant has been set.) 1077 // private int nextStamp; 1078 // // maxFieldIndex keeps the max index of fields which have been set. 1079 // // (WEEK_YEAR is never included.) 1080 // private int maxFieldIndex; 1081 // private String type; 1082 // private TimeZone zone; 1083 // private bool lenient = true; 1084 // private Locale locale; 1085 // private int firstDayOfWeek, minimalDaysInFirstWeek; 1086 1087 // /** 1088 // * Constructs a {@code Calendar.Builder}. 1089 // */ 1090 // this() { 1091 // } 1092 1093 // /** 1094 // * Sets the instant parameter to the given {@code instant} value that is 1095 // * a millisecond offset from <a href="Calendar.html#Epoch">the 1096 // * Epoch</a>. 1097 // * 1098 // * @param instant a millisecond offset from the Epoch 1099 // * @return this {@code Calendar.Builder} 1100 // * @throws IllegalStateException if any of the field parameters have 1101 // * already been set 1102 // * @see Calendar#setTime(LocalDateTime) 1103 // * @see Calendar#setTimeInMillis(long) 1104 // * @see Calendar#time 1105 // */ 1106 // Builder setInstant(long instant) { 1107 // if (fields !is null) { 1108 // throw new IllegalStateException(); 1109 // } 1110 // this.instant = instant; 1111 // nextStamp = COMPUTED; 1112 // return this; 1113 // } 1114 1115 // /** 1116 // * Sets the instant parameter to the {@code instant} value given by a 1117 // * {@link LocalDateTime}. This method is equivalent to a call to 1118 // * {@link #setInstant(long) setInstant(instant.getTime())}. 1119 // * 1120 // * @param instant a {@code LocalDateTime} representing a millisecond offset from 1121 // * the Epoch 1122 // * @return this {@code Calendar.Builder} 1123 // * @throws NullPointerException if {@code instant} is {@code null} 1124 // * @throws IllegalStateException if any of the field parameters have 1125 // * already been set 1126 // * @see Calendar#setTime(LocalDateTime) 1127 // * @see Calendar#setTimeInMillis(long) 1128 // * @see Calendar#time 1129 // */ 1130 // Builder setInstant(LocalDateTime instant) { 1131 // return setInstant(instant.getTime()); // NPE if instant is null 1132 // } 1133 1134 // /** 1135 // * Sets the {@code field} parameter to the given {@code value}. 1136 // * {@code field} is an index to the {@link Calendar#fields}, such as 1137 // * {@link Calendar#DAY_OF_MONTH DAY_OF_MONTH}. Field value validation is 1138 // * not performed in this method. Any out of range values are either 1139 // * normalized in lenient mode or detected as an invalid value in 1140 // * non-lenient mode when building a {@code Calendar}. 1141 // * 1142 // * @param field an index to the {@code Calendar} fields 1143 // * @param value the field value 1144 // * @return this {@code Calendar.Builder} 1145 // * @throws IllegalArgumentException if {@code field} is invalid 1146 // * @throws IllegalStateException if the instant value has already been set, 1147 // * or if fields have been set too many 1148 // * (approximately {@link Integer#MAX_VALUE}) times. 1149 // * @see Calendar#set(int, int) 1150 // */ 1151 // Builder set(int field, int value) { 1152 // // Note: WEEK_YEAR can't be set with this method. 1153 // if (field < 0 || field >= FIELD_COUNT) { 1154 // throw new IllegalArgumentException("field is invalid"); 1155 // } 1156 // if (isInstantSet()) { 1157 // throw new IllegalStateException("instant has been set"); 1158 // } 1159 // allocateFields(); 1160 // internalSet(field, value); 1161 // return this; 1162 // } 1163 1164 // /** 1165 // * Sets field parameters to their values given by 1166 // * {@code fieldValuePairs} that are pairs of a field and its value. 1167 // * For example, 1168 // * <pre> 1169 // * setFields(Calendar.YEAR, 2013, 1170 // * Calendar.MONTH, Calendar.DECEMBER, 1171 // * Calendar.DAY_OF_MONTH, 23);</pre> 1172 // * is equivalent to the sequence of the following 1173 // * {@link #set(int, int) set} calls: 1174 // * <pre> 1175 // * set(Calendar.YEAR, 2013) 1176 // * .set(Calendar.MONTH, Calendar.DECEMBER) 1177 // * .set(Calendar.DAY_OF_MONTH, 23);</pre> 1178 // * 1179 // * @param fieldValuePairs field-value pairs 1180 // * @return this {@code Calendar.Builder} 1181 // * @throws NullPointerException if {@code fieldValuePairs} is {@code null} 1182 // * @throws IllegalArgumentException if any of fields are invalid, 1183 // * or if {@code fieldValuePairs.length} is an odd number. 1184 // * @throws IllegalStateException if the instant value has been set, 1185 // * or if fields have been set too many (approximately 1186 // * {@link Integer#MAX_VALUE}) times. 1187 // */ 1188 // Builder setFields(int... fieldValuePairs) { 1189 // int len = fieldValuePairs.length; 1190 // if ((len % 2) != 0) { 1191 // throw new IllegalArgumentException(); 1192 // } 1193 // if (isInstantSet()) { 1194 // throw new IllegalStateException("instant has been set"); 1195 // } 1196 // if ((nextStamp + len / 2) < 0) { 1197 // throw new IllegalStateException("stamp counter overflow"); 1198 // } 1199 // allocateFields(); 1200 // for (int i = 0; i < len; ) { 1201 // int field = fieldValuePairs[i++]; 1202 // // Note: WEEK_YEAR can't be set with this method. 1203 // if (field < 0 || field >= FIELD_COUNT) { 1204 // throw new IllegalArgumentException("field is invalid"); 1205 // } 1206 // internalSet(field, fieldValuePairs[i++]); 1207 // } 1208 // return this; 1209 // } 1210 1211 // /** 1212 // * Sets the date field parameters to the values given by {@code year}, 1213 // * {@code month}, and {@code dayOfMonth}. This method is equivalent to 1214 // * a call to: 1215 // * <pre> 1216 // * setFields(Calendar.YEAR, year, 1217 // * Calendar.MONTH, month, 1218 // * Calendar.DAY_OF_MONTH, dayOfMonth);</pre> 1219 // * 1220 // * @param year the {@link Calendar#YEAR YEAR} value 1221 // * @param month the {@link Calendar#MONTH MONTH} value 1222 // * (the month numbering is <em>0-based</em>). 1223 // * @param dayOfMonth the {@link Calendar#DAY_OF_MONTH DAY_OF_MONTH} value 1224 // * @return this {@code Calendar.Builder} 1225 // */ 1226 // Builder setDate(int year, int month, int dayOfMonth) { 1227 // return setFields(YEAR, year, MONTH, month, DAY_OF_MONTH, dayOfMonth); 1228 // } 1229 1230 // /** 1231 // * Sets the time of day field parameters to the values given by 1232 // * {@code hourOfDay}, {@code minute}, and {@code second}. This method is 1233 // * equivalent to a call to: 1234 // * <pre> 1235 // * setTimeOfDay(hourOfDay, minute, second, 0);</pre> 1236 // * 1237 // * @param hourOfDay the {@link Calendar#HOUR_OF_DAY HOUR_OF_DAY} value 1238 // * (24-hour clock) 1239 // * @param minute the {@link Calendar#MINUTE MINUTE} value 1240 // * @param second the {@link Calendar#SECOND SECOND} value 1241 // * @return this {@code Calendar.Builder} 1242 // */ 1243 // Builder setTimeOfDay(int hourOfDay, int minute, int second) { 1244 // return setTimeOfDay(hourOfDay, minute, second, 0); 1245 // } 1246 1247 // /** 1248 // * Sets the time of day field parameters to the values given by 1249 // * {@code hourOfDay}, {@code minute}, {@code second}, and 1250 // * {@code millis}. This method is equivalent to a call to: 1251 // * <pre> 1252 // * setFields(Calendar.HOUR_OF_DAY, hourOfDay, 1253 // * Calendar.MINUTE, minute, 1254 // * Calendar.SECOND, second, 1255 // * Calendar.MILLISECOND, millis);</pre> 1256 // * 1257 // * @param hourOfDay the {@link Calendar#HOUR_OF_DAY HOUR_OF_DAY} value 1258 // * (24-hour clock) 1259 // * @param minute the {@link Calendar#MINUTE MINUTE} value 1260 // * @param second the {@link Calendar#SECOND SECOND} value 1261 // * @param millis the {@link Calendar#MILLISECOND MILLISECOND} value 1262 // * @return this {@code Calendar.Builder} 1263 // */ 1264 // Builder setTimeOfDay(int hourOfDay, int minute, int second, int millis) { 1265 // return setFields(HOUR_OF_DAY, hourOfDay, MINUTE, minute, 1266 // SECOND, second, MILLISECOND, millis); 1267 // } 1268 1269 // /** 1270 // * Sets the week-based date parameters to the values with the given 1271 // * date specifiers - week year, week of year, and day of week. 1272 // * 1273 // * <p>If the specified calendar doesn't support week dates, the 1274 // * {@link #build() build} method will throw an {@link IllegalArgumentException}. 1275 // * 1276 // * @param weekYear the week year 1277 // * @param weekOfYear the week number based on {@code weekYear} 1278 // * @param dayOfWeek the day of week value: one of the constants 1279 // * for the {@link Calendar#DAY_OF_WEEK DAY_OF_WEEK} field: 1280 // * {@link Calendar#SUNDAY SUNDAY}, ..., {@link Calendar#SATURDAY SATURDAY}. 1281 // * @return this {@code Calendar.Builder} 1282 // * @see Calendar#setWeekDate(int, int, int) 1283 // * @see Calendar#isWeekDateSupported() 1284 // */ 1285 // Builder setWeekDate(int weekYear, int weekOfYear, int dayOfWeek) { 1286 // allocateFields(); 1287 // internalSet(WEEK_YEAR, weekYear); 1288 // internalSet(WEEK_OF_YEAR, weekOfYear); 1289 // internalSet(DAY_OF_WEEK, dayOfWeek); 1290 // return this; 1291 // } 1292 1293 // /** 1294 // * Sets the time zone parameter to the given {@code zone}. If no time 1295 // * zone parameter is given to this {@code Calendar.Builder}, the 1296 // * {@linkplain TimeZone#getDefault() default 1297 // * <code>TimeZone</code>} will be used in the {@link #build() build} 1298 // * method. 1299 // * 1300 // * @param zone the {@link TimeZone} 1301 // * @return this {@code Calendar.Builder} 1302 // * @throws NullPointerException if {@code zone} is {@code null} 1303 // * @see Calendar#setTimeZone(TimeZone) 1304 // */ 1305 // Builder setTimeZone(TimeZone zone) { 1306 // if (zone is null) { 1307 // throw new NullPointerException(); 1308 // } 1309 // this.zone = zone; 1310 // return this; 1311 // } 1312 1313 // /** 1314 // * Sets the lenient mode parameter to the value given by {@code lenient}. 1315 // * If no lenient parameter is given to this {@code Calendar.Builder}, 1316 // * lenient mode will be used in the {@link #build() build} method. 1317 // * 1318 // * @param lenient {@code true} for lenient mode; 1319 // * {@code false} for non-lenient mode 1320 // * @return this {@code Calendar.Builder} 1321 // * @see Calendar#setLenient(bool) 1322 // */ 1323 // Builder setLenient(bool lenient) { 1324 // this.lenient = lenient; 1325 // return this; 1326 // } 1327 1328 // /** 1329 // * Sets the calendar type parameter to the given {@code type}. The 1330 // * calendar type given by this method has precedence over any explicit 1331 // * or implicit calendar type given by the 1332 // * {@linkplain #setLocale(Locale) locale}. 1333 // * 1334 // * <p>In addition to the available calendar types returned by the 1335 // * {@link Calendar#getAvailableCalendarTypes() Calendar.getAvailableCalendarTypes} 1336 // * method, {@code "gregorian"} and {@code "iso8601"} as aliases of 1337 // * {@code "gregory"} can be used with this method. 1338 // * 1339 // * @param type the calendar type 1340 // * @return this {@code Calendar.Builder} 1341 // * @throws NullPointerException if {@code type} is {@code null} 1342 // * @throws IllegalArgumentException if {@code type} is unknown 1343 // * @throws IllegalStateException if another calendar type has already been set 1344 // * @see Calendar#getCalendarType() 1345 // * @see Calendar#getAvailableCalendarTypes() 1346 // */ 1347 // Builder setCalendarType(String type) { 1348 // if (type.equals("gregorian")) { // NPE if type is null 1349 // type = "gregory"; 1350 // } 1351 // if (!Calendar.getAvailableCalendarTypes().contains(type) 1352 // && !type.equals("iso8601")) { 1353 // throw new IllegalArgumentException("unknown calendar type: " ~ type); 1354 // } 1355 // if (this.type is null) { 1356 // this.type = type; 1357 // } else { 1358 // if (!this.type.equals(type)) { 1359 // throw new IllegalStateException("calendar type override"); 1360 // } 1361 // } 1362 // return this; 1363 // } 1364 1365 // /** 1366 // * Sets the locale parameter to the given {@code locale}. If no locale 1367 // * is given to this {@code Calendar.Builder}, the {@linkplain 1368 // * Locale#getDefault(LocaleCategory) default <code>Locale</code>} 1369 // * for {@link LocaleCategory#FORMAT} will be used. 1370 // * 1371 // * <p>If no calendar type is explicitly given by a call to the 1372 // * {@link #setCalendarType(String) setCalendarType} method, 1373 // * the {@code Locale} value is used to determine what type of 1374 // * {@code Calendar} to be built. 1375 // * 1376 // * <p>If no week definition parameters are explicitly given by a call to 1377 // * the {@link #setWeekDefinition(int,int) setWeekDefinition} method, the 1378 // * {@code Locale}'s default values are used. 1379 // * 1380 // * @param locale the {@link Locale} 1381 // * @throws NullPointerException if {@code locale} is {@code null} 1382 // * @return this {@code Calendar.Builder} 1383 // * @see Calendar#getInstance(Locale) 1384 // */ 1385 // Builder setLocale(Locale locale) { 1386 // if (locale is null) { 1387 // throw new NullPointerException(); 1388 // } 1389 // this.locale = locale; 1390 // return this; 1391 // } 1392 1393 // /** 1394 // * Sets the week definition parameters to the values given by 1395 // * {@code firstDayOfWeek} and {@code minimalDaysInFirstWeek} that are 1396 // * used to determine the <a href="Calendar.html#first_week">first 1397 // * week</a> of a year. The parameters given by this method have 1398 // * precedence over the default values given by the 1399 // * {@linkplain #setLocale(Locale) locale}. 1400 // * 1401 // * @param firstDayOfWeek the first day of a week; one of 1402 // * {@link Calendar#SUNDAY} to {@link Calendar#SATURDAY} 1403 // * @param minimalDaysInFirstWeek the minimal number of days in the first 1404 // * week (1..7) 1405 // * @return this {@code Calendar.Builder} 1406 // * @throws IllegalArgumentException if {@code firstDayOfWeek} or 1407 // * {@code minimalDaysInFirstWeek} is invalid 1408 // * @see Calendar#getFirstDayOfWeek() 1409 // * @see Calendar#getMinimalDaysInFirstWeek() 1410 // */ 1411 // Builder setWeekDefinition(int firstDayOfWeek, int minimalDaysInFirstWeek) { 1412 // if (!isValidWeekParameter(firstDayOfWeek) 1413 // || !isValidWeekParameter(minimalDaysInFirstWeek)) { 1414 // throw new IllegalArgumentException(); 1415 // } 1416 // this.firstDayOfWeek = firstDayOfWeek; 1417 // this.minimalDaysInFirstWeek = minimalDaysInFirstWeek; 1418 // return this; 1419 // } 1420 1421 // /** 1422 // * Returns a {@code Calendar} built from the parameters set by the 1423 // * setter methods. The calendar type given by the {@link #setCalendarType(String) 1424 // * setCalendarType} method or the {@linkplain #setLocale(Locale) locale} is 1425 // * used to determine what {@code Calendar} to be created. If no explicit 1426 // * calendar type is given, the locale's default calendar is created. 1427 // * 1428 // * <p>If the calendar type is {@code "iso8601"}, the 1429 // * {@linkplain GregorianCalendar#setGregorianChange(LocalDateTime) Gregorian change date} 1430 // * of a {@link GregorianCalendar} is set to {@code LocalDateTime(Long.MIN_VALUE)} 1431 // * to be the <em>proleptic</em> Gregorian calendar. Its week definition 1432 // * parameters are also set to be <a 1433 // * href="GregorianCalendar.html#iso8601_compatible_setting">compatible 1434 // * with the ISO 8601 standard</a>. Note that the 1435 // * {@link GregorianCalendar#getCalendarType() getCalendarType} method of 1436 // * a {@code GregorianCalendar} created with {@code "iso8601"} returns 1437 // * {@code "gregory"}. 1438 // * 1439 // * <p>The default values are used for locale and time zone if these 1440 // * parameters haven't been given explicitly. 1441 // * <p> 1442 // * If the locale contains the time zone with "tz" 1443 // * <a href="Locale.html#def_locale_extension">Unicode extension</a>, 1444 // * and time zone hasn't been given explicitly, time zone in the locale 1445 // * is used. 1446 // * 1447 // * <p>Any out of range field values are either normalized in lenient 1448 // * mode or detected as an invalid value in non-lenient mode. 1449 // * 1450 // * @return a {@code Calendar} built with parameters of this {@code 1451 // * Calendar.Builder} 1452 // * @throws IllegalArgumentException if the calendar type is unknown, or 1453 // * if any invalid field values are given in non-lenient mode, or 1454 // * if a week date is given for the calendar type that doesn't 1455 // * support week dates. 1456 // * @see Calendar#getInstance(TimeZone, Locale) 1457 // * @see Locale#getDefault(LocaleCategory) 1458 // * @see TimeZone#getDefault() 1459 // */ 1460 // Calendar build() { 1461 // if (locale is null) { 1462 // locale = Locale.getDefault(); 1463 // } 1464 // if (zone is null) { 1465 // zone = defaultTimeZone(locale); 1466 // } 1467 // Calendar cal; 1468 // if (type is null) { 1469 // type = locale.getUnicodeLocaleType("ca"); 1470 // } 1471 // if (type is null) { 1472 // if (locale.getCountry() == "TH" 1473 // && locale.getLanguage() == "th") { 1474 // type = "buddhist"; 1475 // } else { 1476 // type = "gregory"; 1477 // } 1478 // } 1479 // switch (type) { 1480 // case "gregory": 1481 // cal = new GregorianCalendar(zone, locale, true); 1482 // break; 1483 // case "iso8601": 1484 // GregorianCalendar gcal = new GregorianCalendar(zone, locale, true); 1485 // // make gcal a proleptic Gregorian 1486 // gcal.setGregorianChange(new LocalDateTime(Long.MIN_VALUE)); 1487 // // and week definition to be compatible with ISO 8601 1488 // setWeekDefinition(MONDAY, 4); 1489 // cal = gcal; 1490 // break; 1491 // case "buddhist": 1492 // cal = new BuddhistCalendar(zone, locale); 1493 // cal.clear(); 1494 // break; 1495 // case "japanese": 1496 // cal = new JapaneseImperialCalendar(zone, locale, true); 1497 // break; 1498 // default: 1499 // throw new IllegalArgumentException("unknown calendar type: " ~ type); 1500 // } 1501 // cal.setLenient(lenient); 1502 // if (firstDayOfWeek != 0) { 1503 // cal.setFirstDayOfWeek(firstDayOfWeek); 1504 // cal.setMinimalDaysInFirstWeek(minimalDaysInFirstWeek); 1505 // } 1506 // if (isInstantSet()) { 1507 // cal.setTimeInMillis(instant); 1508 // cal.complete(); 1509 // return cal; 1510 // } 1511 1512 // if (fields !is null) { 1513 // bool weekDate = isSet(WEEK_YEAR) 1514 // && fields[WEEK_YEAR] > fields[YEAR]; 1515 // if (weekDate && !cal.isWeekDateSupported()) { 1516 // throw new IllegalArgumentException("week date is unsupported by " ~ type); 1517 // } 1518 1519 // // Set the fields from the min stamp to the max stamp so that 1520 // // the fields resolution works in the Calendar. 1521 // for (int stamp = MINIMUM_USER_STAMP; stamp < nextStamp; stamp++) { 1522 // for (int index = 0; index <= maxFieldIndex; index++) { 1523 // if (fields[index] == stamp) { 1524 // cal.set(index, fields[NFIELDS + index]); 1525 // break; 1526 // } 1527 // } 1528 // } 1529 1530 // if (weekDate) { 1531 // int weekOfYear = isSet(WEEK_OF_YEAR) ? fields[NFIELDS + WEEK_OF_YEAR] : 1; 1532 // int dayOfWeek = isSet(DAY_OF_WEEK) 1533 // ? fields[NFIELDS + DAY_OF_WEEK] : cal.getFirstDayOfWeek(); 1534 // cal.setWeekDate(fields[NFIELDS + WEEK_YEAR], weekOfYear, dayOfWeek); 1535 // } 1536 // cal.complete(); 1537 // } 1538 1539 // return cal; 1540 // } 1541 1542 // private void allocateFields() { 1543 // if (fields is null) { 1544 // fields = new int[NFIELDS * 2]; 1545 // nextStamp = MINIMUM_USER_STAMP; 1546 // maxFieldIndex = -1; 1547 // } 1548 // } 1549 1550 // private void internalSet(int field, int value) { 1551 // fields[field] = nextStamp++; 1552 // if (nextStamp < 0) { 1553 // throw new IllegalStateException("stamp counter overflow"); 1554 // } 1555 // fields[NFIELDS + field] = value; 1556 // if (field > maxFieldIndex && field < WEEK_YEAR) { 1557 // maxFieldIndex = field; 1558 // } 1559 // } 1560 1561 // private bool isInstantSet() { 1562 // return nextStamp == COMPUTED; 1563 // } 1564 1565 // private bool isSet(int index) { 1566 // return fields !is null && fields[index] > UNSET; 1567 // } 1568 1569 // private bool isValidWeekParameter(int value) { 1570 // return value > 0 && value <= 7; 1571 // } 1572 // } 1573 1574 /** 1575 * Constructs a Calendar with the default time zone 1576 * and the default {@link java.util.LocaleCategory#FORMAT FORMAT} 1577 * locale. 1578 * @see TimeZone#getDefault 1579 */ 1580 // protected this() 1581 // { 1582 // this(TimeZone.getDefaultRef(), Locale.getDefault(LocaleCategory.FORMAT)); 1583 // sharedZone = true; 1584 // } 1585 1586 // /** 1587 // * Constructs a calendar with the specified time zone and locale. 1588 // * 1589 // * @param zone the time zone to use 1590 // * @param aLocale the locale for the week data 1591 // */ 1592 // protected Calendar(TimeZone zone, Locale aLocale) 1593 // { 1594 // fields = new int[FIELD_COUNT]; 1595 // isSet = new bool[FIELD_COUNT]; 1596 // stamp = new int[FIELD_COUNT]; 1597 1598 // this.zone = zone; 1599 // setWeekCountData(aLocale); 1600 // } 1601 1602 /** 1603 * Gets a calendar using the default time zone and locale. The 1604 * <code>Calendar</code> returned is based on the current time 1605 * in the default time zone with the default 1606 * {@link LocaleCategory#FORMAT FORMAT} locale. 1607 * <p> 1608 * If the locale contains the time zone with "tz" 1609 * <a href="Locale.html#def_locale_extension">Unicode extension</a>, 1610 * that time zone is used instead. 1611 * 1612 * @return a Calendar. 1613 */ 1614 static Calendar getInstance() 1615 { 1616 Locale aLocale = Locale.getDefault(LocaleCategory.FORMAT); 1617 return createCalendar(defaultTimeZone(aLocale), aLocale); 1618 } 1619 1620 /** 1621 * Gets a calendar using the specified time zone and default locale. 1622 * The <code>Calendar</code> returned is based on the current time 1623 * in the given time zone with the default 1624 * {@link LocaleCategory#FORMAT FORMAT} locale. 1625 * 1626 * @param zone the time zone to use 1627 * @return a Calendar. 1628 */ 1629 static Calendar getInstance(TimeZone zone) 1630 { 1631 return createCalendar(zone, Locale.getDefault(LocaleCategory.FORMAT)); 1632 } 1633 1634 /** 1635 * Gets a calendar using the default time zone and specified locale. 1636 * The <code>Calendar</code> returned is based on the current time 1637 * in the default time zone with the given locale. 1638 * <p> 1639 * If the locale contains the time zone with "tz" 1640 * <a href="Locale.html#def_locale_extension">Unicode extension</a>, 1641 * that time zone is used instead. 1642 * 1643 * @param aLocale the locale for the week data 1644 * @return a Calendar. 1645 */ 1646 static Calendar getInstance(Locale aLocale) 1647 { 1648 return createCalendar(defaultTimeZone(aLocale), aLocale); 1649 } 1650 1651 /** 1652 * Gets a calendar with the specified time zone and locale. 1653 * The <code>Calendar</code> returned is based on the current time 1654 * in the given time zone with the given locale. 1655 * 1656 * @param zone the time zone to use 1657 * @param aLocale the locale for the week data 1658 * @return a Calendar. 1659 */ 1660 static Calendar getInstance(TimeZone zone, 1661 Locale aLocale) 1662 { 1663 return createCalendar(zone, aLocale); 1664 } 1665 1666 private static TimeZone defaultTimeZone(Locale l) { 1667 import hunt.system.TimeZone; 1668 string tzId = getSystemTimeZoneId(); 1669 version(Posix) { 1670 return cast(TimeZone)PosixTimeZone.getTimeZone(tzId); 1671 } else version(Windows) { 1672 return cast(TimeZone)WindowsTimeZone.getTimeZone(tzId); 1673 } else { 1674 return cast(TimeZone)LocalTime(); 1675 } 1676 // TimeZone defaultTZ = TimeZone.getDefault(); 1677 // TODO: Tasks pending completion -@zxp at 12/20/2018, 7:53:18 PM 1678 // 1679 // return defaultTZ; 1680 // String shortTZID = l.getUnicodeLocaleType("tz"); 1681 // return shortTZID !is null ? 1682 // TimeZoneNameUtility.convertLDMLShortID(shortTZID) 1683 // .map(TimeZone::getTimeZone) 1684 // .orElse(defaultTZ) : 1685 // defaultTZ; 1686 } 1687 1688 private static Calendar createCalendar(TimeZone zone, 1689 Locale aLocale) 1690 { 1691 // CalendarProvider provider = 1692 // LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale) 1693 // .getCalendarProvider(); 1694 // if (provider !is null) { 1695 // try { 1696 // return provider.getInstance(zone, aLocale); 1697 // } catch (IllegalArgumentException iae) { 1698 // // fall back to the default instantiation 1699 // } 1700 // } 1701 1702 // Calendar cal = new GregorianCalendar(zone, aLocale); 1703 // return cal; 1704 1705 // if (aLocale.hasExtensions()) { 1706 // String caltype = aLocale.getUnicodeLocaleType("ca"); 1707 // if (caltype !is null) { 1708 // switch (caltype) { 1709 // case "buddhist": 1710 // cal = new BuddhistCalendar(zone, aLocale); 1711 // break; 1712 // case "japanese": 1713 // cal = new JapaneseImperialCalendar(zone, aLocale); 1714 // break; 1715 // case "gregory": 1716 // cal = new GregorianCalendar(zone, aLocale); 1717 // break; 1718 // } 1719 // } 1720 // } 1721 // if (cal is null) { 1722 // // If no known calendar type is explicitly specified, 1723 // // perform the traditional way to create a Calendar: 1724 // // create a BuddhistCalendar for th_TH locale, 1725 // // a JapaneseImperialCalendar for ja_JP_JP locale, or 1726 // // a GregorianCalendar for any other locales. 1727 // // NOTE: The language, country and variant strings are interned. 1728 // if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") { 1729 // cal = new BuddhistCalendar(zone, aLocale); 1730 // } else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja" 1731 // && aLocale.getCountry() == "JP") { 1732 // cal = new JapaneseImperialCalendar(zone, aLocale); 1733 // } else { 1734 // cal = new GregorianCalendar(zone, aLocale); 1735 // } 1736 // } 1737 // return cal; 1738 1739 implementationMissing(false); 1740 return null; 1741 } 1742 1743 // /** 1744 // * Returns an array of all locales for which the <code>getInstance</code> 1745 // * methods of this class can return localized instances. 1746 // * The array returned must contain at least a <code>Locale</code> 1747 // * instance equal to {@link java.util.Locale#US Locale.US}. 1748 // * 1749 // * @return An array of locales for which localized 1750 // * <code>Calendar</code> instances are available. 1751 // */ 1752 // static synchronized Locale[] getAvailableLocales() 1753 // { 1754 // return DateFormat.getAvailableLocales(); 1755 // } 1756 1757 // /** 1758 // * Converts the current calendar field values in {@link #fields fields[]} 1759 // * to the millisecond time value 1760 // * {@link #time}. 1761 // * 1762 // * @see #complete() 1763 // * @see #computeFields() 1764 // */ 1765 // protected abstract void computeTime(); 1766 1767 // /** 1768 // * Converts the current millisecond time value {@link #time} 1769 // * to calendar field values in {@link #fields fields[]}. 1770 // * This allows you to sync up the calendar field values with 1771 // * a new time that is set for the calendar. The time is <em>not</em> 1772 // * recomputed first; to recompute the time, then the fields, call the 1773 // * {@link #complete()} method. 1774 // * 1775 // * @see #computeTime() 1776 // */ 1777 // protected abstract void computeFields(); 1778 1779 // /** 1780 // * Returns a <code>LocalDateTime</code> object representing this 1781 // * <code>Calendar</code>'s time value (millisecond offset from the <a 1782 // * href="#Epoch">Epoch</a>"). 1783 // * 1784 // * @return a <code>LocalDateTime</code> representing the time value. 1785 // * @see #setTime(LocalDateTime) 1786 // * @see #getTimeInMillis() 1787 // */ 1788 // const LocalDateTime getTime() { 1789 // return new LocalDateTime(getTimeInMillis()); 1790 // } 1791 1792 // /** 1793 // * Sets this Calendar's time with the given <code>LocalDateTime</code>. 1794 // * <p> 1795 // * Note: Calling <code>setTime()</code> with 1796 // * <code>LocalDateTime(Long.MAX_VALUE)</code> or <code>LocalDateTime(Long.MIN_VALUE)</code> 1797 // * may yield incorrect field values from <code>get()</code>. 1798 // * 1799 // * @param date the given LocalDateTime. 1800 // * @see #getTime() 1801 // * @see #setTimeInMillis(long) 1802 // */ 1803 // const void setTime(LocalDateTime date) { 1804 // setTimeInMillis(date.getTime()); 1805 // } 1806 1807 // /** 1808 // * Returns this Calendar's time value in milliseconds. 1809 // * 1810 // * @return the current time as UTC milliseconds from the epoch. 1811 // * @see #getTime() 1812 // * @see #setTimeInMillis(long) 1813 // */ 1814 // long getTimeInMillis() { 1815 // if (!isTimeSet) { 1816 // updateTime(); 1817 // } 1818 // return time; 1819 // } 1820 1821 // /** 1822 // * Sets this Calendar's current time from the given long value. 1823 // * 1824 // * @param millis the new time in UTC milliseconds from the epoch. 1825 // * @see #setTime(LocalDateTime) 1826 // * @see #getTimeInMillis() 1827 // */ 1828 // void setTimeInMillis(long millis) { 1829 // // If we don't need to recalculate the calendar field values, 1830 // // do nothing. 1831 // if (time == millis && isTimeSet && areFieldsSet && areAllFieldsSet 1832 // && (zone instanceof ZoneInfo) && !((ZoneInfo)zone).isDirty()) { 1833 // return; 1834 // } 1835 // time = millis; 1836 // isTimeSet = true; 1837 // areFieldsSet = false; 1838 // computeFields(); 1839 // areAllFieldsSet = areFieldsSet = true; 1840 // } 1841 1842 // /** 1843 // * Returns the value of the given calendar field. In lenient mode, 1844 // * all calendar fields are normalized. In non-lenient mode, all 1845 // * calendar fields are validated and this method throws an 1846 // * exception if any calendar fields have out-of-range values. The 1847 // * normalization and validation are handled by the 1848 // * {@link #complete()} method, which process is calendar 1849 // * system dependent. 1850 // * 1851 // * @param field the given calendar field. 1852 // * @return the value for the given calendar field. 1853 // * @throws ArrayIndexOutOfBoundsException if the specified field is out of range 1854 // * (<code>field < 0 || field >= FIELD_COUNT</code>). 1855 // * @see #set(int,int) 1856 // * @see #complete() 1857 // */ 1858 // int get(int field) 1859 // { 1860 // complete(); 1861 // return internalGet(field); 1862 // } 1863 1864 // /** 1865 // * Returns the value of the given calendar field. This method does 1866 // * not involve normalization or validation of the field value. 1867 // * 1868 // * @param field the given calendar field. 1869 // * @return the value for the given calendar field. 1870 // * @see #get(int) 1871 // */ 1872 // protected const int internalGet(int field) 1873 // { 1874 // return fields[field]; 1875 // } 1876 1877 // /** 1878 // * Sets the value of the given calendar field. This method does 1879 // * not affect any setting state of the field in this 1880 // * <code>Calendar</code> instance. 1881 // * 1882 // * @throws IndexOutOfBoundsException if the specified field is out of range 1883 // * (<code>field < 0 || field >= FIELD_COUNT</code>). 1884 // * @see #areFieldsSet 1885 // * @see #isTimeSet 1886 // * @see #areAllFieldsSet 1887 // * @see #set(int,int) 1888 // */ 1889 // const void internalSet(int field, int value) 1890 // { 1891 // fields[field] = value; 1892 // } 1893 1894 // /** 1895 // * Sets the given calendar field to the given value. The value is not 1896 // * interpreted by this method regardless of the leniency mode. 1897 // * 1898 // * @param field the given calendar field. 1899 // * @param value the value to be set for the given calendar field. 1900 // * @throws ArrayIndexOutOfBoundsException if the specified field is out of range 1901 // * (<code>field < 0 || field >= FIELD_COUNT</code>). 1902 // * in non-lenient mode. 1903 // * @see #set(int,int,int) 1904 // * @see #set(int,int,int,int,int) 1905 // * @see #set(int,int,int,int,int,int) 1906 // * @see #get(int) 1907 // */ 1908 // void set(int field, int value) 1909 // { 1910 // // If the fields are partially normalized, calculate all the 1911 // // fields before changing any fields. 1912 // if (areFieldsSet && !areAllFieldsSet) { 1913 // computeFields(); 1914 // } 1915 // internalSet(field, value); 1916 // isTimeSet = false; 1917 // areFieldsSet = false; 1918 // isSet[field] = true; 1919 // stamp[field] = nextStamp++; 1920 // if (nextStamp == Integer.MAX_VALUE) { 1921 // adjustStamp(); 1922 // } 1923 // } 1924 1925 // /** 1926 // * Sets the values for the calendar fields <code>YEAR</code>, 1927 // * <code>MONTH</code>, and <code>DAY_OF_MONTH</code>. 1928 // * Previous values of other calendar fields are retained. If this is not desired, 1929 // * call {@link #clear()} first. 1930 // * 1931 // * @param year the value used to set the <code>YEAR</code> calendar field. 1932 // * @param month the value used to set the <code>MONTH</code> calendar field. 1933 // * Month value is 0-based. e.g., 0 for January. 1934 // * @param date the value used to set the <code>DAY_OF_MONTH</code> calendar field. 1935 // * @see #set(int,int) 1936 // * @see #set(int,int,int,int,int) 1937 // * @see #set(int,int,int,int,int,int) 1938 // */ 1939 // const void set(int year, int month, int date) 1940 // { 1941 // set(YEAR, year); 1942 // set(MONTH, month); 1943 // set(DATE, date); 1944 // } 1945 1946 // /** 1947 // * Sets the values for the calendar fields <code>YEAR</code>, 1948 // * <code>MONTH</code>, <code>DAY_OF_MONTH</code>, 1949 // * <code>HOUR_OF_DAY</code>, and <code>MINUTE</code>. 1950 // * Previous values of other fields are retained. If this is not desired, 1951 // * call {@link #clear()} first. 1952 // * 1953 // * @param year the value used to set the <code>YEAR</code> calendar field. 1954 // * @param month the value used to set the <code>MONTH</code> calendar field. 1955 // * Month value is 0-based. e.g., 0 for January. 1956 // * @param date the value used to set the <code>DAY_OF_MONTH</code> calendar field. 1957 // * @param hourOfDay the value used to set the <code>HOUR_OF_DAY</code> calendar field. 1958 // * @param minute the value used to set the <code>MINUTE</code> calendar field. 1959 // * @see #set(int,int) 1960 // * @see #set(int,int,int) 1961 // * @see #set(int,int,int,int,int,int) 1962 // */ 1963 // const void set(int year, int month, int date, int hourOfDay, int minute) 1964 // { 1965 // set(YEAR, year); 1966 // set(MONTH, month); 1967 // set(DATE, date); 1968 // set(HOUR_OF_DAY, hourOfDay); 1969 // set(MINUTE, minute); 1970 // } 1971 1972 // /** 1973 // * Sets the values for the fields <code>YEAR</code>, <code>MONTH</code>, 1974 // * <code>DAY_OF_MONTH</code>, <code>HOUR_OF_DAY</code>, <code>MINUTE</code>, and 1975 // * <code>SECOND</code>. 1976 // * Previous values of other fields are retained. If this is not desired, 1977 // * call {@link #clear()} first. 1978 // * 1979 // * @param year the value used to set the <code>YEAR</code> calendar field. 1980 // * @param month the value used to set the <code>MONTH</code> calendar field. 1981 // * Month value is 0-based. e.g., 0 for January. 1982 // * @param date the value used to set the <code>DAY_OF_MONTH</code> calendar field. 1983 // * @param hourOfDay the value used to set the <code>HOUR_OF_DAY</code> calendar field. 1984 // * @param minute the value used to set the <code>MINUTE</code> calendar field. 1985 // * @param second the value used to set the <code>SECOND</code> calendar field. 1986 // * @see #set(int,int) 1987 // * @see #set(int,int,int) 1988 // * @see #set(int,int,int,int,int) 1989 // */ 1990 // const void set(int year, int month, int date, int hourOfDay, int minute, 1991 // int second) 1992 // { 1993 // set(YEAR, year); 1994 // set(MONTH, month); 1995 // set(DATE, date); 1996 // set(HOUR_OF_DAY, hourOfDay); 1997 // set(MINUTE, minute); 1998 // set(SECOND, second); 1999 // } 2000 2001 // /** 2002 // * Sets all the calendar field values and the time value 2003 // * (millisecond offset from the <a href="#Epoch">Epoch</a>) of 2004 // * this <code>Calendar</code> undefined. This means that {@link 2005 // * #isSet(int) isSet()} will return <code>false</code> for all the 2006 // * calendar fields, and the date and time calculations will treat 2007 // * the fields as if they had never been set. A 2008 // * <code>Calendar</code> implementation class may use its specific 2009 // * default field values for date/time calculations. For example, 2010 // * <code>GregorianCalendar</code> uses 1970 if the 2011 // * <code>YEAR</code> field value is undefined. 2012 // * 2013 // * @see #clear(int) 2014 // */ 2015 // const void clear() 2016 // { 2017 // for (int i = 0; i < fields.length; ) { 2018 // stamp[i] = fields[i] = 0; // UNSET == 0 2019 // isSet[i++] = false; 2020 // } 2021 // areAllFieldsSet = areFieldsSet = false; 2022 // isTimeSet = false; 2023 // } 2024 2025 // /** 2026 // * Sets the given calendar field value and the time value 2027 // * (millisecond offset from the <a href="#Epoch">Epoch</a>) of 2028 // * this <code>Calendar</code> undefined. This means that {@link 2029 // * #isSet(int) isSet(field)} will return <code>false</code>, and 2030 // * the date and time calculations will treat the field as if it 2031 // * had never been set. A <code>Calendar</code> implementation 2032 // * class may use the field's specific default value for date and 2033 // * time calculations. 2034 // * 2035 // * <p>The {@link #HOUR_OF_DAY}, {@link #HOUR} and {@link #AM_PM} 2036 // * fields are handled independently and the <a 2037 // * href="#time_resolution">the resolution rule for the time of 2038 // * day</a> is applied. Clearing one of the fields doesn't reset 2039 // * the hour of day value of this <code>Calendar</code>. Use {@link 2040 // * #set(int,int) set(Calendar.HOUR_OF_DAY, 0)} to reset the hour 2041 // * value. 2042 // * 2043 // * @param field the calendar field to be cleared. 2044 // * @see #clear() 2045 // */ 2046 // const void clear(int field) 2047 // { 2048 // fields[field] = 0; 2049 // stamp[field] = UNSET; 2050 // isSet[field] = false; 2051 2052 // areAllFieldsSet = areFieldsSet = false; 2053 // isTimeSet = false; 2054 // } 2055 2056 // /** 2057 // * Determines if the given calendar field has a value set, 2058 // * including cases that the value has been set by internal fields 2059 // * calculations triggered by a <code>get</code> method call. 2060 // * 2061 // * @param field the calendar field to test 2062 // * @return <code>true</code> if the given calendar field has a value set; 2063 // * <code>false</code> otherwise. 2064 // */ 2065 // const bool isSet(int field) 2066 // { 2067 // return stamp[field] != UNSET; 2068 // } 2069 2070 // /** 2071 // * Returns the string representation of the calendar 2072 // * <code>field</code> value in the given <code>style</code> and 2073 // * <code>locale</code>. If no string representation is 2074 // * applicable, <code>null</code> is returned. This method calls 2075 // * {@link Calendar#get(int) get(field)} to get the calendar 2076 // * <code>field</code> value if the string representation is 2077 // * applicable to the given calendar <code>field</code>. 2078 // * 2079 // * <p>For example, if this <code>Calendar</code> is a 2080 // * <code>GregorianCalendar</code> and its date is 2005-01-01, then 2081 // * the string representation of the {@link #MONTH} field would be 2082 // * "January" in the long style in an English locale or "Jan" in 2083 // * the short style. However, no string representation would be 2084 // * available for the {@link #DAY_OF_MONTH} field, and this method 2085 // * would return <code>null</code>. 2086 // * 2087 // * <p>The default implementation supports the calendar fields for 2088 // * which a {@link DateFormatSymbols} has names in the given 2089 // * <code>locale</code>. 2090 // * 2091 // * @param field 2092 // * the calendar field for which the string representation 2093 // * is returned 2094 // * @param style 2095 // * the style applied to the string representation; one of {@link 2096 // * #SHORT_FORMAT} ({@link #SHORT}), {@link #SHORT_STANDALONE}, 2097 // * {@link #LONG_FORMAT} ({@link #LONG}), {@link #LONG_STANDALONE}, 2098 // * {@link #NARROW_FORMAT}, or {@link #NARROW_STANDALONE}. 2099 // * @param locale 2100 // * the locale for the string representation 2101 // * (any calendar types specified by {@code locale} are ignored) 2102 // * @return the string representation of the given 2103 // * {@code field} in the given {@code style}, or 2104 // * {@code null} if no string representation is 2105 // * applicable. 2106 // * @exception IllegalArgumentException 2107 // * if {@code field} or {@code style} is invalid, 2108 // * or if this {@code Calendar} is non-lenient and any 2109 // * of the calendar fields have invalid values 2110 // * @exception NullPointerException 2111 // * if {@code locale} is null 2112 // * @since 1.6 2113 // */ 2114 // String getDisplayName(int field, int style, Locale locale) { 2115 // if (!checkDisplayNameParams(field, style, SHORT, NARROW_FORMAT, locale, 2116 // ERA_MASK|MONTH_MASK|DAY_OF_WEEK_MASK|AM_PM_MASK)) { 2117 // return null; 2118 // } 2119 2120 // String calendarType = getCalendarType(); 2121 // int fieldValue = get(field); 2122 // // the standalone/narrow styles and short era are supported only through 2123 // // CalendarNameProviders. 2124 // if (isStandaloneStyle(style) || isNarrowFormatStyle(style) || 2125 // field == ERA && (style & SHORT) == SHORT) { 2126 // String val = CalendarDataUtility.retrieveFieldValueName(calendarType, 2127 // field, fieldValue, 2128 // style, locale); 2129 // // Perform fallback here to follow the CLDR rules 2130 // if (val is null) { 2131 // if (isNarrowFormatStyle(style)) { 2132 // val = CalendarDataUtility.retrieveFieldValueName(calendarType, 2133 // field, fieldValue, 2134 // toStandaloneStyle(style), 2135 // locale); 2136 // } else if (isStandaloneStyle(style)) { 2137 // val = CalendarDataUtility.retrieveFieldValueName(calendarType, 2138 // field, fieldValue, 2139 // getBaseStyle(style), 2140 // locale); 2141 // } 2142 // } 2143 // return val; 2144 // } 2145 2146 // DateFormatSymbols symbols = DateFormatSymbols.getInstance(locale); 2147 // String[] strings = getFieldStrings(field, style, symbols); 2148 // if (strings !is null) { 2149 // if (fieldValue < strings.length) { 2150 // return strings[fieldValue]; 2151 // } 2152 // } 2153 // return null; 2154 // } 2155 2156 // /** 2157 // * Returns a {@code Map} containing all names of the calendar 2158 // * {@code field} in the given {@code style} and 2159 // * {@code locale} and their corresponding field values. For 2160 // * example, if this {@code Calendar} is a {@link 2161 // * GregorianCalendar}, the returned map would contain "Jan" to 2162 // * {@link #JANUARY}, "Feb" to {@link #FEBRUARY}, and so on, in the 2163 // * {@linkplain #SHORT short} style in an English locale. 2164 // * 2165 // * <p>Narrow names may not be unique due to use of single characters, 2166 // * such as "S" for Sunday and Saturday. In that case narrow names are not 2167 // * included in the returned {@code Map}. 2168 // * 2169 // * <p>The values of other calendar fields may be taken into 2170 // * account to determine a set of display names. For example, if 2171 // * this {@code Calendar} is a lunisolar calendar system and 2172 // * the year value given by the {@link #YEAR} field has a leap 2173 // * month, this method would return month names containing the leap 2174 // * month name, and month names are mapped to their values specific 2175 // * for the year. 2176 // * 2177 // * <p>The default implementation supports display names contained in 2178 // * a {@link DateFormatSymbols}. For example, if {@code field} 2179 // * is {@link #MONTH} and {@code style} is {@link 2180 // * #ALL_STYLES}, this method returns a {@code Map} containing 2181 // * all strings returned by {@link DateFormatSymbols#getShortMonths()} 2182 // * and {@link DateFormatSymbols#getMonths()}. 2183 // * 2184 // * @param field 2185 // * the calendar field for which the display names are returned 2186 // * @param style 2187 // * the style applied to the string representation; one of {@link 2188 // * #SHORT_FORMAT} ({@link #SHORT}), {@link #SHORT_STANDALONE}, 2189 // * {@link #LONG_FORMAT} ({@link #LONG}), {@link #LONG_STANDALONE}, 2190 // * {@link #NARROW_FORMAT}, or {@link #NARROW_STANDALONE} 2191 // * @param locale 2192 // * the locale for the display names 2193 // * @return a {@code Map} containing all display names in 2194 // * {@code style} and {@code locale} and their 2195 // * field values, or {@code null} if no display names 2196 // * are defined for {@code field} 2197 // * @exception IllegalArgumentException 2198 // * if {@code field} or {@code style} is invalid, 2199 // * or if this {@code Calendar} is non-lenient and any 2200 // * of the calendar fields have invalid values 2201 // * @exception NullPointerException 2202 // * if {@code locale} is null 2203 // * @since 1.6 2204 // */ 2205 // Map<String, Integer> getDisplayNames(int field, int style, Locale locale) { 2206 // if (!checkDisplayNameParams(field, style, ALL_STYLES, NARROW_FORMAT, locale, 2207 // ERA_MASK|MONTH_MASK|DAY_OF_WEEK_MASK|AM_PM_MASK)) { 2208 // return null; 2209 // } 2210 2211 // String calendarType = getCalendarType(); 2212 // if (style == ALL_STYLES || isStandaloneStyle(style) || isNarrowFormatStyle(style)) { 2213 // Map<String, Integer> map; 2214 // map = CalendarDataUtility.retrieveFieldValueNames(calendarType, field, style, locale); 2215 2216 // // Perform fallback here to follow the CLDR rules 2217 // if (map is null) { 2218 // if (isNarrowFormatStyle(style)) { 2219 // map = CalendarDataUtility.retrieveFieldValueNames(calendarType, field, 2220 // toStandaloneStyle(style), locale); 2221 // } else if (style != ALL_STYLES) { 2222 // map = CalendarDataUtility.retrieveFieldValueNames(calendarType, field, 2223 // getBaseStyle(style), locale); 2224 // } 2225 // } 2226 // return map; 2227 // } 2228 2229 // // SHORT or LONG 2230 // return getDisplayNamesImpl(field, style, locale); 2231 // } 2232 2233 // private Map<String,Integer> getDisplayNamesImpl(int field, int style, Locale locale) { 2234 // DateFormatSymbols symbols = DateFormatSymbols.getInstance(locale); 2235 // String[] strings = getFieldStrings(field, style, symbols); 2236 // if (strings !is null) { 2237 // Map<String,Integer> names = new HashMap<>(); 2238 // for (int i = 0; i < strings.length; i++) { 2239 // if (strings[i].length() == 0) { 2240 // continue; 2241 // } 2242 // names.put(strings[i], i); 2243 // } 2244 // return names; 2245 // } 2246 // return null; 2247 // } 2248 2249 // bool checkDisplayNameParams(int field, int style, int minStyle, int maxStyle, 2250 // Locale locale, int fieldMask) { 2251 // int baseStyle = getBaseStyle(style); // Ignore the standalone mask 2252 // if (field < 0 || field >= fields.length || 2253 // baseStyle < minStyle || baseStyle > maxStyle || baseStyle == 3) { 2254 // throw new IllegalArgumentException(); 2255 // } 2256 // if (locale is null) { 2257 // throw new NullPointerException(); 2258 // } 2259 // return isFieldSet(fieldMask, field); 2260 // } 2261 2262 // private String[] getFieldStrings(int field, int style, DateFormatSymbols symbols) { 2263 // int baseStyle = getBaseStyle(style); // ignore the standalone mask 2264 2265 // // DateFormatSymbols doesn't support any narrow names. 2266 // if (baseStyle == NARROW_FORMAT) { 2267 // return null; 2268 // } 2269 2270 // String[] strings = null; 2271 // switch (field) { 2272 // case ERA: 2273 // strings = symbols.getEras(); 2274 // break; 2275 2276 // case MONTH: 2277 // strings = (baseStyle == LONG) ? symbols.getMonths() : symbols.getShortMonths(); 2278 // break; 2279 2280 // case DAY_OF_WEEK: 2281 // strings = (baseStyle == LONG) ? symbols.getWeekdays() : symbols.getShortWeekdays(); 2282 // break; 2283 2284 // case AM_PM: 2285 // strings = symbols.getAmPmStrings(); 2286 // break; 2287 // } 2288 // return strings; 2289 // } 2290 2291 // /** 2292 // * Fills in any unset fields in the calendar fields. First, the {@link 2293 // * #computeTime()} method is called if the time value (millisecond offset 2294 // * from the <a href="#Epoch">Epoch</a>) has not been calculated from 2295 // * calendar field values. Then, the {@link #computeFields()} method is 2296 // * called to calculate all calendar field values. 2297 // */ 2298 // protected void complete() 2299 // { 2300 // if (!isTimeSet) { 2301 // updateTime(); 2302 // } 2303 // if (!areFieldsSet || !areAllFieldsSet) { 2304 // computeFields(); // fills in unset fields 2305 // areAllFieldsSet = areFieldsSet = true; 2306 // } 2307 // } 2308 2309 // /** 2310 // * Returns whether the value of the specified calendar field has been set 2311 // * externally by calling one of the setter methods rather than by the 2312 // * internal time calculation. 2313 // * 2314 // * @return <code>true</code> if the field has been set externally, 2315 // * <code>false</code> otherwise. 2316 // * @exception IndexOutOfBoundsException if the specified 2317 // * <code>field</code> is out of range 2318 // * (<code>field < 0 || field >= FIELD_COUNT</code>). 2319 // * @see #selectFields() 2320 // * @see #setFieldsComputed(int) 2321 // */ 2322 // const bool isExternallySet(int field) { 2323 // return stamp[field] >= MINIMUM_USER_STAMP; 2324 // } 2325 2326 // /** 2327 // * Returns a field mask (bit mask) indicating all calendar fields that 2328 // * have the state of externally or internally set. 2329 // * 2330 // * @return a bit mask indicating set state fields 2331 // */ 2332 // const int getSetStateFields() { 2333 // int mask = 0; 2334 // for (int i = 0; i < fields.length; i++) { 2335 // if (stamp[i] != UNSET) { 2336 // mask |= 1 << i; 2337 // } 2338 // } 2339 // return mask; 2340 // } 2341 2342 // /** 2343 // * Sets the state of the specified calendar fields to 2344 // * <em>computed</em>. This state means that the specified calendar fields 2345 // * have valid values that have been set by internal time calculation 2346 // * rather than by calling one of the setter methods. 2347 // * 2348 // * @param fieldMask the field to be marked as computed. 2349 // * @exception IndexOutOfBoundsException if the specified 2350 // * <code>field</code> is out of range 2351 // * (<code>field < 0 || field >= FIELD_COUNT</code>). 2352 // * @see #isExternallySet(int) 2353 // * @see #selectFields() 2354 // */ 2355 // const void setFieldsComputed(int fieldMask) { 2356 // if (fieldMask == ALL_FIELDS) { 2357 // for (int i = 0; i < fields.length; i++) { 2358 // stamp[i] = COMPUTED; 2359 // isSet[i] = true; 2360 // } 2361 // areFieldsSet = areAllFieldsSet = true; 2362 // } else { 2363 // for (int i = 0; i < fields.length; i++) { 2364 // if ((fieldMask & 1) == 1) { 2365 // stamp[i] = COMPUTED; 2366 // isSet[i] = true; 2367 // } else { 2368 // if (areAllFieldsSet && !isSet[i]) { 2369 // areAllFieldsSet = false; 2370 // } 2371 // } 2372 // fieldMask >>>= 1; 2373 // } 2374 // } 2375 // } 2376 2377 // /** 2378 // * Sets the state of the calendar fields that are <em>not</em> specified 2379 // * by <code>fieldMask</code> to <em>unset</em>. If <code>fieldMask</code> 2380 // * specifies all the calendar fields, then the state of this 2381 // * <code>Calendar</code> becomes that all the calendar fields are in sync 2382 // * with the time value (millisecond offset from the Epoch). 2383 // * 2384 // * @param fieldMask the field mask indicating which calendar fields are in 2385 // * sync with the time value. 2386 // * @exception IndexOutOfBoundsException if the specified 2387 // * <code>field</code> is out of range 2388 // * (<code>field < 0 || field >= FIELD_COUNT</code>). 2389 // * @see #isExternallySet(int) 2390 // * @see #selectFields() 2391 // */ 2392 // const void setFieldsNormalized(int fieldMask) { 2393 // if (fieldMask != ALL_FIELDS) { 2394 // for (int i = 0; i < fields.length; i++) { 2395 // if ((fieldMask & 1) == 0) { 2396 // stamp[i] = fields[i] = 0; // UNSET == 0 2397 // isSet[i] = false; 2398 // } 2399 // fieldMask >>= 1; 2400 // } 2401 // } 2402 2403 // // Some or all of the fields are in sync with the 2404 // // milliseconds, but the stamp values are not normalized yet. 2405 // areFieldsSet = true; 2406 // areAllFieldsSet = false; 2407 // } 2408 2409 // /** 2410 // * Returns whether the calendar fields are partially in sync with the time 2411 // * value or fully in sync but not stamp values are not normalized yet. 2412 // */ 2413 // const bool isPartiallyNormalized() { 2414 // return areFieldsSet && !areAllFieldsSet; 2415 // } 2416 2417 // /** 2418 // * Returns whether the calendar fields are fully in sync with the time 2419 // * value. 2420 // */ 2421 // const bool isFullyNormalized() { 2422 // return areFieldsSet && areAllFieldsSet; 2423 // } 2424 2425 // /** 2426 // * Marks this Calendar as not sync'd. 2427 // */ 2428 // const void setUnnormalized() { 2429 // areFieldsSet = areAllFieldsSet = false; 2430 // } 2431 2432 // /** 2433 // * Returns whether the specified <code>field</code> is on in the 2434 // * <code>fieldMask</code>. 2435 // */ 2436 // static bool isFieldSet(int fieldMask, int field) { 2437 // return (fieldMask & (1 << field)) != 0; 2438 // } 2439 2440 // /** 2441 // * Returns a field mask indicating which calendar field values 2442 // * to be used to calculate the time value. The calendar fields are 2443 // * returned as a bit mask, each bit of which corresponds to a field, i.e., 2444 // * the mask value of <code>field</code> is <code>(1 << 2445 // * field)</code>. For example, 0x26 represents the <code>YEAR</code>, 2446 // * <code>MONTH</code>, and <code>DAY_OF_MONTH</code> fields (i.e., 0x26 is 2447 // * equal to 2448 // * <code>(1<<YEAR)|(1<<MONTH)|(1<<DAY_OF_MONTH))</code>. 2449 // * 2450 // * <p>This method supports the calendar fields resolution as described in 2451 // * the class description. If the bit mask for a given field is on and its 2452 // * field has not been set (i.e., <code>isSet(field)</code> is 2453 // * <code>false</code>), then the default value of the field has to be 2454 // * used, which case means that the field has been selected because the 2455 // * selected combination involves the field. 2456 // * 2457 // * @return a bit mask of selected fields 2458 // * @see #isExternallySet(int) 2459 // */ 2460 // const int selectFields() { 2461 // // This implementation has been taken from the GregorianCalendar class. 2462 2463 // // The YEAR field must always be used regardless of its SET 2464 // // state because YEAR is a mandatory field to determine the date 2465 // // and the default value (EPOCH_YEAR) may change through the 2466 // // normalization process. 2467 // int fieldMask = YEAR_MASK; 2468 2469 // if (stamp[ERA] != UNSET) { 2470 // fieldMask |= ERA_MASK; 2471 // } 2472 // // Find the most recent group of fields specifying the day within 2473 // // the year. These may be any of the following combinations: 2474 // // MONTH + DAY_OF_MONTH 2475 // // MONTH + WEEK_OF_MONTH + DAY_OF_WEEK 2476 // // MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK 2477 // // DAY_OF_YEAR 2478 // // WEEK_OF_YEAR + DAY_OF_WEEK 2479 // // We look for the most recent of the fields in each group to determine 2480 // // the age of the group. For groups involving a week-related field such 2481 // // as WEEK_OF_MONTH, DAY_OF_WEEK_IN_MONTH, or WEEK_OF_YEAR, both the 2482 // // week-related field and the DAY_OF_WEEK must be set for the group as a 2483 // // whole to be considered. (See bug 4153860 - liu 7/24/98.) 2484 // int dowStamp = stamp[DAY_OF_WEEK]; 2485 // int monthStamp = stamp[MONTH]; 2486 // int domStamp = stamp[DAY_OF_MONTH]; 2487 // int womStamp = aggregateStamp(stamp[WEEK_OF_MONTH], dowStamp); 2488 // int dowimStamp = aggregateStamp(stamp[DAY_OF_WEEK_IN_MONTH], dowStamp); 2489 // int doyStamp = stamp[DAY_OF_YEAR]; 2490 // int woyStamp = aggregateStamp(stamp[WEEK_OF_YEAR], dowStamp); 2491 2492 // int bestStamp = domStamp; 2493 // if (womStamp > bestStamp) { 2494 // bestStamp = womStamp; 2495 // } 2496 // if (dowimStamp > bestStamp) { 2497 // bestStamp = dowimStamp; 2498 // } 2499 // if (doyStamp > bestStamp) { 2500 // bestStamp = doyStamp; 2501 // } 2502 // if (woyStamp > bestStamp) { 2503 // bestStamp = woyStamp; 2504 // } 2505 2506 // /* No complete combination exists. Look for WEEK_OF_MONTH, 2507 // * DAY_OF_WEEK_IN_MONTH, or WEEK_OF_YEAR alone. Treat DAY_OF_WEEK alone 2508 // * as DAY_OF_WEEK_IN_MONTH. 2509 // */ 2510 // if (bestStamp == UNSET) { 2511 // womStamp = stamp[WEEK_OF_MONTH]; 2512 // dowimStamp = Math.max(stamp[DAY_OF_WEEK_IN_MONTH], dowStamp); 2513 // woyStamp = stamp[WEEK_OF_YEAR]; 2514 // bestStamp = Math.max(Math.max(womStamp, dowimStamp), woyStamp); 2515 2516 // /* Treat MONTH alone or no fields at all as DAY_OF_MONTH. This may 2517 // * result in bestStamp = domStamp = UNSET if no fields are set, 2518 // * which indicates DAY_OF_MONTH. 2519 // */ 2520 // if (bestStamp == UNSET) { 2521 // bestStamp = domStamp = monthStamp; 2522 // } 2523 // } 2524 2525 // if (bestStamp == domStamp || 2526 // (bestStamp == womStamp && stamp[WEEK_OF_MONTH] >= stamp[WEEK_OF_YEAR]) || 2527 // (bestStamp == dowimStamp && stamp[DAY_OF_WEEK_IN_MONTH] >= stamp[WEEK_OF_YEAR])) { 2528 // fieldMask |= MONTH_MASK; 2529 // if (bestStamp == domStamp) { 2530 // fieldMask |= DAY_OF_MONTH_MASK; 2531 // } else { 2532 // assert (bestStamp == womStamp || bestStamp == dowimStamp); 2533 // if (dowStamp != UNSET) { 2534 // fieldMask |= DAY_OF_WEEK_MASK; 2535 // } 2536 // if (womStamp == dowimStamp) { 2537 // // When they are equal, give the priority to 2538 // // WEEK_OF_MONTH for compatibility. 2539 // if (stamp[WEEK_OF_MONTH] >= stamp[DAY_OF_WEEK_IN_MONTH]) { 2540 // fieldMask |= WEEK_OF_MONTH_MASK; 2541 // } else { 2542 // fieldMask |= DAY_OF_WEEK_IN_MONTH_MASK; 2543 // } 2544 // } else { 2545 // if (bestStamp == womStamp) { 2546 // fieldMask |= WEEK_OF_MONTH_MASK; 2547 // } else { 2548 // assert (bestStamp == dowimStamp); 2549 // if (stamp[DAY_OF_WEEK_IN_MONTH] != UNSET) { 2550 // fieldMask |= DAY_OF_WEEK_IN_MONTH_MASK; 2551 // } 2552 // } 2553 // } 2554 // } 2555 // } else { 2556 // assert (bestStamp == doyStamp || bestStamp == woyStamp || 2557 // bestStamp == UNSET); 2558 // if (bestStamp == doyStamp) { 2559 // fieldMask |= DAY_OF_YEAR_MASK; 2560 // } else { 2561 // assert (bestStamp == woyStamp); 2562 // if (dowStamp != UNSET) { 2563 // fieldMask |= DAY_OF_WEEK_MASK; 2564 // } 2565 // fieldMask |= WEEK_OF_YEAR_MASK; 2566 // } 2567 // } 2568 2569 // // Find the best set of fields specifying the time of day. There 2570 // // are only two possibilities here; the HOUR_OF_DAY or the 2571 // // AM_PM and the HOUR. 2572 // int hourOfDayStamp = stamp[HOUR_OF_DAY]; 2573 // int hourStamp = aggregateStamp(stamp[HOUR], stamp[AM_PM]); 2574 // bestStamp = (hourStamp > hourOfDayStamp) ? hourStamp : hourOfDayStamp; 2575 2576 // // if bestStamp is still UNSET, then take HOUR or AM_PM. (See 4846659) 2577 // if (bestStamp == UNSET) { 2578 // bestStamp = Math.max(stamp[HOUR], stamp[AM_PM]); 2579 // } 2580 2581 // // Hours 2582 // if (bestStamp != UNSET) { 2583 // if (bestStamp == hourOfDayStamp) { 2584 // fieldMask |= HOUR_OF_DAY_MASK; 2585 // } else { 2586 // fieldMask |= HOUR_MASK; 2587 // if (stamp[AM_PM] != UNSET) { 2588 // fieldMask |= AM_PM_MASK; 2589 // } 2590 // } 2591 // } 2592 // if (stamp[MINUTE] != UNSET) { 2593 // fieldMask |= MINUTE_MASK; 2594 // } 2595 // if (stamp[SECOND] != UNSET) { 2596 // fieldMask |= SECOND_MASK; 2597 // } 2598 // if (stamp[MILLISECOND] != UNSET) { 2599 // fieldMask |= MILLISECOND_MASK; 2600 // } 2601 // if (stamp[ZONE_OFFSET] >= MINIMUM_USER_STAMP) { 2602 // fieldMask |= ZONE_OFFSET_MASK; 2603 // } 2604 // if (stamp[DST_OFFSET] >= MINIMUM_USER_STAMP) { 2605 // fieldMask |= DST_OFFSET_MASK; 2606 // } 2607 2608 // return fieldMask; 2609 // } 2610 2611 // int getBaseStyle(int style) { 2612 // return style & ~STANDALONE_MASK; 2613 // } 2614 2615 // private int toStandaloneStyle(int style) { 2616 // return style | STANDALONE_MASK; 2617 // } 2618 2619 // private bool isStandaloneStyle(int style) { 2620 // return (style & STANDALONE_MASK) != 0; 2621 // } 2622 2623 // private bool isNarrowStyle(int style) { 2624 // return style == NARROW_FORMAT || style == NARROW_STANDALONE; 2625 // } 2626 2627 // private bool isNarrowFormatStyle(int style) { 2628 // return style == NARROW_FORMAT; 2629 // } 2630 2631 // /** 2632 // * Returns the pseudo-time-stamp for two fields, given their 2633 // * individual pseudo-time-stamps. If either of the fields 2634 // * is unset, then the aggregate is unset. Otherwise, the 2635 // * aggregate is the later of the two stamps. 2636 // */ 2637 // private static int aggregateStamp(int stamp_a, int stamp_b) { 2638 // if (stamp_a == UNSET || stamp_b == UNSET) { 2639 // return UNSET; 2640 // } 2641 // return (stamp_a > stamp_b) ? stamp_a : stamp_b; 2642 // } 2643 2644 // /** 2645 // * Returns an unmodifiable {@code Set} containing all calendar types 2646 // * supported by {@code Calendar} in the runtime environment. The available 2647 // * calendar types can be used for the <a 2648 // * href="Locale.html#def_locale_extension">Unicode locale extensions</a>. 2649 // * The {@code Set} returned contains at least {@code "gregory"}. The 2650 // * calendar types don't include aliases, such as {@code "gregorian"} for 2651 // * {@code "gregory"}. 2652 // * 2653 // * @return an unmodifiable {@code Set} containing all available calendar types 2654 // * @since 1.8 2655 // * @see #getCalendarType() 2656 // * @see Calendar.Builder#setCalendarType(String) 2657 // * @see Locale#getUnicodeLocaleType(String) 2658 // */ 2659 // static Set<String> getAvailableCalendarTypes() { 2660 // return AvailableCalendarTypes.SET; 2661 // } 2662 2663 // private static class AvailableCalendarTypes { 2664 // private enum Set<String> SET; 2665 // static { 2666 // Set<String> set = new HashSet<>(3); 2667 // set.add("gregory"); 2668 // set.add("buddhist"); 2669 // set.add("japanese"); 2670 // SET = Collections.unmodifiableSet(set); 2671 // } 2672 // private AvailableCalendarTypes() { 2673 // } 2674 // } 2675 2676 // /** 2677 // * Returns the calendar type of this {@code Calendar}. Calendar types are 2678 // * defined by the <em>Unicode Locale Data Markup Language (LDML)</em> 2679 // * specification. 2680 // * 2681 // * <p>The default implementation of this method returns the class name of 2682 // * this {@code Calendar} instance. Any subclasses that implement 2683 // * LDML-defined calendar systems should override this method to return 2684 // * appropriate calendar types. 2685 // * 2686 // * @return the LDML-defined calendar type or the class name of this 2687 // * {@code Calendar} instance 2688 // * @since 1.8 2689 // * @see <a href="Locale.html#def_extensions">Locale extensions</a> 2690 // * @see Locale.Builder#setLocale(Locale) 2691 // * @see Locale.Builder#setUnicodeLocaleKeyword(String, String) 2692 // */ 2693 // String getCalendarType() { 2694 // return this.getClass().getName(); 2695 // } 2696 2697 // /** 2698 // * Compares this <code>Calendar</code> to the specified 2699 // * <code>Object</code>. The result is <code>true</code> if and only if 2700 // * the argument is a <code>Calendar</code> object of the same calendar 2701 // * system that represents the same time value (millisecond offset from the 2702 // * <a href="#Epoch">Epoch</a>) under the same 2703 // * <code>Calendar</code> parameters as this object. 2704 // * 2705 // * <p>The <code>Calendar</code> parameters are the values represented 2706 // * by the <code>isLenient</code>, <code>getFirstDayOfWeek</code>, 2707 // * <code>getMinimalDaysInFirstWeek</code> and <code>getTimeZone</code> 2708 // * methods. If there is any difference in those parameters 2709 // * between the two <code>Calendar</code>s, this method returns 2710 // * <code>false</code>. 2711 // * 2712 // * <p>Use the {@link #compareTo(Calendar) compareTo} method to 2713 // * compare only the time values. 2714 // * 2715 // * @param obj the object to compare with. 2716 // * @return <code>true</code> if this object is equal to <code>obj</code>; 2717 // * <code>false</code> otherwise. 2718 // */ 2719 // //@SuppressWarnings("EqualsWhichDoesntCheckParameterClass") 2720 // @Override 2721 // bool equals(Object obj) { 2722 // if (this is obj) { 2723 // return true; 2724 // } 2725 // try { 2726 // Calendar that = (Calendar)obj; 2727 // return compareTo(getMillisOf(that)) == 0 && 2728 // lenient == that.lenient && 2729 // firstDayOfWeek == that.firstDayOfWeek && 2730 // minimalDaysInFirstWeek == that.minimalDaysInFirstWeek && 2731 // zone.equals(that.zone); 2732 // } catch (Exception e) { 2733 // // Note: GregorianCalendar.computeTime throws 2734 // // IllegalArgumentException if the ERA value is invalid 2735 // // even it's in lenient mode. 2736 // } 2737 // return false; 2738 // } 2739 2740 // /** 2741 // * Returns a hash code for this calendar. 2742 // * 2743 // * @return a hash code value for this object. 2744 // * @since 1.2 2745 // */ 2746 // @Override 2747 // int hashCode() { 2748 // // 'otheritems' represents the hash code for the previous versions. 2749 // int otheritems = (lenient ? 1 : 0) 2750 // | (firstDayOfWeek << 1) 2751 // | (minimalDaysInFirstWeek << 4) 2752 // | (zone.hashCode() << 7); 2753 // long t = getMillisOf(this); 2754 // return (int) t ^ (int)(t >> 32) ^ otheritems; 2755 // } 2756 2757 // /** 2758 // * Returns whether this <code>Calendar</code> represents a time 2759 // * before the time represented by the specified 2760 // * <code>Object</code>. This method is equivalent to: 2761 // * <pre>{@code 2762 // * compareTo(when) < 0 2763 // * }</pre> 2764 // * if and only if <code>when</code> is a <code>Calendar</code> 2765 // * instance. Otherwise, the method returns <code>false</code>. 2766 // * 2767 // * @param when the <code>Object</code> to be compared 2768 // * @return <code>true</code> if the time of this 2769 // * <code>Calendar</code> is before the time represented by 2770 // * <code>when</code>; <code>false</code> otherwise. 2771 // * @see #compareTo(Calendar) 2772 // */ 2773 // bool before(Object when) { 2774 // return when instanceof Calendar 2775 // && compareTo((Calendar)when) < 0; 2776 // } 2777 2778 // /** 2779 // * Returns whether this <code>Calendar</code> represents a time 2780 // * after the time represented by the specified 2781 // * <code>Object</code>. This method is equivalent to: 2782 // * <pre>{@code 2783 // * compareTo(when) > 0 2784 // * }</pre> 2785 // * if and only if <code>when</code> is a <code>Calendar</code> 2786 // * instance. Otherwise, the method returns <code>false</code>. 2787 // * 2788 // * @param when the <code>Object</code> to be compared 2789 // * @return <code>true</code> if the time of this <code>Calendar</code> is 2790 // * after the time represented by <code>when</code>; <code>false</code> 2791 // * otherwise. 2792 // * @see #compareTo(Calendar) 2793 // */ 2794 // bool after(Object when) { 2795 // return when instanceof Calendar 2796 // && compareTo((Calendar)when) > 0; 2797 // } 2798 2799 // /** 2800 // * Compares the time values (millisecond offsets from the <a 2801 // * href="#Epoch">Epoch</a>) represented by two 2802 // * <code>Calendar</code> objects. 2803 // * 2804 // * @param anotherCalendar the <code>Calendar</code> to be compared. 2805 // * @return the value <code>0</code> if the time represented by the argument 2806 // * is equal to the time represented by this <code>Calendar</code>; a value 2807 // * less than <code>0</code> if the time of this <code>Calendar</code> is 2808 // * before the time represented by the argument; and a value greater than 2809 // * <code>0</code> if the time of this <code>Calendar</code> is after the 2810 // * time represented by the argument. 2811 // * @exception NullPointerException if the specified <code>Calendar</code> is 2812 // * <code>null</code>. 2813 // * @exception IllegalArgumentException if the time value of the 2814 // * specified <code>Calendar</code> object can't be obtained due to 2815 // * any invalid calendar values. 2816 // * @since 1.5 2817 // */ 2818 // @Override 2819 // int compareTo(Calendar anotherCalendar) { 2820 // return compareTo(getMillisOf(anotherCalendar)); 2821 // } 2822 2823 // /** 2824 // * Adds or subtracts the specified amount of time to the given calendar field, 2825 // * based on the calendar's rules. For example, to subtract 5 days from 2826 // * the current time of the calendar, you can achieve it by calling: 2827 // * <p><code>add(Calendar.DAY_OF_MONTH, -5)</code>. 2828 // * 2829 // * @param field the calendar field. 2830 // * @param amount the amount of date or time to be added to the field. 2831 // * @see #roll(int,int) 2832 // * @see #set(int,int) 2833 // */ 2834 // abstract void add(int field, int amount); 2835 2836 // /** 2837 // * Adds or subtracts (up/down) a single unit of time on the given time 2838 // * field without changing larger fields. For example, to roll the current 2839 // * date up by one day, you can achieve it by calling: 2840 // * <p>roll(Calendar.DATE, true). 2841 // * When rolling on the year or Calendar.YEAR field, it will roll the year 2842 // * value in the range between 1 and the value returned by calling 2843 // * <code>getMaximum(Calendar.YEAR)</code>. 2844 // * When rolling on the month or Calendar.MONTH field, other fields like 2845 // * date might conflict and, need to be changed. For instance, 2846 // * rolling the month on the date 01/31/96 will result in 02/29/96. 2847 // * When rolling on the hour-in-day or Calendar.HOUR_OF_DAY field, it will 2848 // * roll the hour value in the range between 0 and 23, which is zero-based. 2849 // * 2850 // * @param field the time field. 2851 // * @param up indicates if the value of the specified time field is to be 2852 // * rolled up or rolled down. Use true if rolling up, false otherwise. 2853 // * @see Calendar#add(int,int) 2854 // * @see Calendar#set(int,int) 2855 // */ 2856 // abstract void roll(int field, bool up); 2857 2858 // /** 2859 // * Adds the specified (signed) amount to the specified calendar field 2860 // * without changing larger fields. A negative amount means to roll 2861 // * down. 2862 // * 2863 // * <p>NOTE: This default implementation on <code>Calendar</code> just repeatedly calls the 2864 // * version of {@link #roll(int,bool) roll()} that rolls by one unit. This may not 2865 // * always do the right thing. For example, if the <code>DAY_OF_MONTH</code> field is 31, 2866 // * rolling through February will leave it set to 28. The <code>GregorianCalendar</code> 2867 // * version of this function takes care of this problem. Other subclasses 2868 // * should also provide overrides of this function that do the right thing. 2869 // * 2870 // * @param field the calendar field. 2871 // * @param amount the signed amount to add to the calendar <code>field</code>. 2872 // * @since 1.2 2873 // * @see #roll(int,bool) 2874 // * @see #add(int,int) 2875 // * @see #set(int,int) 2876 // */ 2877 // void roll(int field, int amount) 2878 // { 2879 // while (amount > 0) { 2880 // roll(field, true); 2881 // amount--; 2882 // } 2883 // while (amount < 0) { 2884 // roll(field, false); 2885 // amount++; 2886 // } 2887 // } 2888 2889 // /** 2890 // * Sets the time zone with the given time zone value. 2891 // * 2892 // * @param value the given time zone. 2893 // */ 2894 // void setTimeZone(TimeZone value) 2895 // { 2896 // zone = value; 2897 // sharedZone = false; 2898 // /* Recompute the fields from the time using the new zone. This also 2899 // * works if isTimeSet is false (after a call to set()). In that case 2900 // * the time will be computed from the fields using the new zone, then 2901 // * the fields will get recomputed from that. Consider the sequence of 2902 // * calls: cal.setTimeZone(EST); cal.set(HOUR, 1); cal.setTimeZone(PST). 2903 // * Is cal set to 1 o'clock EST or 1 o'clock PST? Answer: PST. More 2904 // * generally, a call to setTimeZone() affects calls to set() BEFORE AND 2905 // * AFTER it up to the next call to complete(). 2906 // */ 2907 // areAllFieldsSet = areFieldsSet = false; 2908 // } 2909 2910 // /** 2911 // * Gets the time zone. 2912 // * 2913 // * @return the time zone object associated with this calendar. 2914 // */ 2915 // TimeZone getTimeZone() 2916 // { 2917 // // If the TimeZone object is shared by other Calendar instances, then 2918 // // create a clone. 2919 // if (sharedZone) { 2920 // zone = (TimeZone) zone.clone(); 2921 // sharedZone = false; 2922 // } 2923 // return zone; 2924 // } 2925 2926 // /** 2927 // * Returns the time zone (without cloning). 2928 // */ 2929 // TimeZone getZone() { 2930 // return zone; 2931 // } 2932 2933 // /** 2934 // * Sets the sharedZone flag to <code>shared</code>. 2935 // */ 2936 // void setZoneShared(bool shared) { 2937 // sharedZone = shared; 2938 // } 2939 2940 // /** 2941 // * Specifies whether or not date/time interpretation is to be lenient. With 2942 // * lenient interpretation, a date such as "February 942, 1996" will be 2943 // * treated as being equivalent to the 941st day after February 1, 1996. 2944 // * With strict (non-lenient) interpretation, such dates will cause an exception to be 2945 // * thrown. The default is lenient. 2946 // * 2947 // * @param lenient <code>true</code> if the lenient mode is to be turned 2948 // * on; <code>false</code> if it is to be turned off. 2949 // * @see #isLenient() 2950 // * @see java.text.DateFormat#setLenient 2951 // */ 2952 // void setLenient(bool lenient) 2953 // { 2954 // this.lenient = lenient; 2955 // } 2956 2957 // /** 2958 // * Tells whether date/time interpretation is to be lenient. 2959 // * 2960 // * @return <code>true</code> if the interpretation mode of this calendar is lenient; 2961 // * <code>false</code> otherwise. 2962 // * @see #setLenient(bool) 2963 // */ 2964 // bool isLenient() 2965 // { 2966 // return lenient; 2967 // } 2968 2969 // /** 2970 // * Sets what the first day of the week is; e.g., <code>SUNDAY</code> in the U.S., 2971 // * <code>MONDAY</code> in France. 2972 // * 2973 // * @param value the given first day of the week. 2974 // * @see #getFirstDayOfWeek() 2975 // * @see #getMinimalDaysInFirstWeek() 2976 // */ 2977 // void setFirstDayOfWeek(int value) 2978 // { 2979 // if (firstDayOfWeek == value) { 2980 // return; 2981 // } 2982 // firstDayOfWeek = value; 2983 // invalidateWeekFields(); 2984 // } 2985 2986 // /** 2987 // * Gets what the first day of the week is; e.g., <code>SUNDAY</code> in the U.S., 2988 // * <code>MONDAY</code> in France. 2989 // * 2990 // * @return the first day of the week. 2991 // * @see #setFirstDayOfWeek(int) 2992 // * @see #getMinimalDaysInFirstWeek() 2993 // */ 2994 // int getFirstDayOfWeek() 2995 // { 2996 // return firstDayOfWeek; 2997 // } 2998 2999 // /** 3000 // * Sets what the minimal days required in the first week of the year are; 3001 // * For example, if the first week is defined as one that contains the first 3002 // * day of the first month of a year, call this method with value 1. If it 3003 // * must be a full week, use value 7. 3004 // * 3005 // * @param value the given minimal days required in the first week 3006 // * of the year. 3007 // * @see #getMinimalDaysInFirstWeek() 3008 // */ 3009 // void setMinimalDaysInFirstWeek(int value) 3010 // { 3011 // if (minimalDaysInFirstWeek == value) { 3012 // return; 3013 // } 3014 // minimalDaysInFirstWeek = value; 3015 // invalidateWeekFields(); 3016 // } 3017 3018 // /** 3019 // * Gets what the minimal days required in the first week of the year are; 3020 // * e.g., if the first week is defined as one that contains the first day 3021 // * of the first month of a year, this method returns 1. If 3022 // * the minimal days required must be a full week, this method 3023 // * returns 7. 3024 // * 3025 // * @return the minimal days required in the first week of the year. 3026 // * @see #setMinimalDaysInFirstWeek(int) 3027 // */ 3028 // int getMinimalDaysInFirstWeek() 3029 // { 3030 // return minimalDaysInFirstWeek; 3031 // } 3032 3033 // /** 3034 // * Returns whether this {@code Calendar} supports week dates. 3035 // * 3036 // * <p>The default implementation of this method returns {@code false}. 3037 // * 3038 // * @return {@code true} if this {@code Calendar} supports week dates; 3039 // * {@code false} otherwise. 3040 // * @see #getWeekYear() 3041 // * @see #setWeekDate(int,int,int) 3042 // * @see #getWeeksInWeekYear() 3043 // * @since 1.7 3044 // */ 3045 // bool isWeekDateSupported() { 3046 // return false; 3047 // } 3048 3049 // /** 3050 // * Returns the week year represented by this {@code Calendar}. The 3051 // * week year is in sync with the week cycle. The {@linkplain 3052 // * #getFirstDayOfWeek() first day of the first week} is the first 3053 // * day of the week year. 3054 // * 3055 // * <p>The default implementation of this method throws an 3056 // * {@link UnsupportedOperationException}. 3057 // * 3058 // * @return the week year of this {@code Calendar} 3059 // * @exception UnsupportedOperationException 3060 // * if any week year numbering isn't supported 3061 // * in this {@code Calendar}. 3062 // * @see #isWeekDateSupported() 3063 // * @see #getFirstDayOfWeek() 3064 // * @see #getMinimalDaysInFirstWeek() 3065 // * @since 1.7 3066 // */ 3067 // int getWeekYear() { 3068 // throw new UnsupportedOperationException(); 3069 // } 3070 3071 // /** 3072 // * Sets the date of this {@code Calendar} with the given date 3073 // * specifiers - week year, week of year, and day of week. 3074 // * 3075 // * <p>Unlike the {@code set} method, all of the calendar fields 3076 // * and {@code time} values are calculated upon return. 3077 // * 3078 // * <p>If {@code weekOfYear} is out of the valid week-of-year range 3079 // * in {@code weekYear}, the {@code weekYear} and {@code 3080 // * weekOfYear} values are adjusted in lenient mode, or an {@code 3081 // * IllegalArgumentException} is thrown in non-lenient mode. 3082 // * 3083 // * <p>The default implementation of this method throws an 3084 // * {@code UnsupportedOperationException}. 3085 // * 3086 // * @param weekYear the week year 3087 // * @param weekOfYear the week number based on {@code weekYear} 3088 // * @param dayOfWeek the day of week value: one of the constants 3089 // * for the {@link #DAY_OF_WEEK} field: {@link 3090 // * #SUNDAY}, ..., {@link #SATURDAY}. 3091 // * @exception IllegalArgumentException 3092 // * if any of the given date specifiers is invalid 3093 // * or any of the calendar fields are inconsistent 3094 // * with the given date specifiers in non-lenient mode 3095 // * @exception UnsupportedOperationException 3096 // * if any week year numbering isn't supported in this 3097 // * {@code Calendar}. 3098 // * @see #isWeekDateSupported() 3099 // * @see #getFirstDayOfWeek() 3100 // * @see #getMinimalDaysInFirstWeek() 3101 // * @since 1.7 3102 // */ 3103 // void setWeekDate(int weekYear, int weekOfYear, int dayOfWeek) { 3104 // throw new UnsupportedOperationException(); 3105 // } 3106 3107 // /** 3108 // * Returns the number of weeks in the week year represented by this 3109 // * {@code Calendar}. 3110 // * 3111 // * <p>The default implementation of this method throws an 3112 // * {@code UnsupportedOperationException}. 3113 // * 3114 // * @return the number of weeks in the week year. 3115 // * @exception UnsupportedOperationException 3116 // * if any week year numbering isn't supported in this 3117 // * {@code Calendar}. 3118 // * @see #WEEK_OF_YEAR 3119 // * @see #isWeekDateSupported() 3120 // * @see #getWeekYear() 3121 // * @see #getActualMaximum(int) 3122 // * @since 1.7 3123 // */ 3124 // int getWeeksInWeekYear() { 3125 // throw new UnsupportedOperationException(); 3126 // } 3127 3128 // /** 3129 // * Returns the minimum value for the given calendar field of this 3130 // * <code>Calendar</code> instance. The minimum value is defined as 3131 // * the smallest value returned by the {@link #get(int) get} method 3132 // * for any possible time value. The minimum value depends on 3133 // * calendar system specific parameters of the instance. 3134 // * 3135 // * @param field the calendar field. 3136 // * @return the minimum value for the given calendar field. 3137 // * @see #getMaximum(int) 3138 // * @see #getGreatestMinimum(int) 3139 // * @see #getLeastMaximum(int) 3140 // * @see #getActualMinimum(int) 3141 // * @see #getActualMaximum(int) 3142 // */ 3143 // abstract int getMinimum(int field); 3144 3145 // /** 3146 // * Returns the maximum value for the given calendar field of this 3147 // * <code>Calendar</code> instance. The maximum value is defined as 3148 // * the largest value returned by the {@link #get(int) get} method 3149 // * for any possible time value. The maximum value depends on 3150 // * calendar system specific parameters of the instance. 3151 // * 3152 // * @param field the calendar field. 3153 // * @return the maximum value for the given calendar field. 3154 // * @see #getMinimum(int) 3155 // * @see #getGreatestMinimum(int) 3156 // * @see #getLeastMaximum(int) 3157 // * @see #getActualMinimum(int) 3158 // * @see #getActualMaximum(int) 3159 // */ 3160 // abstract int getMaximum(int field); 3161 3162 // /** 3163 // * Returns the highest minimum value for the given calendar field 3164 // * of this <code>Calendar</code> instance. The highest minimum 3165 // * value is defined as the largest value returned by {@link 3166 // * #getActualMinimum(int)} for any possible time value. The 3167 // * greatest minimum value depends on calendar system specific 3168 // * parameters of the instance. 3169 // * 3170 // * @param field the calendar field. 3171 // * @return the highest minimum value for the given calendar field. 3172 // * @see #getMinimum(int) 3173 // * @see #getMaximum(int) 3174 // * @see #getLeastMaximum(int) 3175 // * @see #getActualMinimum(int) 3176 // * @see #getActualMaximum(int) 3177 // */ 3178 // abstract int getGreatestMinimum(int field); 3179 3180 // /** 3181 // * Returns the lowest maximum value for the given calendar field 3182 // * of this <code>Calendar</code> instance. The lowest maximum 3183 // * value is defined as the smallest value returned by {@link 3184 // * #getActualMaximum(int)} for any possible time value. The least 3185 // * maximum value depends on calendar system specific parameters of 3186 // * the instance. For example, a <code>Calendar</code> for the 3187 // * Gregorian calendar system returns 28 for the 3188 // * <code>DAY_OF_MONTH</code> field, because the 28th is the last 3189 // * day of the shortest month of this calendar, February in a 3190 // * common year. 3191 // * 3192 // * @param field the calendar field. 3193 // * @return the lowest maximum value for the given calendar field. 3194 // * @see #getMinimum(int) 3195 // * @see #getMaximum(int) 3196 // * @see #getGreatestMinimum(int) 3197 // * @see #getActualMinimum(int) 3198 // * @see #getActualMaximum(int) 3199 // */ 3200 // abstract int getLeastMaximum(int field); 3201 3202 // /** 3203 // * Returns the minimum value that the specified calendar field 3204 // * could have, given the time value of this <code>Calendar</code>. 3205 // * 3206 // * <p>The default implementation of this method uses an iterative 3207 // * algorithm to determine the actual minimum value for the 3208 // * calendar field. Subclasses should, if possible, override this 3209 // * with a more efficient implementation - in many cases, they can 3210 // * simply return <code>getMinimum()</code>. 3211 // * 3212 // * @param field the calendar field 3213 // * @return the minimum of the given calendar field for the time 3214 // * value of this <code>Calendar</code> 3215 // * @see #getMinimum(int) 3216 // * @see #getMaximum(int) 3217 // * @see #getGreatestMinimum(int) 3218 // * @see #getLeastMaximum(int) 3219 // * @see #getActualMaximum(int) 3220 // * @since 1.2 3221 // */ 3222 // int getActualMinimum(int field) { 3223 // int fieldValue = getGreatestMinimum(field); 3224 // int endValue = getMinimum(field); 3225 3226 // // if we know that the minimum value is always the same, just return it 3227 // if (fieldValue == endValue) { 3228 // return fieldValue; 3229 // } 3230 3231 // // clone the calendar so we don't mess with the real one, and set it to 3232 // // accept anything for the field values 3233 // Calendar work = (Calendar)this.clone(); 3234 // work.setLenient(true); 3235 3236 // // now try each value from getLeastMaximum() to getMaximum() one by one until 3237 // // we get a value that normalizes to another value. The last value that 3238 // // normalizes to itself is the actual minimum for the current date 3239 // int result = fieldValue; 3240 3241 // do { 3242 // work.set(field, fieldValue); 3243 // if (work.get(field) != fieldValue) { 3244 // break; 3245 // } else { 3246 // result = fieldValue; 3247 // fieldValue--; 3248 // } 3249 // } while (fieldValue >= endValue); 3250 3251 // return result; 3252 // } 3253 3254 // /** 3255 // * Returns the maximum value that the specified calendar field 3256 // * could have, given the time value of this 3257 // * <code>Calendar</code>. For example, the actual maximum value of 3258 // * the <code>MONTH</code> field is 12 in some years, and 13 in 3259 // * other years in the Hebrew calendar system. 3260 // * 3261 // * <p>The default implementation of this method uses an iterative 3262 // * algorithm to determine the actual maximum value for the 3263 // * calendar field. Subclasses should, if possible, override this 3264 // * with a more efficient implementation. 3265 // * 3266 // * @param field the calendar field 3267 // * @return the maximum of the given calendar field for the time 3268 // * value of this <code>Calendar</code> 3269 // * @see #getMinimum(int) 3270 // * @see #getMaximum(int) 3271 // * @see #getGreatestMinimum(int) 3272 // * @see #getLeastMaximum(int) 3273 // * @see #getActualMinimum(int) 3274 // * @since 1.2 3275 // */ 3276 // int getActualMaximum(int field) { 3277 // int fieldValue = getLeastMaximum(field); 3278 // int endValue = getMaximum(field); 3279 3280 // // if we know that the maximum value is always the same, just return it. 3281 // if (fieldValue == endValue) { 3282 // return fieldValue; 3283 // } 3284 3285 // // clone the calendar so we don't mess with the real one, and set it to 3286 // // accept anything for the field values. 3287 // Calendar work = (Calendar)this.clone(); 3288 // work.setLenient(true); 3289 3290 // // if we're counting weeks, set the day of the week to Sunday. We know the 3291 // // last week of a month or year will contain the first day of the week. 3292 // if (field == WEEK_OF_YEAR || field == WEEK_OF_MONTH) { 3293 // work.set(DAY_OF_WEEK, firstDayOfWeek); 3294 // } 3295 3296 // // now try each value from getLeastMaximum() to getMaximum() one by one until 3297 // // we get a value that normalizes to another value. The last value that 3298 // // normalizes to itself is the actual maximum for the current date 3299 // int result = fieldValue; 3300 3301 // do { 3302 // work.set(field, fieldValue); 3303 // if (work.get(field) != fieldValue) { 3304 // break; 3305 // } else { 3306 // result = fieldValue; 3307 // fieldValue++; 3308 // } 3309 // } while (fieldValue <= endValue); 3310 3311 // return result; 3312 // } 3313 3314 // /** 3315 // * Creates and returns a copy of this object. 3316 // * 3317 // * @return a copy of this object. 3318 // */ 3319 // @Override 3320 // Object clone() 3321 // { 3322 // try { 3323 // Calendar other = (Calendar) super.clone(); 3324 3325 // other.fields = new int[FIELD_COUNT]; 3326 // other.isSet = new bool[FIELD_COUNT]; 3327 // other.stamp = new int[FIELD_COUNT]; 3328 // for (int i = 0; i < FIELD_COUNT; i++) { 3329 // other.fields[i] = fields[i]; 3330 // other.stamp[i] = stamp[i]; 3331 // other.isSet[i] = isSet[i]; 3332 // } 3333 // if (!sharedZone) { 3334 // other.zone = (TimeZone) zone.clone(); 3335 // } 3336 // return other; 3337 // } 3338 // catch (CloneNotSupportedException e) { 3339 // // this shouldn't happen, since we are Cloneable 3340 // throw new InternalError(e); 3341 // } 3342 // } 3343 3344 // private enum String[] FIELD_NAME = { 3345 // "ERA", "YEAR", "MONTH", "WEEK_OF_YEAR", "WEEK_OF_MONTH", "DAY_OF_MONTH", 3346 // "DAY_OF_YEAR", "DAY_OF_WEEK", "DAY_OF_WEEK_IN_MONTH", "AM_PM", "HOUR", 3347 // "HOUR_OF_DAY", "MINUTE", "SECOND", "MILLISECOND", "ZONE_OFFSET", 3348 // "DST_OFFSET" 3349 // }; 3350 3351 // /** 3352 // * Returns the name of the specified calendar field. 3353 // * 3354 // * @param field the calendar field 3355 // * @return the calendar field name 3356 // * @exception IndexOutOfBoundsException if <code>field</code> is negative, 3357 // * equal to or greater than {@code FIELD_COUNT}. 3358 // */ 3359 // static String getFieldName(int field) { 3360 // return FIELD_NAME[field]; 3361 // } 3362 3363 // /** 3364 // * Return a string representation of this calendar. This method 3365 // * is intended to be used only for debugging purposes, and the 3366 // * format of the returned string may vary between implementations. 3367 // * The returned string may be empty but may not be <code>null</code>. 3368 // * 3369 // * @return a string representation of this calendar. 3370 // */ 3371 // @Override 3372 // String toString() { 3373 // // NOTE: BuddhistCalendar.toString() interprets the string 3374 // // produced by this method so that the Gregorian year number 3375 // // is substituted by its B.E. year value. It relies on 3376 // // "...,YEAR=<year>,..." or "...,YEAR=?,...". 3377 // StringBuilder buffer = new StringBuilder(800); 3378 // buffer.append(getClass().getName()).append('['); 3379 // appendValue(buffer, "time", isTimeSet, time); 3380 // buffer.append(",areFieldsSet=").append(areFieldsSet); 3381 // buffer.append(",areAllFieldsSet=").append(areAllFieldsSet); 3382 // buffer.append(",lenient=").append(lenient); 3383 // buffer.append(",zone=").append(zone); 3384 // appendValue(buffer, ",firstDayOfWeek", true, (long) firstDayOfWeek); 3385 // appendValue(buffer, ",minimalDaysInFirstWeek", true, (long) minimalDaysInFirstWeek); 3386 // for (int i = 0; i < FIELD_COUNT; ++i) { 3387 // buffer.append(','); 3388 // appendValue(buffer, FIELD_NAME[i], isSet(i), (long) fields[i]); 3389 // } 3390 // buffer.append(']'); 3391 // return buffer.toString(); 3392 // } 3393 3394 // // =======================privates=============================== 3395 3396 // private static void appendValue(StringBuilder sb, String item, bool valid, long value) { 3397 // sb.append(item).append('='); 3398 // if (valid) { 3399 // sb.append(value); 3400 // } else { 3401 // sb.append('?'); 3402 // } 3403 // } 3404 3405 // /** 3406 // * Both firstDayOfWeek and minimalDaysInFirstWeek are locale-dependent. 3407 // * They are used to figure out the week count for a specific date for 3408 // * a given locale. These must be set when a Calendar is constructed. 3409 // * @param desiredLocale the given locale. 3410 // */ 3411 // private void setWeekCountData(Locale desiredLocale) 3412 // { 3413 // /* try to get the Locale data from the cache */ 3414 // int[] data = cachedLocaleData.get(desiredLocale); 3415 // if (data is null) { /* cache miss */ 3416 // data = new int[2]; 3417 // data[0] = CalendarDataUtility.retrieveFirstDayOfWeek(desiredLocale); 3418 // data[1] = CalendarDataUtility.retrieveMinimalDaysInFirstWeek(desiredLocale); 3419 // cachedLocaleData.putIfAbsent(desiredLocale, data); 3420 // } 3421 // firstDayOfWeek = data[0]; 3422 // minimalDaysInFirstWeek = data[1]; 3423 // } 3424 3425 // /** 3426 // * Recomputes the time and updates the status fields isTimeSet 3427 // * and areFieldsSet. Callers should check isTimeSet and only 3428 // * call this method if isTimeSet is false. 3429 // */ 3430 // private void updateTime() { 3431 // computeTime(); 3432 // // The areFieldsSet and areAllFieldsSet values are no longer 3433 // // controlled here (as of 1.5). 3434 // isTimeSet = true; 3435 // } 3436 3437 // private int compareTo(long t) { 3438 // long thisTime = getMillisOf(this); 3439 // return (thisTime > t) ? 1 : (thisTime == t) ? 0 : -1; 3440 // } 3441 3442 // private static long getMillisOf(Calendar calendar) { 3443 // if (calendar.isTimeSet) { 3444 // return calendar.time; 3445 // } 3446 // Calendar cal = (Calendar) calendar.clone(); 3447 // cal.setLenient(true); 3448 // return cal.getTimeInMillis(); 3449 // } 3450 3451 // /** 3452 // * Adjusts the stamp[] values before nextStamp overflow. nextStamp 3453 // * is set to the next stamp value upon the return. 3454 // */ 3455 // private void adjustStamp() { 3456 // int max = MINIMUM_USER_STAMP; 3457 // int newStamp = MINIMUM_USER_STAMP; 3458 3459 // for (;;) { 3460 // int min = Integer.MAX_VALUE; 3461 // for (int v : stamp) { 3462 // if (v >= newStamp && min > v) { 3463 // min = v; 3464 // } 3465 // if (max < v) { 3466 // max = v; 3467 // } 3468 // } 3469 // if (max != min && min == Integer.MAX_VALUE) { 3470 // break; 3471 // } 3472 // for (int i = 0; i < stamp.length; i++) { 3473 // if (stamp[i] == min) { 3474 // stamp[i] = newStamp; 3475 // } 3476 // } 3477 // newStamp++; 3478 // if (min == max) { 3479 // break; 3480 // } 3481 // } 3482 // nextStamp = newStamp; 3483 // } 3484 3485 // /** 3486 // * Sets the WEEK_OF_MONTH and WEEK_OF_YEAR fields to new values with the 3487 // * new parameter value if they have been calculated internally. 3488 // */ 3489 // private void invalidateWeekFields() 3490 // { 3491 // if (stamp[WEEK_OF_MONTH] != COMPUTED && 3492 // stamp[WEEK_OF_YEAR] != COMPUTED) { 3493 // return; 3494 // } 3495 3496 // // We have to check the new values of these fields after changing 3497 // // firstDayOfWeek and/or minimalDaysInFirstWeek. If the field values 3498 // // have been changed, then set the new values. (4822110) 3499 // Calendar cal = (Calendar) clone(); 3500 // cal.setLenient(true); 3501 // cal.clear(WEEK_OF_MONTH); 3502 // cal.clear(WEEK_OF_YEAR); 3503 3504 // if (stamp[WEEK_OF_MONTH] == COMPUTED) { 3505 // int weekOfMonth = cal.get(WEEK_OF_MONTH); 3506 // if (fields[WEEK_OF_MONTH] != weekOfMonth) { 3507 // fields[WEEK_OF_MONTH] = weekOfMonth; 3508 // } 3509 // } 3510 3511 // if (stamp[WEEK_OF_YEAR] == COMPUTED) { 3512 // int weekOfYear = cal.get(WEEK_OF_YEAR); 3513 // if (fields[WEEK_OF_YEAR] != weekOfYear) { 3514 // fields[WEEK_OF_YEAR] = weekOfYear; 3515 // } 3516 // } 3517 // } 3518 3519 // /** 3520 // * Save the state of this object to a stream (i.e., serialize it). 3521 // * 3522 // * Ideally, <code>Calendar</code> would only write out its state data and 3523 // * the current time, and not write any field data out, such as 3524 // * <code>fields[]</code>, <code>isTimeSet</code>, <code>areFieldsSet</code>, 3525 // * and <code>isSet[]</code>. <code>nextStamp</code> also should not be part 3526 // * of the persistent state. Unfortunately, this didn't happen before JDK 1.1 3527 // * shipped. To be compatible with JDK 1.1, we will always have to write out 3528 // * the field values and state flags. However, <code>nextStamp</code> can be 3529 // * removed from the serialization stream; this will probably happen in the 3530 // * near future. 3531 // */ 3532 // private synchronized void writeObject(ObjectOutputStream stream) 3533 // throws IOException 3534 // { 3535 // // Try to compute the time correctly, for the future (stream 3536 // // version 2) in which we don't write out fields[] or isSet[]. 3537 // if (!isTimeSet) { 3538 // try { 3539 // updateTime(); 3540 // } 3541 // catch (IllegalArgumentException e) {} 3542 // } 3543 3544 // // If this Calendar has a ZoneInfo, save it and set a 3545 // // SimpleTimeZone equivalent (as a single DST schedule) for 3546 // // backward compatibility. 3547 // TimeZone savedZone = null; 3548 // if (zone instanceof ZoneInfo) { 3549 // SimpleTimeZone stz = ((ZoneInfo)zone).getLastRuleInstance(); 3550 // if (stz is null) { 3551 // stz = new SimpleTimeZone(zone.getRawOffset(), zone.getID()); 3552 // } 3553 // savedZone = zone; 3554 // zone = stz; 3555 // } 3556 3557 // // Write out the 1.1 FCS object. 3558 // stream.defaultWriteObject(); 3559 3560 // // Write out the ZoneInfo object 3561 // // 4802409: we write out even if it is null, a temporary workaround 3562 // // the real fix for bug 4844924 in corba-iiop 3563 // stream.writeObject(savedZone); 3564 // if (savedZone !is null) { 3565 // zone = savedZone; 3566 // } 3567 // } 3568 3569 // private static class CalendarAccessControlContext { 3570 // private enum AccessControlContext INSTANCE; 3571 // static { 3572 // RuntimePermission perm = new RuntimePermission("accessClassInPackage.sun.util.calendar"); 3573 // PermissionCollection perms = perm.newPermissionCollection(); 3574 // perms.add(perm); 3575 // INSTANCE = new AccessControlContext(new ProtectionDomain[] { 3576 // new ProtectionDomain(null, perms) 3577 // }); 3578 // } 3579 // private CalendarAccessControlContext() { 3580 // } 3581 // } 3582 3583 // /** 3584 // * Reconstitutes this object from a stream (i.e., deserialize it). 3585 // */ 3586 // private void readObject(ObjectInputStream stream) 3587 // throws IOException, ClassNotFoundException 3588 // { 3589 // const ObjectInputStream input = stream; 3590 // input.defaultReadObject(); 3591 3592 // stamp = new int[FIELD_COUNT]; 3593 3594 // // Starting with version 2 (not implemented yet), we expect that 3595 // // fields[], isSet[], isTimeSet, and areFieldsSet may not be 3596 // // streamed out anymore. We expect 'time' to be correct. 3597 // if (serialVersionOnStream >= 2) 3598 // { 3599 // isTimeSet = true; 3600 // if (fields is null) { 3601 // fields = new int[FIELD_COUNT]; 3602 // } 3603 // if (isSet is null) { 3604 // isSet = new bool[FIELD_COUNT]; 3605 // } 3606 // } 3607 // else if (serialVersionOnStream >= 0) 3608 // { 3609 // for (int i=0; i<FIELD_COUNT; ++i) { 3610 // stamp[i] = isSet[i] ? COMPUTED : UNSET; 3611 // } 3612 // } 3613 3614 // serialVersionOnStream = currentSerialVersion; 3615 3616 // // If there's a ZoneInfo object, use it for zone. 3617 // ZoneInfo zi = null; 3618 // try { 3619 // zi = AccessController.doPrivileged( 3620 // new PrivilegedExceptionAction<>() { 3621 // @Override 3622 // ZoneInfo run() throws Exception { 3623 // return (ZoneInfo) input.readObject(); 3624 // } 3625 // }, 3626 // CalendarAccessControlContext.INSTANCE); 3627 // } catch (PrivilegedActionException pae) { 3628 // Exception e = pae.getException(); 3629 // if (!(e instanceof OptionalDataException)) { 3630 // if (e instanceof RuntimeException) { 3631 // throw (RuntimeException) e; 3632 // } else if (e instanceof IOException) { 3633 // throw (IOException) e; 3634 // } else if (e instanceof ClassNotFoundException) { 3635 // throw (ClassNotFoundException) e; 3636 // } 3637 // throw new RuntimeException(e); 3638 // } 3639 // } 3640 // if (zi !is null) { 3641 // zone = zi; 3642 // } 3643 3644 // // If the deserialized object has a SimpleTimeZone, try to 3645 // // replace it with a ZoneInfo equivalent (as of 1.4) in order 3646 // // to be compatible with the SimpleTimeZone-based 3647 // // implementation as much as possible. 3648 // if (zone instanceof SimpleTimeZone) { 3649 // String id = zone.getID(); 3650 // TimeZone tz = TimeZone.getTimeZone(id); 3651 // if (tz !is null && tz.hasSameRules(zone) && tz.getID().equals(id)) { 3652 // zone = tz; 3653 // } 3654 // } 3655 // } 3656 3657 // /** 3658 // * Converts this object to an {@link Instant}. 3659 // * <p> 3660 // * The conversion creates an {@code Instant} that represents the 3661 // * same point on the time-line as this {@code Calendar}. 3662 // * 3663 // * @return the instant representing the same point on the time-line 3664 // * @since 1.8 3665 // */ 3666 // const Instant toInstant() { 3667 // return Instant.ofEpochMilli(getTimeInMillis()); 3668 // } 3669 }