Ejemplo n.º 1
0
static void days_since_epoch_into_ymd(
    uint32_t days,
    uint16_t * pYear,
    uint8_t * pMonth,
    uint8_t * pDay)
{
    uint16_t year = 1900;
    uint8_t month = 1;
    uint8_t day = 1;

    while (days >= 365) {
        if ((is_leap_year(year)) && (days == 365))
            break;
        days -= 365;
        if (is_leap_year(year))
            --days;
        year++;
    }

    while (days >= (uint32_t) month_days(year, month)) {
        days -= month_days(year, month);
        month++;
    }

    day = (uint8_t) (day + days);

    if (pYear)
        *pYear = year;
    if (pMonth)
        *pMonth = month;
    if (pDay)
        *pDay = day;

    return;
}
Ejemplo n.º 2
0
/*
 *  add @n months to date
 */
Date& Date::add_month(int n)
{
    if (n) {
	int   mm;
	int   yy;

	yy = n / 12;
	mm = m + n % 12;

	// left n add m great than 12
	if (mm > 12) {
	    yy++;
	    mm -= 12;
	}

	// month first
	m = Month(mm);
	if (d > month_days(m, y))
	    d = month_days(m, y);

	add_year(yy);

	cache->valid = false;
    }

    return *this;
}
Ejemplo n.º 3
0
/* Adjust time T by adding SECONDS.
   The absolute value of SECONDS cannot exceed 59 * INT_MAX,
   and also cannot exceed one month's worth of seconds;
   this is enough to handle any POSIX or real-life daylight-saving offset.
   Adjust only T's year, mon, mday, hour, min and sec members;
   plus adjust wday if it is defined.  */
void
adjzone (register struct tm *t,
         long seconds)
{
   int days = 0;

   /* This code can be off by a second if SECONDS is not a multiple of 60,
      if T is local time, and if a leap second happens during this minute.
      But this bug has never occurred, and most likely will not ever occur.
      Liberia, the last country for which SECONDS % 60 was nonzero,
      switched to UTC in May 1972; the first leap second was in June 1972.  */
   int leap_second = t->tm_sec == 60;
   long sec = seconds + (t->tm_sec - leap_second);
   if (sec < 0)
   {
      if ((t->tm_min -= (59 - sec) / 60) < 0
          && (t->tm_hour -= (59 - t->tm_min) / 60) < 0)
      {
         days = - ((23 - t->tm_hour) / 24);
         if ((t->tm_mday += days) <= 0)
         {
            if (--t->tm_mon < 0)
            {
               --t->tm_year;
               t->tm_mon = 11;
            }
            t->tm_mday += month_days (t);
         }
      }
   }
   else
   {
      if (60 <= (t->tm_min += sec / 60)
          && (24 <= (t->tm_hour += t->tm_min / 60)))
      {
         days = t->tm_hour / 24;
         if (month_days (t) < (t->tm_mday += days))
         {
            if (11 < ++t->tm_mon)
            {
               ++t->tm_year;
               t->tm_mon = 0;
            }
            t->tm_mday = 1;
         }
      }
   }
   if (TM_DEFINED (t->tm_wday))
      t->tm_wday = MOD (t->tm_wday + days, 7);
   t->tm_hour = MOD (t->tm_hour, 24);
   t->tm_min = MOD (t->tm_min, 60);
   t->tm_sec = (int) MOD (sec, 60) + leap_second;
}
Ejemplo n.º 4
0
		unsigned date::day_in_year(unsigned y, unsigned m, unsigned d)
		{
			unsigned days = 0;
			for(unsigned i = 1; i < m; ++i)
				days += month_days(y, i);
			return days + d;
		}
Ejemplo n.º 5
0
		date date::_m_sub(unsigned x) const
		{
			date d(*this);
			while(x)
			{
				if(d.value_.day <= x)
				{
					if(d.value_.month == 1)
					{
						d.value_.month = 12;
						-- d.value_.year;
					}
					else
						-- d.value_.month;

					d.value_.day = month_days(d.value_.year, d.value_.month);

					x -= d.value_.day;
				}
				else
				{
					d.value_.day -= x;
					break;
				}
			}
			return d;
		}
Ejemplo n.º 6
0
void testDateEpoch(
    Test * pTest)
{
    uint32_t days = 0;
    uint16_t year = 0, test_year = 0;
    uint8_t month = 0, test_month = 0;
    uint8_t day = 0, test_day = 0;

    days = days_since_epoch(1900, 1, 1);
    ct_test(pTest, days == 0);
    days_since_epoch_into_ymd(days, &year, &month, &day);
    ct_test(pTest, year == 1900);
    ct_test(pTest, month == 1);
    ct_test(pTest, day == 1);


    for (year = 1900; year <= 2154; year++) {
        for (month = 1; month <= 12; month++) {
            for (day = 1; day <= month_days(year, month); day++) {
                days = days_since_epoch(year, month, day);
                days_since_epoch_into_ymd(days, &test_year, &test_month,
                    &test_day);
                ct_test(pTest, year == test_year);
                ct_test(pTest, month == test_month);
                ct_test(pTest, day == test_day);
            }
        }
    }
}
Ejemplo n.º 7
0
		date date::_m_add(unsigned x) const
		{
			date d(*this);
			while(x)
			{
				unsigned off = month_days(d.value_.year, d.value_.month) - d.value_.day;
				if(off < x)
				{
					d.value_.day = 1;
					if(d.value_.month == 12)
					{
						d.value_.month = 1;
						++ d.value_.year;
					}
					else
						++ d.value_.month;

					x -= (off + 1);
				}
				else if(off >= x)
				{
					d.value_.day += x;
					break;
				}
			}
			return d;
		}
Ejemplo n.º 8
0
/*
 *  add @n year to date
 */
Date& Date::add_year(int n)
{
    if (n) {
	int  yy;
	yy = y + n;
	
	if (d == month_days(m, y))
	    if ( (!leapyear(y) && leapyear(yy)) ||
		 (leapyear(y) && !leapyear(yy)) )
		d = month_days(m, yy);
	y = yy;

	cache->valid = false;
    }
    
    return *this;
}
Ejemplo n.º 9
0
/*
 *  add @n days to date
 */
Date& Date::add_day(int n)
{
    if (n) {
	int   left = n;

	while ( (left + d) > month_days(m, y)) {
	    left -= (month_days(m, y) - d + 1);
	    d = 1;
	    add_month(1);
	}

	if (left)
	    d += left;
	
	cache->valid = false;
    }

    return *this;
}
Ejemplo n.º 10
0
static void progress_date(unsigned * Y, unsigned * M, unsigned * D, const bool is_leapyear)
{
    if (++(*D) > month_days(*M, is_leapyear))
    {
        *D = 1;
        if (++(*M) > 12)
        {
            *M = 1;
            ++(*Y);
        }
    }
}
Ejemplo n.º 11
0
/*
 * Does the rtc_time represent a valid date/time?
 */
int rtc_valid_tm(struct rtc_time *tm)
{
	if (tm->tm_year < 70 ||
	    tm->tm_mon >= 12 ||
	    tm->tm_mday < 1 ||
	    tm->tm_mday > month_days(tm->tm_mon, tm->tm_year + 1900) ||
	    tm->tm_hour >= 24 ||
	    tm->tm_min >= 60 ||
	    tm->tm_sec >= 60)
		return -EINVAL;

	return 0;
}
date_t plusab(date_t *date, day_t days)
    { /* todo: eliminate loops, handle year <== 1752 */
    /* Normalize the days to be less then 1 year */
       while(days < 0){
         date->year -= 1;
         days += year_days(date->year);
       };
       while(days > year_days(date->year)){
         days -= year_days(date->year);
         date->year += 1;
       };
       date->month_day += days;
    /* Normalize the days to be the same month */
       while(date->month_day > month_days(date->year, date->month)){
          date->month_day -= month_days(date->year, date->month);
          date->month += 1;
          if(date->month > year_months){
             date->month -= year_months;
             date->year += 1;
          }
       }
       date->week_day = week_day(*date);
       return *date;
    }
Ejemplo n.º 13
0
static bool date_is_valid(
    uint16_t year,
    uint8_t month,
    uint8_t day)
{
    bool status = false;        /* true if value date */
    uint8_t monthdays;  /* days in a month */


    monthdays = month_days(year, month);
    if ((year >= 1900) && (monthdays) && (day >= 1) && (day <= monthdays)) {
        status = true;
    }

    return status;
}
Ejemplo n.º 14
0
void tui_set_clock(void) {
	struct mtm tm;
	timer_get_time(&tm);
	tm.sec = 0;
	uint16_t year = tui_gen_nummenu(PSTR("YEAR"),TIME_EPOCH_YEAR,TIME_EPOCH_YEAR+130,tm.year+TIME_EPOCH_YEAR);
	uint8_t month = tui_gen_nummenu(PSTR("MONTH"),1,12,tm.month);
	year = year - TIME_EPOCH_YEAR;
	if ((tm.month != month)||(tm.year != year)) { // Day count in the month possibly changed, cannot start from old day.
		tm.day = 1;
	}
	tm.day = tui_gen_nummenu(PSTR("DAY"),1,month_days(year,month-1),tm.day);
	tm.year = year;
	tm.month = month;
	tm.hour = tui_gen_nummenu(PSTR("HOURS"), 0, 23, tm.hour);
	tm.min = tui_gen_nummenu(PSTR("MINUTES"),0, 59, tm.min);
	timer_set_time(&tm);
}
Ejemplo n.º 15
0
/*
 *  the constructor of Date, it'll throw a BadDate exception if
 *  the input date is illegal.
 */
Date::Date(int dd, Month mm, int yy)
{
    dd = dd ? dd : default_date.d;
    mm = mm ? mm : default_date.m;
    yy = yy ? yy : default_date.y;

    if (mm < jan || mm > dec)
	throw BadDate("incorrect month");
	
    if (dd < 1 || dd > month_days(mm, yy))
	throw BadDate("incorrect day");
    
    d = dd;
    m = mm;
    y = yy;

    cache = new Cache();
    cache->valid = false;
}
Ejemplo n.º 16
0
static uint32_t days_since_epoch(
    uint16_t year,
    uint8_t month,
    uint8_t day)
{
    uint32_t days = 0;  /* return value */
    uint16_t years = 0; /* loop counter for years */
    uint8_t months = 0; /* loop counter for months */

    if (date_is_valid(year, month, day)) {
        for (years = 1900; years < year; years++) {
            days += 365;
            if (is_leap_year(years))
                days++;
        }
        for (months = 1; months < month; months++) {
            days += month_days(years, months);
        }
        days += (day - 1);
    }

    return (days);
}
Ejemplo n.º 17
0
/*
 * Convert seconds since 01-01-1970 00:00:00 to Gregorian date.
 */
void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
{
	int days, month, year;

	days = time / 86400;
	time -= days * 86400;

	tm->tm_wday = (days + 4) % 7;

	year = 1970 + days / 365;
	days -= (year - 1970) * 365
	        + LEAPS_THRU_END_OF(year - 1)
	        - LEAPS_THRU_END_OF(1970 - 1);
	if (days < 0) {
		year -= 1;
		days += 365 + LEAP_YEAR(year);
	}
	tm->tm_year = year - 1900;
	tm->tm_yday = days + 1;

	for (month = 0; month < 11; month++) {
		int newdays;

		newdays = days - month_days(month, year);
		if (newdays < 0)
			break;
		days = newdays;
	}
	tm->tm_mon = month;
	tm->tm_mday = days + 1;

	tm->tm_hour = time / 3600;
	time -= tm->tm_hour * 3600;
	tm->tm_min = time / 60;
	tm->tm_sec = time - tm->tm_min * 60;
}
day_t year_days(year_t year) /* Ignore 1752 CE for the moment */
  { return (month_days(year, 2) == 28) ? 365 : 366; }