Logo Search packages:      
Sourcecode: icu version File versions

void Calendar::computeWeekFields ( UErrorCode ec  )  [private]

Compute the fields WEEK_OF_YEAR, YEAR_WOY, WEEK_OF_MONTH, DAY_OF_WEEK_IN_MONTH, and DOW_LOCAL from EXTENDED_YEAR, YEAR, DAY_OF_WEEK, and DAY_OF_YEAR. The latter fields are computed by the subclass based on the calendar system.

The YEAR_WOY field is computed simplistically. It is equal to YEAR most of the time, but at the year boundary it may be adjusted to YEAR-1 or YEAR+1 to reflect the overlap of a week into an adjacent year. In this case, a simple increment or decrement is performed on YEAR, even though this may yield an invalid YEAR value. For instance, if the YEAR is part of a calendar system with an N-year cycle field CYCLE, then incrementing the YEAR may involve incrementing CYCLE and setting YEAR back to 0 or 1. This is not handled by this code, and in fact cannot be simply handled without having subclasses define an entire parallel set of fields for fields larger than or equal to a year. This additional complexity is not warranted, since the intention of the YEAR_WOY field is to support ISO 8601 notation, so it will typically be used with a proleptic Gregorian calendar, which has no field larger than a year.

Definition at line 1338 of file calendar.cpp.

References fFields, fTime, getFirstDayOfWeek(), getMinimalDaysInFirstWeek(), handleGetYearLength(), U_FAILURE, UCAL_DAY_OF_MONTH, UCAL_DAY_OF_WEEK, UCAL_DAY_OF_WEEK_IN_MONTH, UCAL_DAY_OF_YEAR, UCAL_EXTENDED_YEAR, UCAL_WEEK_OF_MONTH, UCAL_WEEK_OF_YEAR, UCAL_YEAR_WOY, and weekNumber().

Referenced by computeFields().

                                               {
    if(U_FAILURE(ec)) { 
        return;
    }
    int32_t eyear = fFields[UCAL_EXTENDED_YEAR];
    int32_t dayOfWeek = fFields[UCAL_DAY_OF_WEEK];
    int32_t dayOfYear = fFields[UCAL_DAY_OF_YEAR];

    // WEEK_OF_YEAR start
    // Compute the week of the year.  For the Gregorian calendar, valid week
    // numbers run from 1 to 52 or 53, depending on the year, the first day
    // of the week, and the minimal days in the first week.  For other
    // calendars, the valid range may be different -- it depends on the year
    // length.  Days at the start of the year may fall into the last week of
    // the previous year; days at the end of the year may fall into the
    // first week of the next year.  ASSUME that the year length is less than
    // 7000 days.
    int32_t yearOfWeekOfYear = eyear;
    int32_t relDow = (dayOfWeek + 7 - getFirstDayOfWeek()) % 7; // 0..6
    int32_t relDowJan1 = (dayOfWeek - dayOfYear + 7001 - getFirstDayOfWeek()) % 7; // 0..6
    int32_t woy = (dayOfYear - 1 + relDowJan1) / 7; // 0..53
    if ((7 - relDowJan1) >= getMinimalDaysInFirstWeek()) {
        ++woy;
    }

    // Adjust for weeks at the year end that overlap into the previous or
    // next calendar year.
    if (woy == 0) {
        // We are the last week of the previous year.
        // Check to see if we are in the last week; if so, we need
        // to handle the case in which we are the first week of the
        // next year.

        int32_t prevDoy = dayOfYear + handleGetYearLength(eyear - 1);
        woy = weekNumber(prevDoy, dayOfWeek);
        yearOfWeekOfYear--;
    } else {
        int32_t lastDoy = handleGetYearLength(eyear);
        // Fast check: For it to be week 1 of the next year, the DOY
        // must be on or after L-5, where L is yearLength(), then it
        // cannot possibly be week 1 of the next year:
        //          L-5                  L
        // doy: 359 360 361 362 363 364 365 001
        // dow:      1   2   3   4   5   6   7
        if (dayOfYear >= (lastDoy - 5)) {
            int32_t lastRelDow = (relDow + lastDoy - dayOfYear) % 7;
            if (lastRelDow < 0) {
                lastRelDow += 7;
            }
            if (((6 - lastRelDow) >= getMinimalDaysInFirstWeek()) &&
                ((dayOfYear + 7 - relDow) > lastDoy)) {
                    woy = 1;
                    yearOfWeekOfYear++;
                }
        }
    }
    fFields[UCAL_WEEK_OF_YEAR] = woy;
    fFields[UCAL_YEAR_WOY] = yearOfWeekOfYear;
    // WEEK_OF_YEAR end

    int32_t dayOfMonth = fFields[UCAL_DAY_OF_MONTH];
    fFields[UCAL_WEEK_OF_MONTH] = weekNumber(dayOfMonth, dayOfWeek);
    fFields[UCAL_DAY_OF_WEEK_IN_MONTH] = (dayOfMonth-1) / 7 + 1;
#if defined (U_DEBUG_CAL)
    if(fFields[UCAL_DAY_OF_WEEK_IN_MONTH]==0) fprintf(stderr, "%s:%d: DOWIM %d on %g\n", 
        __FILE__, __LINE__,fFields[UCAL_DAY_OF_WEEK_IN_MONTH], fTime);
#endif
}


Generated by  Doxygen 1.6.0   Back to index