⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 calendar.java

📁 已经移植好的java虚拟机
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
    millisInDay += dstOffset;    // If DST has pushed us into the next day, we must call timeToFields() again.    // This happens in DST between 12:00 am and 1:00 am every day.  The call to    // timeToFields() will give the wrong day, since the Standard time is in the    // previous day.    if (millisInDay >= ONE_DAY) {      long dstMillis = localMillis + dstOffset;      millisInDay -= ONE_DAY;      // As above, check for and pin extreme values      if (localMillis > 0 && dstMillis < 0 && dstOffset > 0) {        dstMillis = Long.MAX_VALUE;      } else if (localMillis < 0 && dstMillis > 0 && dstOffset < 0) {        dstMillis = Long.MIN_VALUE;      }      timeToFields(dstMillis);    }    // Fill in all time-related fields based on millisInDay.    // so as not to perturb flags.    packed_time = (packed_time & (~1023)) | (millisInDay % 1000);    millisInDay /= 1000;    packed_time = (packed_time & (~(63<<10))) | ((millisInDay % 60) << 10);    millisInDay /= 60;    packed_time = (packed_time & (~(63<<16))) | ((millisInDay % 60) << 16);    millisInDay /= 60;    packed_time = (packed_time & (~(31<<22))) | ((millisInDay & 31) << 22);  }  /**   * Convert the time as milliseconds to the date fields.  Millis must be   * given as local wall millis to get the correct local day.  For example,   * if it is 11:30 pm Standard, and DST is in effect, the correct DST millis   * must be passed in to get the right date.   * <p>   * Fields that are completed by this method: YEAR, MONTH, DATE, DAY_OF_WEEK.   * @param theTime the time in wall millis (either Standard or DST),   * whichever is in effect   * @param quick if true, only compute the YEAR, MONTH, DATE, and DAY_OF_WEEK.   */  private final void timeToFields(long theTime) {    int dayOfYear, weekCount, year_field;    boolean isLeap;    // Compute the year, month, and day of month from the given millis    if (theTime >= gregorianCutover) {      // The Gregorian epoch day is zero for Monday January 1, year 1.      long gregorianEpochDay = millisToJulianDay(theTime) - JAN_1_1_JULIAN_DAY;      // Here we convert from the day number to the multiple radix      // representation.  We use 400-year, 100-year, and 4-year cycles.      // For example, the 4-year cycle has 4 years + 1 leap day; giving      // 1461 == 365*4 + 1 days.      int[] rem = new int[1];      int n400 = floorDivide(gregorianEpochDay, 146097, rem); // 400-year cycle length      int n100 = floorDivide(rem[0], 36524, rem); // 100-year cycle length      int n4 = floorDivide(rem[0], 1461, rem); // 4-year cycle length      int n1 = floorDivide(rem[0], 365, rem);      year_field = 400*n400 + 100*n100 + 4*n4 + n1;      dayOfYear = rem[0]; // zero-based day of year      if (n100 == 4 || n1 == 4) dayOfYear = 365; // Dec 31 at end of 4- or 400-yr cycle      else ++year_field;      isLeap = ((year_field&0x3) == 0) && // equiv. to (year_field%4 == 0)        (year_field%100 != 0 || year_field%400 == 0);      // Gregorian day zero is a Monday      day_field = (int)((gregorianEpochDay+1) % 7);    }    else {      // The Julian epoch day (not the same as Julian Day)      // is zero on Saturday December 30, 0 (Gregorian).      long julianEpochDay = millisToJulianDay(theTime) - (JAN_1_1_JULIAN_DAY - 2);      year_field = (int) floorDivide(4*julianEpochDay + 1464, 1461);      // Compute the Julian calendar day number for January 1, year      long january1 = 365*(year_field-1) + floorDivide(year_field-1, 4);      dayOfYear = (int)(julianEpochDay - january1); // 0-based      // Julian leap years occurred historically every 4 years starting      // with 8 AD.  Before 8 AD the spacing is irregular; every 3 years      // from 45 BC to 9 BC, and then none until 8 AD.  However, we don't      // implement this historical detail; instead, we implement the      // computationally cleaner proleptic calendar, which assumes      // consistent 4-year cycles throughout time.      isLeap = ((year_field&0x3) == 0); // equiv. to (year_field%4 == 0)      // Julian calendar day zero is a Saturday      day_field = (int)((julianEpochDay-1) % 7);    }    // Common Julian/Gregorian calculation    int correction = 0;    int march1 = isLeap ? 60 : 59; // zero-based DOY for March 1    if (dayOfYear >= march1) correction = isLeap ? 1 : 2;    int month_field = (12 * (dayOfYear + correction) + 6) / 367; // zero-based month    int date_field = dayOfYear -      (isLeap ? LEAP_NUM_DAYS[month_field] : NUM_DAYS[month_field]) + 1; // one-based DOM    // Normalize day of week    day_field += (day_field < 0) ? (SUNDAY+7) : SUNDAY;    month_field += JANUARY; // 0-based    packed_date =  year_field << 9;    packed_date |= (month_field & 15) << 5;    packed_date |= date_field & 31;  }  /////////////////////////////  // Fields => Time computation  /////////////////////////////  /**   * Converts time field values to UTC as milliseconds.   * @exception IllegalArgumentException if any fields are invalid.   */  private void calculateTime() {    // This function takes advantage of the fact that unset fields in    // the time field list have a value of zero.    // First, use the year to determine whether to use the Gregorian or the    // Julian calendar. If the year is not the year of the cutover, this    // computation will be correct. But if the year is the cutover year,    // this may be incorrect. In that case, assume the Gregorian calendar,    // make the computation, and then recompute if the resultant millis    // indicate the wrong calendar has been assumed.    // A date such as Oct. 10, 1582 does not exist in a Gregorian calendar    // with the default changeover of Oct. 15, 1582, since in such a    // calendar Oct. 4 (Julian) is followed by Oct. 15 (Gregorian).  This    // algorithm will interpret such a date using the Julian calendar,    // yielding Oct. 20, 1582 (Gregorian).    int year_field = packed_date >> 9;    boolean isGregorian = year_field >= gregorianCutoverYear;    long julianDay = calculateJulianDay(isGregorian, year_field);    long millis = julianDayToMillis(julianDay);    // The following check handles portions of the cutover year BEFORE the    // cutover itself happens. The check for the julianDate number is for a    // rare case; it's a hardcoded number, but it's efficient.  The given    // Julian day number corresponds to Dec 3, 292269055 BC, which    // corresponds to millis near Long.MIN_VALUE.  The need for the check    // arises because for extremely negative Julian day numbers, the millis    // actually overflow to be positive values. Without the check, the    // initial date is interpreted with the Gregorian calendar, even when    // the cutover doesn't warrant it.    if (isGregorian != (millis >= gregorianCutover) &&        julianDay != -106749550580L) { // See above      julianDay = calculateJulianDay(!isGregorian, year_field);      millis = julianDayToMillis(julianDay);    }    // Do the time portion of the conversion.    int millisInDay = 0;    // Hours    // Don't normalize here; let overflow bump into the next period.    // This is consistent with how we handle other fields.    millisInDay += (packed_time >> 22) & 31;    millisInDay *= 60;    millisInDay += (packed_time >> 16) & 63; // now have minutes    millisInDay *= 60;    millisInDay += (packed_time >> 10) & 63; // now have seconds    millisInDay *= 1000;    millisInDay += packed_time & 1023; // now have millis    // Compute the time zone offset and DST offset.  There are two potential    // ambiguities here.  We'll assume a 2:00 am (wall time) switchover time    // for discussion purposes here.    // 1. The transition into DST.  Here, a designated time of 2:00 am - 2:59 am    //    can be in standard or in DST depending.  However, 2:00 am is an invalid    //    representation (the representation jumps from 1:59:59 am Std to 3:00:00 am DST).    //    We assume standard time.    // 2. The transition out of DST.  Here, a designated time of 1:00 am - 1:59 am    //    can be in standard or DST.  Both are valid representations (the rep    //    jumps from 1:59:59 DST to 1:00:00 Std).    //    Again, we assume standard time.    // We use the TimeZone object to get the zone offset    int zoneOffset = zone.getRawOffset();    // Now add date and millisInDay together, to make millis contain local wall    // millis, with no zone or DST adjustments    millis += millisInDay;    dstOffset = 0;    /* Normalize the millisInDay to 0..ONE_DAY-1.  If the millis is out     * of range, then we must call timeToFields() to recompute our     * fields. */    int[] normalizedMillisInDay = new int[1];    floorDivide(millis, (int)ONE_DAY, normalizedMillisInDay);    // We need to have the month, the day, and the day of the week.    // Calling timeToFields will compute the MONTH and DATE fields.    //    // It's tempting to try to use DAY_OF_WEEK here, if it    // is set, but we CAN'T.  Even if it's set, it might have    // been set wrong by the user.  We should rely only on    // the Julian day number, which has been computed correctly    // using the disambiguation algorithm above. [LIU]    int dow = julianDayToDayOfWeek(julianDay);    // It's tempting to try to use DAY_OF_WEEK here, if it    // is set, but we CAN'T.  Even if it's set, it might have    // been set wrong by the user.  We should rely only on    // the Julian day number, which has been computed correctly    // using the disambiguation algorithm above. [LIU]    dstOffset = zone.getOffset(1,                               packed_date >> 9,                               (packed_date >> 5) & 15,                               packed_date & 31,                               dow,                               normalizedMillisInDay[0]) -      zoneOffset;    dstSet = true;    // Note: Because we pass in wall millisInDay, rather than    // standard millisInDay, we interpret "1:00 am" on the day    // of cessation of DST as "1:00 am Std" (assuming the time    // of cessation is 2:00 am).    // Store our final computed GMT time, with timezone adjustments.    time = millis - zoneOffset - dstOffset;  }  /**   * Compute the Julian day number under either the Gregorian or the   * Julian calendar, using the given year and the remaining fields.   * @param isGregorian if true, use the Gregorian calendar   * @param year the adjusted year number, with 0 indicating the   * year 1 BC, -1 indicating 2 BC, etc.   * @return the Julian day number   */  private final long calculateJulianDay(boolean isGregorian, int year) {    int month = 0, y;    long millis = 0;    month = (packed_date >> 5) & 15 - JANUARY;    // If the month is out of range, adjust it into range    if (month < 0 || month > 11) {      int[] rem = new int[1];      year += floorDivide(month, 12, rem);      month = rem[0];    }    boolean isLeap = year%4 == 0;    y = year - 1;    long julianDay = 365L*y + floorDivide(y, 4) + (JAN_1_1_JULIAN_DAY - 3);    if (isGregorian) {      isLeap = isLeap && ((year%100 != 0) || (year%400 == 0));      // Add 2 because Gregorian calendar starts 2 days after Julian calendar      julianDay += floorDivide(y, 400) - floorDivide(y, 100) + 2;    }    // At this point julianDay is the 0-based day BEFORE the first day of    // January 1, year 1 of the given calendar.  If julianDay == 0, it    // specifies (Jan. 1, 1) - 1, in whatever calendar we are using (Julian    // or Gregorian).    julianDay += isLeap ? LEAP_NUM_DAYS[month] : NUM_DAYS[month];    julianDay += packed_date & 31;    return julianDay;  }  /////////////////  // Implementation  /////////////////  /**   * Converts time as milliseconds to Julian day.   * @param millis the given milliseconds.   * @return the Julian day number.   */  private static final long millisToJulianDay(long millis) {    return EPOCH_JULIAN_DAY + floorDivide(millis, ONE_DAY);  }  /**   * Converts Julian day to time as milliseconds.   * @param julian the given Julian day number.   * @return time as milliseconds.   */  private static final long julianDayToMillis(long julian) {    return (julian - EPOCH_JULIAN_DAY) * ONE_DAY;  }  private static final int julianDayToDayOfWeek(long julian) {    // If julian is negative, then julian%7 will be negative, so we adjust    // accordingly.  We add 1 because Julian day 0 is Monday.    int dayOfWeek = (int)((julian + 1) % 7);    return dayOfWeek + ((dayOfWeek < 0) ? (7 + SUNDAY) : SUNDAY);  }  /**   * Divide two long integers, returning the floor of the quotient.   * <p>   * Unlike the built-in division, this is mathematically well-behaved.   * E.g., <code>-1/4</code> => 0   * but <code>floorDivide(-1,4)</code> => -1.   * @param numerator the numerator   * @param denominator a divisor which must be > 0   * @return the floor of the quotient.   */  private static final long floorDivide(long numerator, long denominator) {    // We do this computation in order to handle    // a numerator of Long.MIN_VALUE correctly    return (numerator >= 0) ?      numerator / denominator :      ((numerator + 1) / denominator) - 1;  }  /**   * Divide two integers, returning the floor of the quotient.   * <p>   * Unlike the built-in division, this is mathematically well-behaved.   * E.g., <code>-1/4</code> => 0   * but <code>floorDivide(-1,4)</code> => -1.   * @param numerator the numerator   * @param denominator a divisor which must be > 0   * @return the floor of the quotient.   */  private static final int floorDivide(int numerator, int denominator) {    // We do this computation in order to handle    // a numerator of Integer.MIN_VALUE correctly    return (numerator >= 0) ?      numerator / denominator :      ((numerator + 1) / denominator) - 1;  }  /**   * Divide two integers, returning the floor of the quotient, and   * the modulus remainder.   * <p>   * Unlike the built-in division, this is mathematically well-behaved.   * E.g., <code>-1/4</code> => 0 and <code>-1%4</code> => -1,   * but <code>floorDivide(-1,4)</code> => -1 with <code>remainder[0]</code> => 3.   * @param numerator the numerator   * @param denominator a divisor which must be > 0   * @param remainder an array of at least one element in which the value   * <code>numerator mod denominator</code> is returned. Unlike <code>numerator   * % denominator</code>, this will always be non-negative.   * @return the floor of the quotient.   */  private static final int floorDivide(int numerator, int denominator, int[] remainder) {    if (numerator >= 0) {      remainder[0] = numerator % denominator;      return numerator / denominator;    }    int quotient = ((numerator + 1) / denominator) - 1;    remainder[0] = numerator - (quotient * denominator);    return quotient;  }  /**   * Divide two integers, returning the floor of the quotient, and   * the modulus remainder.   * <p>   * Unlike the built-in division, this is mathematically well-behaved.   * E.g., <code>-1/4</code> => 0 and <code>-1%4</code> => -1,   * but <code>floorDivide(-1,4)</code> => -1 with <code>remainder[0]</code> => 3.   * @param numerator the numerator   * @param denominator a divisor which must be > 0   * @param remainder an array of at least one element in which the value   * <code>numerator mod denominator</code> is returned. Unlike <code>numerator   * % denominator</code>, this will always be non-negative.   * @return the floor of the quotient.   */  private static final int floorDivide(long numerator, int denominator, int[] remainder) {    if (numerator >= 0) {      remainder[0] = (int)(numerator % denominator);      return (int)(numerator / denominator);    }    int quotient = (int)(((numerator + 1) / denominator) - 1);    remainder[0] = (int)(numerator - (quotient * denominator));    return quotient;  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -