int DateTime::Weeknumber() const { /* We use ISO-8601: Week 1 is the week containing Jan 4th. ISO-8601 also has the odd rule that the last few days of a year may be in week 1 of the following year, and the first few days of a year may actually belong to the previous year. */ int year, month, day; GetDateFromTimeValue( Value(), year, month, day ); for ( int offset = 1; offset >= -1; --offset ) { DateTime startOfYear( year + offset, 1, 4, 0, 0, 0.0 ); int firstweekday = startOfYear.Weekday(); // now we go back firstweekday days. DateTime startOfWeekOne = startOfYear - DayTimeDuration(firstweekday, 0, 0, 0.0); if ( startOfWeekOne <= *this ) { // the number of days passed helps us. DayTimeDuration days = *this - startOfWeekOne; int weeks = days.Days() / 7 + 1; return weeks; } } // this cannot happen actually, so we return zero. return 0; }
/** * Return JD of start of given month/year. * @internal */ int32_t HebrewCalendar::handleComputeMonthStart(int32_t eyear, int32_t month, UBool /*useMonth*/) const { UErrorCode status = U_ZERO_ERROR; // Resolve out-of-range months. This is necessary in order to // obtain the correct year. We correct to // a 12- or 13-month year (add/subtract 12 or 13, depending // on the year) but since we _always_ number from 0..12, and // the leap year determines whether or not month 5 (Adar 1) // is present, we allow 0..12 in any given year. while (month < 0) { month += monthsInYear(--eyear); } // Careful: allow 0..12 in all years while (month > 12) { month -= monthsInYear(eyear++); } int32_t day = startOfYear(eyear, status); if(U_FAILURE(status)) { return 0; } if (month != 0) { if (isLeapYear(eyear)) { day += LEAP_MONTH_START[month][yearType(eyear)]; } else { day += MONTH_START[month][yearType(eyear)]; } } return (int) (day + 347997); }
/** * Subclasses may override this method to compute several fields * specific to each calendar system. These are: * * <ul><li>ERA * <li>YEAR * <li>MONTH * <li>DAY_OF_MONTH * <li>DAY_OF_YEAR * <li>EXTENDED_YEAR</ul> * * Subclasses can refer to the DAY_OF_WEEK and DOW_LOCAL fields, * which will be set when this method is called. Subclasses can * also call the getGregorianXxx() methods to obtain Gregorian * calendar equivalents for the given Julian day. * * <p>In addition, subclasses should compute any subclass-specific * fields, that is, fields from BASE_FIELD_COUNT to * getFieldCount() - 1. * @internal */ void HebrewCalendar::handleComputeFields(int32_t julianDay, UErrorCode &status) { int32_t d = julianDay - 347997; double m = ((d * (double)DAY_PARTS)/ (double) MONTH_PARTS); // Months (approx) int32_t year = (int32_t)( ((19. * m + 234.) / 235.) + 1.); // Years (approx) int32_t ys = startOfYear(year, status); // 1st day of year int32_t dayOfYear = (d - ys); // Because of the postponement rules, it's possible to guess wrong. Fix it. while (dayOfYear < 1) { year--; ys = startOfYear(year, status); dayOfYear = (d - ys); } // Now figure out which month we're in, and the date within that month int32_t type = yearType(year); UBool isLeap = isLeapYear(year); int32_t month = 0; int32_t momax = UPRV_LENGTHOF(MONTH_START); while (month < momax && dayOfYear > ( isLeap ? LEAP_MONTH_START[month][type] : MONTH_START[month][type] ) ) { month++; } if (month >= momax || month<=0) { // TODO: I found dayOfYear could be out of range when // a large value is set to julianDay. I patched startOfYear // to reduce the chace, but it could be still reproduced either // by startOfYear or other places. For now, we check // the month is in valid range to avoid out of array index // access problem here. However, we need to carefully review // the calendar implementation to check the extreme limit of // each calendar field and the code works well for any values // in the valid value range. -yoshito status = U_ILLEGAL_ARGUMENT_ERROR; return; } month--; int dayOfMonth = dayOfYear - (isLeap ? LEAP_MONTH_START[month][type] : MONTH_START[month][type]); internalSet(UCAL_ERA, 0); internalSet(UCAL_YEAR, year); internalSet(UCAL_EXTENDED_YEAR, year); internalSet(UCAL_MONTH, month); internalSet(UCAL_DAY_OF_MONTH, dayOfMonth); internalSet(UCAL_DAY_OF_YEAR, dayOfYear); }
/** * Returns the number of days in the given Hebrew year * @internal */ int32_t HebrewCalendar::handleGetYearLength(int32_t eyear) const { UErrorCode status = U_ZERO_ERROR; return startOfYear(eyear+1, status) - startOfYear(eyear, status); }