/**---------------------------------------------------------------------------- * PRIVATE Determine the number of days in any given month/year * * @param month Month to be tested * @param year Year to be tested * @return Number of days in month/year */ S32 Time::_daysInMonth(S32 month, S32 year) const { if (_isLeapYear(year)) return _DaysInMonthLeap[month]; else return _DaysInMonth[month]; }
double _TimeFromYearMonth(int y, int m) { static int daysMonth[12] ={ 0,31,59,90,120,151,181,212,243,273,304,334}; static int leapDaysMonth[12] = { 0,31,60,91,121,152,182,213,244,274,305,335}; int* pMonth = daysMonth; if(_isLeapYear(y)) pMonth = leapDaysMonth; return _TimeFromYear(y) + ((double)pMonth[m])*86400000; }
bool Time::set(S32 year, S32 month, S32 day, S32 hour, S32 minute, S32 second, S32 microsecond) { second += microsecond / 100000; microsecond %= 100000; minute += second / 60; second %= 60; hour += minute / 60; minute %= 60; S32 carryDays = hour / 24; hour %= 24; bool leapYear = _isLeapYear(year); year -= 1; // all the next operations need (year-1) so do it ahead of time S32 gregorian = 365 * year // number of days since the epoch + (year/4) // add Julian leap year days - (year/100) // subtract century leap years + (year/400) // add gregorian 400 year leap adjustment + ((367*month-362)/12) // days in prior months + day // add days + carryDays; // add days from time overflow/underflow // make days in this year adjustment if leap year if (leapYear) { if (month > 2) gregorian -= 1; } else { if (month > 2) gregorian -= 2; } _time = S64(gregorian) * OneDay; _time += S64((hour * OneHour) + (minute * OneMinute) + (second * OneSecond) + microsecond); return true; }
int _DateFromTime(double t) { int day = _DayWithinYear(t); int year = _YearFromTime(t); bool leap = _isLeapYear(year); int month = _MonthFromTime(t); switch (month) { case 0: return day+1; case 1: return day-30; case 2: return day-58-leap; case 3: return day-89-leap; case 4: return day-119-leap; case 5: return day-150-leap; case 6: return day-180-leap; case 7: return day-211-leap; case 8: return day-242-leap; case 9: return day-272-leap; case 10: return day-303-leap; case 11: return day-333-leap; default: return 0; } }
int _MonthFromTime(double t) { int day = _DayWithinYear(t); int year = _YearFromTime(t); if(0<=day && day <31) return 0; if(31<=day && day< 59+_isLeapYear(year)) return 1; if((59+_isLeapYear(year))<=day && day<(90+_isLeapYear(year))) return 2; if((90+_isLeapYear(year))<=day && day<(120+_isLeapYear(year))) return 3; if((120+_isLeapYear(year))<=day && day<(151+_isLeapYear(year))) return 4; if((151+_isLeapYear(year))<=day && day<(181+_isLeapYear(year))) return 5; if((181+_isLeapYear(year))<=day && day<(212+_isLeapYear(year))) return 6; if((212+_isLeapYear(year))<=day && day<(243+_isLeapYear(year))) return 7; if((243+_isLeapYear(year))<=day && day<(273+_isLeapYear(year))) return 8; if((273+_isLeapYear(year))<=day && day<(304+_isLeapYear(year))) return 9; if((304+_isLeapYear(year))<=day && day<(334+_isLeapYear(year))) return 10; if((334+_isLeapYear(year))<=day && day<(365+_isLeapYear(year))) return 11; return -1; }
//----------------------------------------------------------------------------- void Time::get(S32 *pyear, S32 *pmonth, S32 *pday, S32 *phour, S32 *pminute, S32 *psecond, S32 *pmicrosecond) const { // extract date if requested if (pyear || pmonth || pday) { S32 gregorian = (S32)(_time / OneDay); S32 prior = gregorian - 1; // prior days S32 years400 = prior / 146097L; // number of 400 year cycles S32 days400 = prior % 146097L; // days NOT in years400 S32 years100 = days400 / 36524L; // number 100 year cycles not checked S32 days100 = days400 % 36524L; // days NOT already included S32 years4 = days100 / 1461L; // number 4 year cycles not checked S32 days4 = days100 % 1461L; // days NOT already included S32 year1 = days4 / 365L; // number years not already checked S32 day1 = days4 % 365L; // days NOT already included S32 day; S32 year = (400 * years400) + (100 * years100) + (4 * years4) + year1; // December 31 of leap year if (years100 == 4 || year1 == 4) { day = 366; } else { year += 1; day = day1 + 1; } const S32 *dayNumber = _isLeapYear(year) ? _DayNumberLeap : _DayNumber; // find month and day in month given computed year and day number, S32 month = 1; while(day >= dayNumber[month]) month++; day -= dayNumber[month-1]; if(pyear) *pyear = year; if(pmonth) *pmonth = month; if(pday) *pday = day; } // extract time if (phour) *phour = (S32)((_time % OneDay) / OneHour); S32 time = (S32)(_time % OneHour); if (pminute) *pminute = time / (S32)OneMinute; time %= OneMinute; if (psecond) *psecond = time / (S32)OneSecond; if (pmicrosecond) *pmicrosecond = time % OneSecond; }
/** * Breaks the passed time_t struct (seconds since the epoch) into a broken-down * time representation in Coordinated Universal Time (UTC) (GMT time). The * passed tm struct will be populated. * * This function is re-entrant and therefore thread-safe. * * @param timep the time_t (seconds since the epoch) to break-down. * @param result the tm to populate with the broken-down date. * * @return a pointer to the result. */ struct tm* gmtime_r(const time_t* timep, struct tm* result) { // the number of seconds per day time_t secsPerDay = 86400; // the number of seconds today time_t secs = *timep % secsPerDay; // the number of whole minutes today time_t mins = secs / 60; // set the number of seconds after the current minute result->tm_sec = secs % 60; // set the number of minutes after the current hour result->tm_min = mins % 60; // set the number of hours past midnight result->tm_hour = mins / 60; // determine the year and the day in the year: // start with the number of whole days since the epoch time_t day = *timep / secsPerDay; time_t daysPerYear = 365; // determine the week day (Jan 1 1970 was a Thursday, so add 4) result->tm_wday = (day + 4) % 7; int* year = &result->tm_year; for(*year = 1970; ; ++(*year)) { // check for leap year daysPerYear = _isLeapYear(*year) ? 366 : 365; if(day >= daysPerYear) { // remove year day -= daysPerYear; } else { // year should be years since 1900 *year -= 1900; break; } } // set the day in the year (days do not begin on 0, so +1) ++day; result->tm_yday = day; // remove extra day from leap years (31 days in Jan + 28 in February = 59) if(_isLeapYear(1900 + *year) && day > 59) { --day; } // determine the month int* month = &result->tm_mon; for(*month = 11; day <= _daysInPreviousMonth[*month]; --(*month)); // determine the day of the month result->tm_mday = day - _daysInPreviousMonth[*month]; // daylight savings time information not available result->tm_isdst = -1; return result; }