struct tm * mygmtime(register const time_t time) { static struct tm br_time; register struct tm *timep = &br_time; register unsigned long dayclock, dayno; int year = EPOCH_YR; dayclock = (unsigned long)time % SECS_DAY; dayno = (unsigned long)time / SECS_DAY; timep->tm_sec = dayclock % 60; timep->tm_min = (dayclock % 3600) / 60; timep->tm_hour = dayclock / 3600; timep->tm_wday = (dayno + 4) % 7; /* day 0 was a thursday */ while (dayno >= YEARSIZE(year)) { dayno -= YEARSIZE(year); year++; } timep->tm_year = year - YEAR0; timep->tm_yday = dayno; timep->tm_mon = 0; while (dayno >= _ytab[LEAPYEAR(year)][timep->tm_mon]) { dayno -= _ytab[LEAPYEAR(year)][timep->tm_mon]; timep->tm_mon++; } timep->tm_mday = dayno + 1; timep->tm_isdst = 0; return timep; }
struct tm *gmtime_r(const time_t *timer, struct tm *tmbuf) { time_t time = *timer; unsigned long dayclock, dayno; int year = 1970; dayclock = (unsigned long) time % SECS_PER_DAY; dayno = (unsigned long) time / SECS_PER_DAY; tmbuf->tm_sec = dayclock % SECS_PER_MIN; tmbuf->tm_min = (dayclock % SECS_PER_HOUR) / SECS_PER_MIN; tmbuf->tm_hour = dayclock / SECS_PER_HOUR; tmbuf->tm_wday = (dayno + 4) % 7; // Day 0 was a thursday while (dayno >= (unsigned long) YEARSIZE(year)) { dayno -= YEARSIZE(year); year++; } tmbuf->tm_year = year - 1900; tmbuf->tm_yday = dayno+1; tmbuf->tm_mon = 0; while (dayno >= (unsigned long) _ytab[LEAPYEAR(year)][tmbuf->tm_mon]) { dayno -= _ytab[LEAPYEAR(year)][tmbuf->tm_mon]; tmbuf->tm_mon++; } tmbuf->tm_mday = dayno + 1; return tmbuf; }
virtual void getTimeAndDate(TimeDate &t) const { time_t curTime = time(NULL); #define YEAR0 1900 #define EPOCH_YR 1970 #define SECS_DAY (24L * 60L * 60L) #define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) % 400))) #define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365) const int _ytab[2][12] = { {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} }; int year = EPOCH_YR; unsigned long dayclock = (unsigned long)curTime % SECS_DAY; unsigned long dayno = (unsigned long)curTime / SECS_DAY; t.tm_sec = dayclock % 60; t.tm_min = (dayclock % 3600) / 60; t.tm_hour = dayclock / 3600; t.tm_wday = (dayno + 4) % 7; /* day 0 was a thursday */ while (dayno >= YEARSIZE(year)) { dayno -= YEARSIZE(year); year++; } t.tm_year = year - YEAR0; t.tm_mon = 0; while (dayno >= _ytab[LEAPYEAR(year)][t.tm_mon]) { dayno -= _ytab[LEAPYEAR(year)][t.tm_mon]; t.tm_mon++; } t.tm_mday = dayno + 1; }
void from_unix_timestamp(uint64_t ts, unsigned *day_of_month, unsigned *month_of_year, unsigned *year, unsigned *seconds, unsigned *minutes, unsigned *hours) { uint64_t ndays = ts / 86400; uint64_t time = ts % 86400; *hours = time / 3600; *minutes = (time % 3600) / 60; *seconds = time % 60; *year = EPOCH; while (ndays >= (LEAPYEAR(*year) ? 366 : 365)) { ndays -= (LEAPYEAR(*year) ? 366 : 365); ++*year; } unsigned month = 1; while (ndays >= days_in_month[month]) { ndays -= days_in_month[month]; ++month; } *month_of_year = month; *day_of_month = ndays + 1; }
void expand_time(struct time_exp_t *xt, uint64_t wall_clock) { uint32_t time = NS_TO_SECS(wall_clock); unsigned long dayclock, dayno; int year = EPOCH_YR; dayclock = (unsigned long)time % SECS_DAY; dayno = (unsigned long)time / SECS_DAY; xt->tm_usec = NS_TO_US(wall_clock) % 1000000ULL; xt->tm_sec = dayclock % 60; xt->tm_min = (dayclock % 3600) / 60; xt->tm_hour = dayclock / 3600; xt->tm_wday = (dayno + 4) % 7; /* day 0 was a thursday */ while (dayno >= YEARSIZE(year)) { dayno -= YEARSIZE(year); year++; } xt->tm_year = year - YEAR0; xt->tm_yday = dayno; xt->tm_mon = 0; while (dayno >= _ytab[LEAPYEAR(year)][xt->tm_mon]) { dayno -= _ytab[LEAPYEAR(year)][xt->tm_mon]; xt->tm_mon++; } xt->tm_mday = dayno + 1; xt->tm_isdst = 0; xt->tm_gmtoff = 0; }
u_long chiptotime(int sec, int min, int hour, int day, int mon, int year) { int days, yr; sec = FROMBCD(sec); min = FROMBCD(min); hour = FROMBCD(hour); day = FROMBCD(day); mon = FROMBCD(mon); year = FROMBCD(year) + YEAR0; if (year < 70) year = 70; /* simple sanity checks */ if (year < 70 || mon < 1 || mon > 12 || day < 1 || day > 31) return (0); days = 0; for (yr = 70; yr < year; yr++) days += LEAPYEAR(yr) ? 366 : 365; days += dayyr[mon - 1] + day - 1; if (LEAPYEAR(yr) && mon > 2) days++; /* now have days since Jan 1, 1970; the rest is easy... */ return days * SECDAY + hour * 3600 + min * 60 + sec; }
struct tm *gmtime_r(const time_t *timer, struct tm *tmbuf) { time_t time = *timer; INT32U dayclock, dayno; int year = EPOCH_YR; dayclock = (INT32U) time % SECS_DAY; dayno = (INT32U) time / SECS_DAY; tmbuf->tm_sec = dayclock % 60; tmbuf->tm_min = (dayclock % 3600) / 60; tmbuf->tm_hour = dayclock / 3600; tmbuf->tm_wday = (dayno + 4) % 7; // Day 0 was a thursday while (dayno >= (INT32U) YEARSIZE(year)) { dayno -= YEARSIZE(year); year++; } tmbuf->tm_year = year - YEAR0; tmbuf->tm_yday = dayno; tmbuf->tm_mon = 0; while (dayno >= (INT32U) _ytab[LEAPYEAR(year)][tmbuf->tm_mon]) { dayno -= _ytab[LEAPYEAR(year)][tmbuf->tm_mon]; tmbuf->tm_mon++; } tmbuf->tm_mday = dayno + 1; tmbuf->tm_isdst = 0; //tmbuf->tm_gmtoff = 0; //tmbuf->tm_zone = "UTC"; return tmbuf; }
char *format_time(uint64_t sec) { struct tm t; static char buf[64]; unsigned long dayclock, dayno; int year = EPOCH_YR; dayclock = (unsigned long)sec % SECS_DAY; dayno = (unsigned long)sec / SECS_DAY; t.tm_sec = dayclock % 60; t.tm_min = (dayclock % 3600) / 60; t.tm_hour = dayclock / 3600; t.tm_wday = (dayno + 4) % 7; /* day 0 was a thursday */ while (dayno >= YEARSIZE(year)) { dayno -= YEARSIZE(year); year++; } t.tm_year = year - YEAR0; t.tm_yday = dayno; t.tm_mon = 0; while (dayno >= _ytab[LEAPYEAR(year)][t.tm_mon]) { dayno -= _ytab[LEAPYEAR(year)][t.tm_mon]; t.tm_mon++; } t.tm_mday = dayno + 1; t.tm_isdst = 0; sprintf(buf, "%s, %s %d, %d, %02d:%02d:%02d", _days[t.tm_wday], _months[t.tm_mon], t.tm_mday, t.tm_year + YEAR0, t.tm_hour, t.tm_min, t.tm_sec); return buf; }
struct tm *GmTimeR(const time_t *timer, struct tm *tmbuf) { static const int _ytab[2][12] = { {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} }; static char zone[4] = "UTC"; time_t time = *timer; if (time < 0) return 0; ui64 dayclock, dayno; int year = EPOCH_YR; if (time < 0) { ui64 shift = (ui64)(-time - 1) / ((ui64)FOURCENTURIES * SECS_DAY) + 1; time += shift * ((ui64)FOURCENTURIES * SECS_DAY); year -= shift * 400; } dayclock = (ui64) time % SECS_DAY; dayno = (ui64) time / SECS_DAY; year += 400 * (dayno / FOURCENTURIES); dayno = dayno % FOURCENTURIES; tmbuf->tm_sec = dayclock % 60; tmbuf->tm_min = (dayclock % 3600) / 60; tmbuf->tm_hour = dayclock / 3600; tmbuf->tm_wday = (dayno + 4) % 7; // Day 0 was a thursday while (dayno >= (ui64) YEARSIZE(year)) { dayno -= YEARSIZE(year); year++; } tmbuf->tm_year = year - YEAR0; tmbuf->tm_yday = dayno; tmbuf->tm_mon = 0; while (dayno >= (ui64) _ytab[LEAPYEAR(year)][tmbuf->tm_mon]) { dayno -= _ytab[LEAPYEAR(year)][tmbuf->tm_mon]; tmbuf->tm_mon++; } tmbuf->tm_mday = dayno + 1; tmbuf->tm_isdst = 0; #ifndef _win_ tmbuf->tm_gmtoff = 0; tmbuf->tm_zone = zone; YASSERT(!strcmp(zone, "UTC")); #endif return tmbuf; }
static int date_of(register struct dsttype *dst, struct tm *timep) { int leap = LEAPYEAR(YEAR0 + timep->tm_year); int firstday, tmpday; register int day, month; if (dst->ds_type != 'M') { return dst->ds_date[0] - (dst->ds_type == 'J' && leap && dst->ds_date[0] < 58); } day = 0; month = 1; while (month < dst->ds_date[0]) { day += _ytab[leap][month - 1]; month++; } firstday = (day + FIRSTDAYOF(timep)) % 7; tmpday = day; day += (dst->ds_date[2] - firstday + 7) % 7 + 7 * (dst->ds_date[1] - 1); if (day >= tmpday + _ytab[leap][month-1]) day -= 7; return day; }
uint8_t SparkTime::day(uint32_t tnow) { uint32_t dayNum = (tnow+timeZoneDSTOffset(tnow)-SPARKTIMEBASESTART)/SPARKTIMESECPERDAY; uint32_t tempYear = SPARKTIMEBASEYEAR; uint8_t tempMonth = 0; while(dayNum >= YEARSIZE(tempYear)) { dayNum -= YEARSIZE(tempYear); tempYear++; } while(dayNum >= _monthLength[LEAPYEAR(tempYear)][tempMonth]) { dayNum -= _monthLength[LEAPYEAR(tempYear)][tempMonth]; tempMonth++; } dayNum++; // correct for zero-base return (uint8_t)dayNum; }
uint8_t SparkTime::month(uint32_t tnow) { uint32_t dayNum = (tnow+timeZoneDSTOffset(tnow)-SPARKTIMEBASESTART)/SPARKTIMESECPERDAY; uint32_t tempYear = SPARKTIMEBASEYEAR; uint8_t tempMonth = 0; while(dayNum >= YEARSIZE(tempYear)) { dayNum -= YEARSIZE(tempYear); tempYear++; } while(dayNum >= _monthLength[LEAPYEAR(tempYear)][tempMonth]) { dayNum -= _monthLength[LEAPYEAR(tempYear)][tempMonth]; tempMonth++; } tempMonth++; return tempMonth; }
static int last_sunday(register int day, register struct tm *timep) { int first = FIRSTSUNDAY(timep); if (day >= 58 && LEAPYEAR(YEAR0 + timep->tm_year)) day++; if (day < first) return first; return day - (day - first) % 7; }
uint64_t to_unix_timestamp(unsigned day_of_month, unsigned month_of_year, unsigned year, unsigned seconds, unsigned minutes, unsigned hours) { uint64_t days = 0; /* Iteratively count up from the epoch year to the given year as each year may be a leap. */ for (unsigned y = EPOCH; y < year; ++y) days += LEAPYEAR(y) ? 366 : 365; /* Same with months, because February could be 28 or 29. */ for (unsigned m = 1; m < month_of_year; ++m) days += days_in_month[m] + ((LEAPYEAR(year) && m == 2) ? 1 : 0); days += day_of_month-1; return days * 86400 + hours * 3600 + minutes * 60 + seconds; }
/**************************************************** * Class:Function : getSecsSomceEpoch * Input : uint16_t epoch date (ie, 1970) * Input : uint8 ptr to returned month * Input : uint8 ptr to returned day * Input : uint8 ptr to returned years since Epoch * Input : uint8 ptr to returned hour * Input : uint8 ptr to returned minute * Input : uint8 ptr to returned seconds * Output : uint32_t Seconds between Epoch year and timestamp * Behavior : * * Converts MM/DD/YY HH:MM:SS to actual seconds since epoch. * Epoch year is assumed at Jan 1, 00:00:01am. ****************************************************/ uint32_t getSecsSinceEpoch(uint16_t epoch, uint8_t month, uint8_t day, uint8_t years, uint8_t hour, uint8_t minute, uint8_t second) { unsigned long secs = 0; int countleap = 0; int i; int dayspermonth; secs = years * (SECSPERDAY * 365); for (i = 0; i < (years - 1); i++) { if (LEAPYEAR((epoch + i))) countleap++; } secs += (countleap * SECSPERDAY); secs += second; secs += (hour * SECSPERHOUR); secs += (minute * SECSPERMIN); secs += ((day - 1) * SECSPERDAY); if (month > 1) { dayspermonth = 0; if (LEAPYEAR((epoch + years))) // Only counts when we're on leap day or past it { if (month > 2) { dayspermonth = 1; } else if (month == 2 && day >= 29) { dayspermonth = 1; } } for (i = 0; i < month - 1; i++) { secs += (_ytab[dayspermonth][i] * SECSPERDAY); } } return secs; }
// The gmtime() function converts the calendar time timep to broken-down // time representation, expressed in Coordinated Universal Time (UTC). const struct tm* gmtime(time_t time){ static struct tm tm; uint32_t dayclock = time % SECS_DAY; tm.tm_mday = time / SECS_DAY; tm.tm_year = EPOCH_YR; tm.tm_sec = time % 60UL; tm.tm_min = (time % 3600UL) / 60; tm.tm_hour = dayclock / 3600UL; tm.tm_wday = (tm.tm_mday + 4) % 7; /* day 0 was a thursday */ while (tm.tm_mday >= YEARSIZE(tm.tm_year)) { tm.tm_mday -= YEARSIZE(tm.tm_year); tm.tm_year++; } tm.tm_mon = 0; while (tm.tm_mday >= monthlen(LEAPYEAR(tm.tm_year),tm.tm_mon)) { tm.tm_mday -= monthlen(LEAPYEAR(tm.tm_year),tm.tm_mon); tm.tm_mon++; } tm.tm_mday++; return &tm; }
// gmtime -- convert calendar time (sec since 1970) into broken down time // returns something like Fri 2007-10-19 in day and 01:02:21 in clock // The return values is the minutes as integer. This way you can update // the entire display when the minutes have changed and otherwise just // write current time (clock). That way an LCD display needs complete // re-write only every minute. uint8_t gmtime(const uint32_t time,char *day, char *clock) { char dstr[4]; uint8_t i; uint32_t dayclock; uint16_t dayno; uint16_t tm_year = EPOCH_YR; uint8_t tm_sec,tm_min,tm_hour,tm_wday,tm_mon; dayclock = (time) % SECS_DAY; dayno = (time) / SECS_DAY; extern newMinute; tm_sec = dayclock % 60UL; newMinute=tm_sec; tm_min = (dayclock % 3600UL) / 60; tm_hour = dayclock / 3600UL; tm_wday = (dayno + 4) % 7; /* day 0 was a Thursday */ while (dayno >= YEARSIZE(tm_year)) { dayno -= YEARSIZE(tm_year); tm_year++; } tm_mon = 0; while (dayno >= monthlen(LEAPYEAR(tm_year),tm_mon)) { dayno -= monthlen(LEAPYEAR(tm_year),tm_mon); tm_mon++; } i=0; while (i<3){ dstr[i]= pgm_read_byte(&(day_abbrev[tm_wday*3 + i])); i++; } dstr[3]='\0'; sprintf_P(day,PSTR("%s %u-%02u-%02u"),dstr,tm_year,tm_mon+1,dayno + 1); sprintf_P(clock,PSTR("%02u:%02u:%02u"),tm_hour,tm_min,tm_sec); return(tm_min); }
bool SparkTime::isEuroDST(uint32_t tnow) { // 1am last Sunday in March to 1am on last Sunday October // can't use offset here bool result = false; uint32_t dayNum = (tnow+_timezone*3600UL-SPARKTIMEBASESTART)/SPARKTIMESECPERDAY; uint32_t tempYear = SPARKTIMEBASEYEAR; uint8_t tempMonth = 0; uint8_t tempHour = ((tnow+_timezone*3600UL) % 86400UL)/3600UL; while(dayNum >= YEARSIZE(tempYear)) { dayNum -= YEARSIZE(tempYear); tempYear++; } while(dayNum >= _monthLength[LEAPYEAR(tempYear)][tempMonth]) { dayNum -= _monthLength[LEAPYEAR(tempYear)][tempMonth]; tempMonth++; } tempMonth++; dayNum++; // correct for zero-base if (tempMonth>3 && tempMonth<10) { result = true; } else if (tempMonth == 3) { if ((dayNum == _EuDSTStart[tempYear-SPARKTIMEBASEYEAR] && tempHour >=1) || (dayNum > _EuDSTStart[tempYear-SPARKTIMEBASEYEAR])) { result = true; } } else if (tempMonth == 10) { if (!((dayNum == _EuDSTEnd[tempYear-SPARKTIMEBASEYEAR] && tempHour >=1) || (dayNum > _EuDSTEnd[tempYear-SPARKTIMEBASEYEAR]))) { result = true; } } return result; }
/* * Convert date fields from EndRun to nanoseconds since the epoch. * The year string must be of the form YYYY . * The day of year string must be of the form DDD . * Return 0 on success, -1 if illegal characters are encountered. */ int endrun_date_to_nano(char *y, char *doy, int64_t *nano) { struct clock_ymdhms clock; time_t secs; int n, i; int year_days = 365; int month_days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; #define FEBRUARY 2 #define LEAPYEAR(x) \ ((x) % 4 == 0 && \ (x) % 100 != 0) || \ (x) % 400 == 0 if ((n = endrun_atoi(y, 4)) == -1) return -1; clock.dt_year = n; if (LEAPYEAR(n)) { month_days[FEBRUARY]++; year_days++; } if ((n = endrun_atoi(doy, 3)) == -1 || n == 0 || n > year_days) return -1; /* convert day of year to month, day */ for (i = 1; n > month_days[i]; i++) { n -= month_days[i]; } clock.dt_mon = i; clock.dt_day = n; DPRINTFN(1, ("mm/dd %d/%d\n", i, n)); clock.dt_hour = clock.dt_min = clock.dt_sec = 0; secs = clock_ymdhms_to_secs(&clock); *nano = secs * 1000000000LL; return 0; }
//! Inverse of gmtime: converts struct tm to time_t, assuming the data //! in tm is UTC rather than local timezone. This implementation //! returns the number of seconds since 1970-01-01, converted to time_t. //! @note this code adopted from //! http://osdir.com/ml/web.wget.patches/2005-07/msg00010.html //! Subject: A more robust timegm - msg#00010 time_t TimeGM(struct tm* t) { static const unsigned short int month_to_days[][13] = { { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }, { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 } }; // Only handles years between 1970 and 2099. if (t->tm_year < 70 || t->tm_year > 129) return (time_t) -1; int days = 365 * (t->tm_year - 70); // Take into account the leap days between 1970 and YEAR-1; all // years divisible by four between 1968 and 2100 should be leap. days += (t->tm_year - 1 - 68) / 4; if (t->tm_mon < 0 || t->tm_mon >= 12) return (time_t) -1; days += month_to_days[LEAPYEAR (1900 + t->tm_year)][t->tm_mon]; days += t->tm_mday - 1; unsigned long secs = days * 86400 + t->tm_hour * 3600 + t->tm_min * 60 + t->tm_sec; return (time_t) secs; }
void Interface_t::Task() { static uint32_t IBlinkTmr=0, IStateTmr=0; static bool IsDisplayed; static uint8_t OldH=27, OldM=99; // Dummy values for first time switch(State) { case msIdle: // Display time if needed if(Time.SecElapsed(&TimeChangeTmr, 1)) { Time.GetDateTime(&IDateTime); DisplayHour(true); DisplayMinute(true); DisplaySecond(true); DisplayYear(true); DisplayMonth(true); DisplayDay(true); ShowTime.ShowMinute(IDateTime.S); // Check if showtime has come if(IDateTime.M != OldM) { OldM = IDateTime.M; //ShowTime.ShowMinute(IDateTime.M); } if(IDateTime.H != OldH) { OldH = IDateTime.H; ShowTime.ShowHour(IDateTime.H); } } // Handle keys if(Keys.AnyKeyWasJustPressed()) { Lcd.Backlight(72); Delay.Reset(&BckLtTmr); } if(Keys.Enter.WasJustPressed()) { Keys.Up.ResetPresses(); Keys.Down.ResetPresses(); State = msHour; IsDisplayed = true; Delay.Reset(&IBlinkTmr); Delay.Reset(&IStateTmr); // to return to idle } // Handle backlight if(Delay.Elapsed(&BckLtTmr, BCKLT_DELAY)) Lcd.Backlight(0); break; case msHour: // Handle autoexit if(Delay.Elapsed(&IStateTmr, STATE_DELAY)) { EnterIdle(); break; } // Handle keys if(Keys.Down.WasJustPressed()) IDec(false, &IDateTime.H, 0, 23); else if(Keys.Up.WasJustPressed()) IInc(false, &IDateTime.H, 0, 23); else if(Keys.Enter.WasJustPressed()) { IDateTime.S = 0; DisplaySecond(true); State = msMinute; } if(Keys.AnyKeyWasJustPressed()) { Delay.Reset(&IStateTmr); Delay.Reset(&IBlinkTmr); DisplayHour(IsDisplayed = true); } // Handle blink else if(!Keys.Down.IsPressed() and !Keys.Up.IsPressed() and Delay.Elapsed(&IBlinkTmr, BLINK_DELAY)) DisplayHour(IsDisplayed = !IsDisplayed); // Blink the value break; case msMinute: // Handle autoexit if(Delay.Elapsed(&IStateTmr, STATE_DELAY)) { EnterIdle(); break; } // Handle keys if(Keys.Down.WasJustPressed()) IDec(false, &IDateTime.M, 0, 59); else if(Keys.Up.WasJustPressed()) IInc(false, &IDateTime.M, 0, 59); else if(Keys.Enter.WasJustPressed()) State = msYear; if(Keys.AnyKeyWasJustPressed()) { Delay.Reset(&IStateTmr); Delay.Reset(&IBlinkTmr); DisplayMinute(IsDisplayed = true); } // Handle blink else if(!Keys.Down.IsPressed() and !Keys.Up.IsPressed() and Delay.Elapsed(&IBlinkTmr, BLINK_DELAY)) DisplayMinute(IsDisplayed = !IsDisplayed); // Blink the value break; case msYear: // Handle autoexit if(Delay.Elapsed(&IStateTmr, STATE_DELAY)) { EnterIdle(); break; } // Handle keys if(Keys.Down.WasJustPressed()) IDec(false, &IDateTime.Year, YEAR_MIN, YEAR_MAX); else if(Keys.Up.WasJustPressed()) IInc(false, &IDateTime.Year, YEAR_MIN, YEAR_MAX); else if(Keys.Enter.WasJustPressed()) State = msMonth; if(Keys.AnyKeyWasJustPressed()) { Delay.Reset(&IStateTmr); Delay.Reset(&IBlinkTmr); DisplayYear(IsDisplayed = true); } // Handle blink else if(!Keys.Down.IsPressed() and !Keys.Up.IsPressed() and Delay.Elapsed(&IBlinkTmr, BLINK_DELAY)) DisplayYear(IsDisplayed = !IsDisplayed); // Blink the value break; case msMonth: // Handle autoexit if(Delay.Elapsed(&IStateTmr, STATE_DELAY)) { EnterIdle(); break; } // Handle keys if(Keys.Down.WasJustPressed()) IDec(false, &IDateTime.Month, 1, 12); else if(Keys.Up.WasJustPressed()) IInc(false, &IDateTime.Month, 1, 12); else if(Keys.Enter.WasJustPressed()) State = msDay; if(Keys.AnyKeyWasJustPressed()) { Delay.Reset(&IStateTmr); Delay.Reset(&IBlinkTmr); DisplayMonth(IsDisplayed = true); } // Handle blink else if(!Keys.Down.IsPressed() and !Keys.Up.IsPressed() and Delay.Elapsed(&IBlinkTmr, BLINK_DELAY)) DisplayMonth(IsDisplayed = !IsDisplayed); // Blink the value break; case msDay: // Handle autoexit if(Delay.Elapsed(&IStateTmr, STATE_DELAY)) { EnterIdle(); break; } // Handle keys if(Keys.Down.WasJustPressed()) IDec(false, &IDateTime.Day, 1, MonthDays[LEAPYEAR(IDateTime.Year)][IDateTime.Month-1]); else if(Keys.Up.WasJustPressed()) IInc(false, &IDateTime.Day, 1, MonthDays[LEAPYEAR(IDateTime.Year)][IDateTime.Month-1]); else if(Keys.Enter.WasJustPressed()) EnterIdle(); if(Keys.AnyKeyWasJustPressed()) { Delay.Reset(&IStateTmr); Delay.Reset(&IBlinkTmr); DisplayDay(IsDisplayed = true); } // Handle blink else if(!Keys.Down.IsPressed() and !Keys.Up.IsPressed() and Delay.Elapsed(&IBlinkTmr, BLINK_DELAY)) DisplayDay(IsDisplayed = !IsDisplayed); // Blink the value break; } }
time_t mktime(struct tm *tmbuf) { u32 day; u32 tm_year, year; u32 yday, month; u32 seconds; u32 overflow; u32 dst; tmbuf->tm_min += tmbuf->tm_sec / 60; tmbuf->tm_sec %= 60; if (tmbuf->tm_sec < 0) { tmbuf->tm_sec += 60; tmbuf->tm_min--; } tmbuf->tm_hour += tmbuf->tm_min / 60; tmbuf->tm_min = tmbuf->tm_min % 60; if (tmbuf->tm_min < 0) { tmbuf->tm_min += 60; tmbuf->tm_hour--; } day = tmbuf->tm_hour / 24; tmbuf->tm_hour= tmbuf->tm_hour % 24; if (tmbuf->tm_hour < 0) { tmbuf->tm_hour += 24; day--; } tmbuf->tm_year += tmbuf->tm_mon / 12; tmbuf->tm_mon %= 12; if (tmbuf->tm_mon < 0) { tmbuf->tm_mon += 12; tmbuf->tm_year--; } day += (tmbuf->tm_mday - 1); while (day < 0) { if(--tmbuf->tm_mon < 0) { tmbuf->tm_year--; tmbuf->tm_mon = 11; } day += _ytab[LEAPYEAR(YEAR0 + tmbuf->tm_year)][tmbuf->tm_mon]; } while (day >= _ytab[LEAPYEAR(YEAR0 + tmbuf->tm_year)][tmbuf->tm_mon]) { day -= _ytab[LEAPYEAR(YEAR0 + tmbuf->tm_year)][tmbuf->tm_mon]; if (++(tmbuf->tm_mon) == 12) { tmbuf->tm_mon = 0; tmbuf->tm_year++; } } tmbuf->tm_mday = day + 1; year = EPOCH_YR; if (tmbuf->tm_year < year - YEAR0) return (time_t) -1; seconds = 0; day = 0; // Means days since day 0 now overflow = 0; // Assume that when day becomes negative, there will certainly // be overflow on seconds. // The check for overflow needs not to be done for leapyears // divisible by 400. // The code only works when year (1970) is not a leapyear. tm_year = tmbuf->tm_year + YEAR0; if (TIME_MAX / 365 < tm_year - year) overflow++; day = (tm_year - year) * 365; if (TIME_MAX - day < (tm_year - year) / 4 + 1) overflow++; day += (tm_year - year) / 4 + ((tm_year % 4) && tm_year % 4 < year % 4); day -= (tm_year - year) / 100 + ((tm_year % 100) && tm_year % 100 < year % 100); day += (tm_year - year) / 400 + ((tm_year % 400) && tm_year % 400 < year % 400); yday = month = 0; while (month < tmbuf->tm_mon) { yday += _ytab[LEAPYEAR(tm_year)][month]; month++; } yday += (tmbuf->tm_mday - 1); if (day + yday < 0) overflow++; day += yday; tmbuf->tm_yday = yday; tmbuf->tm_wday = (day + 4) % 7; // Day 0 was thursday (4) seconds = ((tmbuf->tm_hour * (u32)60) + tmbuf->tm_min) * (u32)60 + tmbuf->tm_sec; if ((TIME_MAX - seconds) / SECS_DAY < day) overflow++; seconds += day * SECS_DAY; // Now adjust according to timezone and daylight saving time if (((_timezone > 0) && (TIME_MAX - _timezone < seconds)) || ((_timezone < 0) && (seconds < -_timezone))) overflow++; seconds += _timezone; if (tmbuf->tm_isdst) dst = _dstbias; else dst = 0; if (dst > seconds) overflow++; // dst is always non-negative seconds -= dst; if (overflow) return (time_t) -1; if ((time_t) seconds != seconds) return (time_t) -1; return (time_t) seconds; }
_CODE_ACCESS time_t mktime(register struct tm *tptr) { time_t result; time_t daycount; int mdays; int adjust; /*-----------------------------------------------------------------*/ /* HANDLE SECONDS. IF TOO MANY OR TOO FEW, MODIFY MINUTES. */ /*-----------------------------------------------------------------*/ adjust = (tptr->tm_sec < 0) ? -((unsigned)(-tptr->tm_sec + 59) / 60) : (tptr->tm_sec / 60); if (OVERFLOW(tptr->tm_min, adjust)) return((time_t) -1); tptr->tm_min += adjust; tptr->tm_sec -= adjust * 60; /*-----------------------------------------------------------------*/ /* HANDLE MINUTES. IF TOO MANY OR TOO FEW, MODIFY HOURS */ /*-----------------------------------------------------------------*/ adjust = (tptr->tm_min < 0) ? -((unsigned)(-tptr->tm_min + 59) / 60) : (tptr->tm_min / 60); if (OVERFLOW(tptr->tm_hour, adjust)) return((time_t) -1); tptr->tm_hour += adjust; tptr->tm_min -= adjust * 60; /*-----------------------------------------------------------------*/ /* HANDLE HOURS. IF TOO MANY OR TOO FEW, MODIFY DAYS */ /*-----------------------------------------------------------------*/ adjust = (tptr->tm_hour < 0) ? -((unsigned)(-tptr->tm_hour + 23) / 24) : (tptr->tm_hour / 24); if (OVERFLOW(tptr->tm_mday, adjust)) return((time_t) -1); tptr->tm_mday += adjust; tptr->tm_hour -= adjust * 24; for (;;) { /*-----------------------------------------------------------------*/ /* HANDLE MONTHS. IF TOO MANY OR TOO FEW, MODIFY YEARS */ /*-----------------------------------------------------------------*/ adjust = (tptr->tm_mon < 0) ? -((unsigned)(-tptr->tm_mon + 11) / 12) : (tptr->tm_mon / 12); if (OVERFLOW(tptr->tm_year, adjust)) return((time_t) -1); tptr->tm_year += adjust; tptr->tm_mon -= adjust * 12; /*-----------------------------------------------------------------*/ /* HANDLE DAYS. IF TOO MANY OR TOO FEW, MODIFY MONTHS */ /*-----------------------------------------------------------------*/ if (tptr->tm_mday <= 0) { tptr->tm_mon--; tptr->tm_mday += mon_len[tptr->tm_mon < 0 ? 11 : tptr->tm_mon] + ((tptr->tm_mon == 1) && ((tptr->tm_year % 4) == 0)); continue; } /*-----------------------------------------------------------------*/ /* CALCULATE NUMBER OF DAYS IN THIS MONTH. */ /*-----------------------------------------------------------------*/ mdays = mon_len[tptr->tm_mon] + ( (tptr->tm_mon == 1) && LEAPYEAR(tptr->tm_year) ); if (tptr->tm_mday > mdays) { tptr->tm_mday -= mdays; tptr->tm_mon++; } else break; } /*--------------------------------------------------------------------*/ /* WE CAN NOW BE SURE THAT ALL FIELDS IN THE TIME STRUCTURE ARE RIGHT */ /*--------------------------------------------------------------------*/ tptr->tm_yday = mon_day[tptr->tm_mon] + tptr->tm_mday - 1 + ( (tptr->tm_mon > 1) && LEAPYEAR(tptr->tm_year) ); daycount = tptr->tm_year * DAYS_IN_YR + ((tptr->tm_year - 1) / 4) + tptr->tm_yday; result = daycount * SECS_IN_DAY + tptr->tm_hour * SECS_IN_HR + tptr->tm_min * SECS_IN_MIN + tptr->tm_sec; tptr->tm_wday = (JAN11900 + daycount) % 7; tptr->tm_isdst = _tz.daylight; return result; }
static char *_fmt(const char *format, const struct tm *t, char *pt, const char *ptlim) { for ( ; *format; ++format) { if (*format == '%') { if (*format == 'E') { format++; // Alternate Era } else if (*format == 'O') { format++; // Alternate numeric symbols } switch (*++format) { case '\0': --format; break; case 'A': pt = _add((t->tm_wday < 0 || t->tm_wday > 6) ? "?" : _days[t->tm_wday], pt, ptlim); continue; case 'a': pt = _add((t->tm_wday < 0 || t->tm_wday > 6) ? "?" : _days_abbrev[t->tm_wday], pt, ptlim); continue; case 'B': pt = _add((t->tm_mon < 0 || t->tm_mon > 11) ? "?" : _months[t->tm_mon], pt, ptlim); continue; case 'b': case 'h': pt = _add((t->tm_mon < 0 || t->tm_mon > 11) ? "?" : _months_abbrev[t->tm_mon], pt, ptlim); continue; case 'C': pt = _conv((t->tm_year + TM_YEAR_BASE) / 100, "%02d", pt, ptlim); continue; case 'c': pt = _fmt("%a %b %e %H:%M:%S %Y", t, pt, ptlim); continue; case 'D': pt = _fmt("%m/%d/%y", t, pt, ptlim); continue; case 'd': pt = _conv(t->tm_mday, "%02d", pt, ptlim); continue; case 'e': pt = _conv(t->tm_mday, "%2d", pt, ptlim); continue; case 'F': pt = _fmt("%Y-%m-%d", t, pt, ptlim); continue; case 'H': pt = _conv(t->tm_hour, "%02d", pt, ptlim); continue; case 'I': pt = _conv((t->tm_hour % 12) ? (t->tm_hour % 12) : 12, "%02d", pt, ptlim); continue; case 'j': pt = _conv(t->tm_yday + 1, "%03d", pt, ptlim); continue; case 'k': pt = _conv(t->tm_hour, "%2d", pt, ptlim); continue; case 'l': pt = _conv((t->tm_hour % 12) ? (t->tm_hour % 12) : 12, "%2d", pt, ptlim); continue; case 'M': pt = _conv(t->tm_min, "%02d", pt, ptlim); continue; case 'm': pt = _conv(t->tm_mon + 1, "%02d", pt, ptlim); continue; case 'n': pt = _add("\n", pt, ptlim); continue; case 'p': pt = _add((t->tm_hour >= 12) ? "pm" : "am", pt, ptlim); continue; case 'R': pt = _fmt("%H:%M", t, pt, ptlim); continue; case 'r': pt = _fmt("%I:%M:%S %p", t, pt, ptlim); continue; case 'S': pt = _conv(t->tm_sec, "%02d", pt, ptlim); continue; case 's': { struct tm tm; char buf[32]; time_t mkt; tm = *t; mkt = mktime(&tm); sprintf(buf, "%lu", mkt); pt = _add(buf, pt, ptlim); continue; } case 'T': pt = _fmt("%H:%M:%S", t, pt, ptlim); continue; case 't': pt = _add("\t", pt, ptlim); continue; case 'U': pt = _conv((t->tm_yday + 7 - t->tm_wday) / 7, "%02d", pt, ptlim); continue; case 'u': pt = _conv((t->tm_wday == 0) ? 7 : t->tm_wday, "%d", pt, ptlim); continue; case 'V': // ISO 8601 week number case 'G': // ISO 8601 year (four digits) case 'g': { // ISO 8601 year (two digits) int year; int yday; int wday; int w; year = t->tm_year + TM_YEAR_BASE; yday = t->tm_yday; wday = t->tm_wday; while (1) { int len; int bot; int top; len = LEAPYEAR(year) ? DAYSPERLYEAR : DAYSPERNYEAR; bot = ((yday + 11 - wday) % DAYSPERWEEK) - 3; top = bot - (len % DAYSPERWEEK); if (top < -3) top += DAYSPERWEEK; top += len; if (yday >= top) { ++year; w = 1; break; } if (yday >= bot) { w = 1 + ((yday - bot) / DAYSPERWEEK); break; } --year; yday += LEAPYEAR(year) ? DAYSPERLYEAR : DAYSPERNYEAR; } if (*format == 'V') { pt = _conv(w, "%02d", pt, ptlim); } else if (*format == 'g') { pt = _conv(year % 100, "%02d", pt, ptlim); } else { pt = _conv(year, "%04d", pt, ptlim); } continue; } case 'v': pt = _fmt("%e-%b-%Y", t, pt, ptlim); continue; case 'W': pt = _conv((t->tm_yday + 7 - (t->tm_wday ? (t->tm_wday - 1) : 6)) / 7, "%02d", pt, ptlim); continue; case 'w': pt = _conv(t->tm_wday, "%d", pt, ptlim); continue; case 'X': pt = _fmt("%H:%M:%S", t, pt, ptlim); continue; case 'x': pt = _fmt("%m/%d/%y", t, pt, ptlim); continue; case 'y': pt = _conv((t->tm_year + TM_YEAR_BASE) % 100, "%02d", pt, ptlim); continue; case 'Y': pt = _conv(t->tm_year + TM_YEAR_BASE, "%04d", pt, ptlim); continue; case 'Z': pt = _add("?", pt, ptlim); continue; case 'z': { long absoff; if (_timezone >= 0) { absoff = _timezone; pt = _add("+", pt, ptlim); } else { absoff = _timezone; pt = _add("-", pt, ptlim); } pt = _conv(absoff / 3600, "%02d", pt, ptlim); pt = _conv((absoff % 3600) / 60, "%02d", pt, ptlim); continue; } case '+': pt = _fmt("%a, %d %b %Y %H:%M:%S %z", t, pt, ptlim); continue; case '%': default: break; } } if (pt == ptlim) break; *pt++ = *format; } return pt; }