Exemplo n.º 1
0
  /** Converts UTC as milliseconds to time field values. */
  protected void computeFields() {
    int rawOffset = getTimeZone().getRawOffset();
    long localMillis = time + rawOffset;

    // Check for very extreme values -- millis near Long.MIN_VALUE or
    // Long.MAX_VALUE.  For these values, adding the zone offset can push
    // the millis past MAX_VALUE to MIN_VALUE, or vice versa.  This produces
    // the undesirable effect that the time can wrap around at the ends,
    // yielding, for example, a Date(Long.MAX_VALUE) with a big BC year
    // (should be AD).  Handle this by pinning such values to Long.MIN_VALUE
    // or Long.MAX_VALUE. - liu 8/11/98 CR 4149677
    if (time > 0 && localMillis < 0 && rawOffset > 0) {
      localMillis = Long.MAX_VALUE;
    } else if (time < 0 && localMillis > 0 && rawOffset < 0) {
      localMillis = Long.MIN_VALUE;
    }

    // Time to fields takes the wall millis (Standard or DST).
    timeToFields(localMillis);

    long days = (long) (localMillis / ONE_DAY);
    int millisInDay = (int) (localMillis - (days * ONE_DAY));

    if (millisInDay < 0) millisInDay += ONE_DAY;

    // Call getOffset() to get the TimeZone offset.
    // The millisInDay value must be standard local millis.
    int dstOffset =
        getTimeZone()
                .getOffset(
                    AD,
                    this.fields[YEAR],
                    this.fields[MONTH],
                    this.fields[DATE],
                    this.fields[DAY_OF_WEEK],
                    millisInDay)
            - rawOffset;

    // Adjust our millisInDay for DST, if necessary.
    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.
    this.fields[MILLISECOND] = millisInDay % 1000;
    millisInDay /= 1000;

    this.fields[SECOND] = millisInDay % 60;
    millisInDay /= 60;

    this.fields[MINUTE] = millisInDay % 60;
    millisInDay /= 60;

    this.fields[HOUR_OF_DAY] = millisInDay;
    this.fields[AM_PM] = millisInDay / 12;
    this.fields[HOUR] = millisInDay % 12;
  }