Subclasses may override this. This method calls handleGetMonthLength() to obtain the calendar-specific month length.
For internal use only.
Reimplemented in GregorianCalendar. Definition at line 2559 of file calendar.cpp. References FALSE, Calendar::fStamp, Calendar::getDefaultDayInMonth(), Calendar::getDefaultMonthInYear(), Calendar::getFirstDayOfWeek(), Calendar::getLeastMaximum(), Calendar::getLocalDOW(), Calendar::getMinimalDaysInFirstWeek(), Calendar::handleComputeMonthStart(), Calendar::handleGetExtendedYear(), Calendar::handleGetMonthLength(), Calendar::internalGet(), Calendar::internalSet(), Calendar::isSet(), Calendar::julianDayToDayOfWeek(), Calendar::kYearPrecedence, Calendar::resolveFields(), UCAL_DAY_OF_MONTH, UCAL_DAY_OF_WEEK_IN_MONTH, UCAL_DAY_OF_YEAR, UCAL_EXTENDED_YEAR, UCAL_JANUARY, UCAL_MONTH, UCAL_WEEK_OF_MONTH, UCAL_WEEK_OF_YEAR, and UCAL_YEAR_WOY. Referenced by Calendar::computeJulianDay(), and GregorianCalendar::handleComputeJulianDay(). { UBool useMonth = (bestField == UCAL_DAY_OF_MONTH || bestField == UCAL_WEEK_OF_MONTH || bestField == UCAL_DAY_OF_WEEK_IN_MONTH); int32_t year; if (bestField == UCAL_WEEK_OF_YEAR) { year = internalGet(UCAL_YEAR_WOY, handleGetExtendedYear()); internalSet(UCAL_EXTENDED_YEAR, year); } else { year = handleGetExtendedYear(); internalSet(UCAL_EXTENDED_YEAR, year); } #if defined (U_DEBUG_CAL) fprintf(stderr, "%s:%d: bestField= %s - y=%d\n", __FILE__, __LINE__, fldName(bestField), year); #endif // Get the Julian day of the day BEFORE the start of this year. // If useMonth is true, get the day before the start of the month. // give calendar subclass a chance to have a default 'first' month int32_t month; if(isSet(UCAL_MONTH)) { month = internalGet(UCAL_MONTH); } else { month = getDefaultMonthInYear(year); } int32_t julianDay = handleComputeMonthStart(year, useMonth ? month : 0, useMonth); if (bestField == UCAL_DAY_OF_MONTH) { // give calendar subclass a chance to have a default 'first' dom int32_t dayOfMonth; if(isSet(UCAL_DAY_OF_MONTH)) { dayOfMonth = internalGet(UCAL_DAY_OF_MONTH,1); } else { dayOfMonth = getDefaultDayInMonth(year, month); } return julianDay + dayOfMonth; } if (bestField == UCAL_DAY_OF_YEAR) { return julianDay + internalGet(UCAL_DAY_OF_YEAR); } int32_t firstDayOfWeek = getFirstDayOfWeek(); // Localized fdw // 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). (or it is before the month we are in, if useMonth is True) // At this point we need to process the WEEK_OF_MONTH or // WEEK_OF_YEAR, which are similar, or the DAY_OF_WEEK_IN_MONTH. // First, perform initial shared computations. These locate the // first week of the period. // Get the 0-based localized DOW of day one of the month or year. // Valid range 0..6. int32_t first = julianDayToDayOfWeek(julianDay + 1) - firstDayOfWeek; if (first < 0) { first += 7; } int32_t dowLocal = getLocalDOW(); // Find the first target DOW (dowLocal) in the month or year. // Actually, it may be just before the first of the month or year. // It will be an integer from -5..7. int32_t date = 1 - first + dowLocal; if (bestField == UCAL_DAY_OF_WEEK_IN_MONTH) { // Adjust the target DOW to be in the month or year. if (date < 1) { date += 7; } // The only trickiness occurs if the day-of-week-in-month is // negative. int32_t dim = internalGet(UCAL_DAY_OF_WEEK_IN_MONTH, 1); if (dim >= 0) { date += 7*(dim - 1); } else { // Move date to the last of this day-of-week in this month, // then back up as needed. If dim==-1, we don't back up at // all. If dim==-2, we back up once, etc. Don't back up // past the first of the given day-of-week in this month. // Note that we handle -2, -3, etc. correctly, even though // values < -1 are technically disallowed. int32_t m = internalGet(UCAL_MONTH, UCAL_JANUARY); int32_t monthLength = handleGetMonthLength(year, m); date += ((monthLength - date) / 7 + dim + 1) * 7; } } else { #if defined (U_DEBUG_CAL) fprintf(stderr, "%s:%d - bf= %s\n", __FILE__, __LINE__, fldName(bestField)); #endif if(bestField == UCAL_WEEK_OF_YEAR) { // ------------------------------------- WOY ------------- if(!isSet(UCAL_YEAR_WOY) || // YWOY not set at all or ( (resolveFields(kYearPrecedence) != UCAL_YEAR_WOY) // YWOY doesn't have precedence && (fStamp[UCAL_YEAR_WOY]!=kInternallySet) ) ) // (excluding where all fields are internally set - then YWOY is used) { // need to be sure to stay in 'real' year. int32_t woy = internalGet(bestField); int32_t nextJulianDay = handleComputeMonthStart(year+1, 0, FALSE); // jd of day before jan 1 int32_t nextFirst = julianDayToDayOfWeek(nextJulianDay + 1) - firstDayOfWeek; if (nextFirst < 0) { // 0..6 ldow of Jan 1 nextFirst += 7; } if(woy==1) { // FIRST WEEK --------------------------------- #if defined (U_DEBUG_CAL) fprintf(stderr, "%s:%d - woy=%d, yp=%d, nj(%d)=%d, nf=%d", __FILE__, __LINE__, internalGet(bestField), resolveFields(kYearPrecedence), year+1, nextJulianDay, nextFirst); fprintf(stderr, " next: %d DFW, min=%d \n", (7-nextFirst), getMinimalDaysInFirstWeek() ); #endif // nextFirst is now the localized DOW of Jan 1 of y-woy+1 if((nextFirst > 0) && // Jan 1 starts on FDOW (7-nextFirst) >= getMinimalDaysInFirstWeek()) // or enough days in the week { // Jan 1 of (yearWoy+1) is in yearWoy+1 - recalculate JD to next year #if defined (U_DEBUG_CAL) fprintf(stderr, "%s:%d - was going to move JD from %d to %d [d%d]\n", __FILE__, __LINE__, julianDay, nextJulianDay, (nextJulianDay-julianDay)); #endif julianDay = nextJulianDay; // recalculate 'first' [0-based local dow of jan 1] first = julianDayToDayOfWeek(julianDay + 1) - firstDayOfWeek; if (first < 0) { first += 7; } // recalculate date. date = 1 - first + dowLocal; } } else if(woy>=getLeastMaximum(bestField)) { // could be in the last week- find out if this JD would overstep int32_t testDate = date; if ((7 - first) < getMinimalDaysInFirstWeek()) { testDate += 7; } // Now adjust for the week number. testDate += 7 * (woy - 1); #if defined (U_DEBUG_CAL) fprintf(stderr, "%s:%d - y=%d, y-1=%d doy%d, njd%d (C.F. %d)\n", __FILE__, __LINE__, year, year-1, testDate, julianDay+testDate, nextJulianDay); #endif if(julianDay+testDate > nextJulianDay) { // is it past Dec 31? (nextJulianDay is day BEFORE year+1's Jan 1) // Fire up the calculating engines.. retry YWOY = (year-1) julianDay = handleComputeMonthStart(year-1, 0, FALSE); // jd before Jan 1 of previous year first = julianDayToDayOfWeek(julianDay + 1) - firstDayOfWeek; // 0 based local dow of first week if(first < 0) { // 0..6 first += 7; } date = 1 - first + dowLocal; #if defined (U_DEBUG_CAL) fprintf(stderr, "%s:%d - date now %d, jd%d, ywoy%d\n", __FILE__, __LINE__, date, julianDay, year-1); #endif } /* correction needed */ } /* leastmaximum */ } /* resolvefields(year) != year_woy */ } /* bestfield != week_of_year */ // assert(bestField == WEEK_OF_MONTH || bestField == WEEK_OF_YEAR) // Adjust for minimal days in first week if ((7 - first) < getMinimalDaysInFirstWeek()) { date += 7; } // Now adjust for the week number. date += 7 * (internalGet(bestField) - 1); } return julianDay + date; }
|