Example #1
0
/*********************************************************************
 * @fn      osal_ConvertUTCTime
 *
 * @brief   Converts UTCTime to UTCTimeStruct
 *
 * @param   tm - pointer to breakdown struct
 *
 * @param   secTime - number of seconds since 0 hrs, 0 minutes,
 *          0 seconds, on the 1st of January 2000 UTC
 *
 * @return  none
 */
void osal_ConvertUTCTime( UTCTimeStruct *tm, UTCTime secTime )
{
  // calculate the time less than a day - hours, minutes, seconds
  {
    uint32 day = secTime % DAY;
    tm->seconds = day % 60UL;
    tm->minutes = (day % 3600UL) / 60UL;
    tm->hour = day / 3600UL;
  }

  // Fill in the calendar - day, month, year
  {
    uint16 numDays = secTime / DAY;
    tm->year = BEGYEAR;
    while ( numDays >= YearLength( tm->year ) )
    {
      numDays -= YearLength( tm->year );
      tm->year++;
    }

    tm->month = 0;
    while ( numDays >= monthLength( IsLeapYear( tm->year ), tm->month ) )
    {
      numDays -= monthLength( IsLeapYear( tm->year ), tm->month );
      tm->month++;
    }

    tm->day = numDays;
  }
}
Example #2
0
/*********************************************************************
 * @fn      osal_ConvertUTCSecs
 *
 * @brief   Converts a UTCTimeStruct to UTCTime
 *
 * @param   tm - pointer to provided struct
 *
 * @return  number of seconds since 00:00:00 on 01/01/2000 (UTC)
 */
UTCTime osal_ConvertUTCSecs(UTCTimeStruct *tm)
{
	uint32 seconds;

	/* Seconds for the partial day */
	seconds = (((tm->hour * 60UL) + tm->minutes) * 60UL) + tm->seconds;

	/* Account for previous complete days */
	{
		/* Start with complete days in current month */
		uint16	days = tm->day;

		/* Next, complete months in current year */
		{
			int8	month = tm->month;
//			while (--month >= 0) {		// modify by xyz - 2014.10.31
			while (--month > 0) {
				days += monthLength(IsLeapYear(tm->year), month);
			}
		}

		/* Next, complete years before current year */
		{
			uint16	year = tm->year;
			while (--year >= BEGYEAR) {
				days += YearLength(year);
			}
		}

		/* Add total seconds before partial day */
		seconds += (days * DAY);
	}

	return (seconds);
}
Example #3
0
/**
* After adjustments such as add(MONTH), add(YEAR), we don't want the
* month to jump around.  E.g., we don't want Jan 31 + 1 month to go to Mar
* 3, we want it to go to Feb 28.  Adjustments which might run into this
* problem call this method to retain the proper month.
*/
void 
GregorianCalendar::pinDayOfMonth() 
{
    int32_t monthLen = monthLength(internalGet(UCAL_MONTH));
    int32_t dom = internalGet(UCAL_DATE);
    if(dom > monthLen) 
        set(UCAL_DATE, monthLen);
}
int32_t Grego::dayOfWeekInMonth(int32_t year, int32_t month, int32_t dom) {
    int32_t weekInMonth = (dom + 6)/7;
    if (weekInMonth == 4) {
        if (dom + 7 > monthLength(year, month)) {
            weekInMonth = -1;
        }
    } else if (weekInMonth == 5) {
        weekInMonth = -1;
    }
    return weekInMonth;
}
Example #5
0
    Date::Date(Day d, Month m, Year y) {
        QL_REQUIRE(y > 1900 && y < 2200,
                   "year " << y << " out of bound. It must be in [1901,2199]");
        QL_REQUIRE(Integer(m) > 0 && Integer(m) < 13,
                   "month " << Integer(m)
                   << " outside January-December range [1,12]");

        bool leap = isLeap(y);
        Day len = monthLength(m,leap), offset = monthOffset(m,leap);
        QL_REQUIRE(d <= len && d > 0,
                   "day outside month (" << Integer(m) << ") day-range "
                   << "[1," << len << "]");

        serialNumber_ = d + offset + yearOffset(y);
    }
Example #6
0
    Date Date::advance(const Date& date, Integer n, TimeUnit units) {
        switch (units) {
          case Days:
            return date + n;
          case Weeks:
            return date + 7*n;
          case Months: {
            Day d = date.dayOfMonth();
            Integer m = Integer(date.month())+n;
            Year y = date.year();
            while (m > 12) {
                m -= 12;
                y += 1;
            }
            while (m < 1) {
                m += 12;
                y -= 1;
            }

            QL_ENSURE(y >= 1900 && y <= 2199,
                      "year " << y << " out of bounds. "
                      << "It must be in [1901,2199]");

            Integer length = monthLength(Month(m), isLeap(y));
            if (d > length)
                d = length;

            return Date(d, Month(m), y);
          }
          case Years: {
              Day d = date.dayOfMonth();
              Month m = date.month();
              Year y = date.year()+n;

              QL_ENSURE(y >= 1900 && y <= 2199,
                        "year " << y << " out of bounds. "
                        << "It must be in [1901,2199]");

              if (d == 29 && m == February && !isLeap(y))
                  d = 28;

              return Date(d,m,y);
          }
          default:
            QL_FAIL("undefined time units");
        }
    }
Example #7
0
 TimeFrame::TimeFrame()
 {
   int i = 0,j = 0;
   for(int I = 1; I <= 12;I++)
   {
     int dim = monthLength(I);
     for(int J = 1;J<=dim;J++)
     {
       j++;
       for(int K=1;K<=24;K++)
       {
         assert(i < TIMESLICES);
         Hour[i] = K;
         Day[i] = J;
         Month[i] = I;
         YTD[i++] = j;
       }
     }
   }
 }
Example #8
0
UBool
GregorianCalendar::validateFields() const
{
    for (int32_t field = 0; field < UCAL_FIELD_COUNT; field++) {
        // Ignore DATE and DAY_OF_YEAR which are handled below
        if (field != UCAL_DATE &&
            field != UCAL_DAY_OF_YEAR &&
            isSet((UCalendarDateFields)field) &&
            ! boundsCheck(internalGet((UCalendarDateFields)field), (UCalendarDateFields)field))
            return FALSE;
    }

    // Values differ in Least-Maximum and Maximum should be handled
    // specially.
    if (isSet(UCAL_DATE)) {
        int32_t date = internalGet(UCAL_DATE);
        if (date < getMinimum(UCAL_DATE) ||
            date > monthLength(internalGet(UCAL_MONTH))) {
                return FALSE;
            }
    }

    if (isSet(UCAL_DAY_OF_YEAR)) {
        int32_t days = internalGet(UCAL_DAY_OF_YEAR);
        if (days < 1 || days > yearLength()) {
            return FALSE;
        }
    }

    // Handle DAY_OF_WEEK_IN_MONTH, which must not have the value zero.
    // We've checked against minimum and maximum above already.
    if (isSet(UCAL_DAY_OF_WEEK_IN_MONTH) &&
        0 == internalGet(UCAL_DAY_OF_WEEK_IN_MONTH)) {
            return FALSE;
        }

        return TRUE;
}
Example #9
0
void
GregorianCalendar::roll(UCalendarDateFields field, int32_t amount, UErrorCode& status)
{
    if((amount == 0) || U_FAILURE(status)) {
        return;
    }

    // J81 processing. (gregorian cutover)
    UBool inCutoverMonth = FALSE;
    int32_t cMonthLen=0; // 'c' for cutover; in days
    int32_t cDayOfMonth=0; // no discontinuity: [0, cMonthLen)
    double cMonthStart=0.0; // in ms

    // Common code - see if we're in the cutover month of the cutover year
    if(get(UCAL_EXTENDED_YEAR, status) == fGregorianCutoverYear) {
        switch (field) {
        case UCAL_DAY_OF_MONTH:
        case UCAL_WEEK_OF_MONTH:
            {
                int32_t max = monthLength(internalGet(UCAL_MONTH));
                UDate t = internalGetTime();
                // We subtract 1 from the DAY_OF_MONTH to make it zero-based, and an
                // additional 10 if we are after the cutover. Thus the monthStart
                // value will be correct iff we actually are in the cutover month.
                cDayOfMonth = internalGet(UCAL_DAY_OF_MONTH) - ((t >= fGregorianCutover) ? 10 : 0);
                cMonthStart = t - ((cDayOfMonth - 1) * kOneDay);
                // A month containing the cutover is 10 days shorter.
                if ((cMonthStart < fGregorianCutover) &&
                    (cMonthStart + (cMonthLen=(max-10))*kOneDay >= fGregorianCutover)) {
                        inCutoverMonth = TRUE;
                    }
            }
        default:
            ;
        }
    }

    switch (field) {
    case UCAL_WEEK_OF_YEAR: {
        // Unlike WEEK_OF_MONTH, WEEK_OF_YEAR never shifts the day of the
        // week.  Also, rolling the week of the year can have seemingly
        // strange effects simply because the year of the week of year
        // may be different from the calendar year.  For example, the
        // date Dec 28, 1997 is the first day of week 1 of 1998 (if
        // weeks start on Sunday and the minimal days in first week is
        // <= 3).
        int32_t woy = get(UCAL_WEEK_OF_YEAR, status);
        // Get the ISO year, which matches the week of year.  This
        // may be one year before or after the calendar year.
        int32_t isoYear = get(UCAL_YEAR_WOY, status);
        int32_t isoDoy = internalGet(UCAL_DAY_OF_YEAR);
        if (internalGet(UCAL_MONTH) == UCAL_JANUARY) {
            if (woy >= 52) {
                isoDoy += handleGetYearLength(isoYear);
            }
        } else {
            if (woy == 1) {
                isoDoy -= handleGetYearLength(isoYear - 1);
            }
        }
        woy += amount;
        // Do fast checks to avoid unnecessary computation:
        if (woy < 1 || woy > 52) {
            // Determine the last week of the ISO year.
            // We do this using the standard formula we use
            // everywhere in this file.  If we can see that the
            // days at the end of the year are going to fall into
            // week 1 of the next year, we drop the last week by
            // subtracting 7 from the last day of the year.
            int32_t lastDoy = handleGetYearLength(isoYear);
            int32_t lastRelDow = (lastDoy - isoDoy + internalGet(UCAL_DAY_OF_WEEK) -
                getFirstDayOfWeek()) % 7;
            if (lastRelDow < 0) lastRelDow += 7;
            if ((6 - lastRelDow) >= getMinimalDaysInFirstWeek()) lastDoy -= 7;
            int32_t lastWoy = weekNumber(lastDoy, lastRelDow + 1);
            woy = ((woy + lastWoy - 1) % lastWoy) + 1;
        }
        set(UCAL_WEEK_OF_YEAR, woy);
        set(UCAL_YEAR_WOY,isoYear);
        return;
                            }

    case UCAL_DAY_OF_MONTH:
        if( !inCutoverMonth ) { 
            Calendar::roll(field, amount, status);
            return;
        } else {
            // [j81] 1582 special case for DOM
            // The default computation works except when the current month
            // contains the Gregorian cutover.  We handle this special case
            // here.  [j81 - aliu]
            double monthLen = cMonthLen * kOneDay;
            double msIntoMonth = uprv_fmod(internalGetTime() - cMonthStart +
                amount * kOneDay, monthLen);
            if (msIntoMonth < 0) {
                msIntoMonth += monthLen;
            }
#if defined (U_DEBUG_CAL)
            fprintf(stderr, "%s:%d: roll DOM %d  -> %.0lf ms  \n", 
                __FILE__, __LINE__,amount, cMonthLen, cMonthStart+msIntoMonth);
#endif
            setTimeInMillis(cMonthStart + msIntoMonth, status);
            return;
        }

    case UCAL_WEEK_OF_MONTH:
        if( !inCutoverMonth ) { 
            Calendar::roll(field, amount, status);
            return;
        } else {
#if defined (U_DEBUG_CAL)
            fprintf(stderr, "%s:%d: roll WOM %d ??????????????????? \n", 
                __FILE__, __LINE__,amount);
#endif
            // NOTE: following copied from  the old
            //     GregorianCalendar::roll( WEEK_OF_MONTH )  code 

            // This is tricky, because during the roll we may have to shift
            // to a different day of the week.  For example:

            //    s  m  t  w  r  f  s
            //          1  2  3  4  5
            //    6  7  8  9 10 11 12

            // When rolling from the 6th or 7th back one week, we go to the
            // 1st (assuming that the first partial week counts).  The same
            // thing happens at the end of the month.

            // The other tricky thing is that we have to figure out whether
            // the first partial week actually counts or not, based on the
            // minimal first days in the week.  And we have to use the
            // correct first day of the week to delineate the week
            // boundaries.

            // Here's our algorithm.  First, we find the real boundaries of
            // the month.  Then we discard the first partial week if it
            // doesn't count in this locale.  Then we fill in the ends with
            // phantom days, so that the first partial week and the last
            // partial week are full weeks.  We then have a nice square
            // block of weeks.  We do the usual rolling within this block,
            // as is done elsewhere in this method.  If we wind up on one of
            // the phantom days that we added, we recognize this and pin to
            // the first or the last day of the month.  Easy, eh?

            // Another wrinkle: To fix jitterbug 81, we have to make all this
            // work in the oddball month containing the Gregorian cutover.
            // This month is 10 days shorter than usual, and also contains
            // a discontinuity in the days; e.g., the default cutover month
            // is Oct 1582, and goes from day of month 4 to day of month 15.

            // Normalize the DAY_OF_WEEK so that 0 is the first day of the week
            // in this locale.  We have dow in 0..6.
            int32_t dow = internalGet(UCAL_DAY_OF_WEEK) - getFirstDayOfWeek();
            if (dow < 0) 
                dow += 7;

            // Find the day of month, compensating for cutover discontinuity.
            int32_t dom = cDayOfMonth;

            // Find the day of the week (normalized for locale) for the first
            // of the month.
            int32_t fdm = (dow - dom + 1) % 7;
            if (fdm < 0) 
                fdm += 7;

            // Get the first day of the first full week of the month,
            // including phantom days, if any.  Figure out if the first week
            // counts or not; if it counts, then fill in phantom days.  If
            // not, advance to the first real full week (skip the partial week).
            int32_t start;
            if ((7 - fdm) < getMinimalDaysInFirstWeek())
                start = 8 - fdm; // Skip the first partial week
            else
                start = 1 - fdm; // This may be zero or negative

            // Get the day of the week (normalized for locale) for the last
            // day of the month.
            int32_t monthLen = cMonthLen;
            int32_t ldm = (monthLen - dom + dow) % 7;
            // We know monthLen >= DAY_OF_MONTH so we skip the += 7 step here.

            // Get the limit day for the blocked-off rectangular month; that
            // is, the day which is one past the last day of the month,
            // after the month has already been filled in with phantom days
            // to fill out the last week.  This day has a normalized DOW of 0.
            int32_t limit = monthLen + 7 - ldm;

            // Now roll between start and (limit - 1).
            int32_t gap = limit - start;
            int32_t newDom = (dom + amount*7 - start) % gap;
            if (newDom < 0) 
                newDom += gap;
            newDom += start;

            // Finally, pin to the real start and end of the month.
            if (newDom < 1) 
                newDom = 1;
            if (newDom > monthLen) 
                newDom = monthLen;

            // Set the DAY_OF_MONTH.  We rely on the fact that this field
            // takes precedence over everything else (since all other fields
            // are also set at this point).  If this fact changes (if the
            // disambiguation algorithm changes) then we will have to unset
            // the appropriate fields here so that DAY_OF_MONTH is attended
            // to.

            // If we are in the cutover month, manipulate ms directly.  Don't do
            // this in general because it doesn't work across DST boundaries
            // (details, details).  This takes care of the discontinuity.
            setTimeInMillis(cMonthStart + (newDom-1)*kOneDay, status);                
            return;
        }

    default:
        Calendar::roll(field, amount, status);
        return;
    }
}
Example #10
0
 inline bool Date::isEndOfMonth(const Date& d) {
    return (d.dayOfMonth() == monthLength(d.month(), isLeap(d.year())));
 }
Example #11
0
 inline Date Date::endOfMonth(const Date& d) {
     Month m = d.month();
     Year y = d.year();
     return Date(monthLength(m, isLeap(y)), m, y);
 }