|
- #include "Time2.h"
-
- /*==============================================================================*/
- /* Useful Constants */
- #define SECS_PER_MIN (60UL)
- #define SECS_PER_HOUR (3600UL)
- #define SECS_PER_DAY (SECS_PER_HOUR * 24UL)
- #define DAYS_PER_WEEK (7UL)
- #define SECS_PER_WEEK (SECS_PER_DAY * DAYS_PER_WEEK)
- #define SECS_PER_YEAR (SECS_PER_WEEK * 52UL)
- #define SECS_YR_2000 (946684800UL) // the time at the start of y2k
-
- /* Useful Macros for getting elapsed time */
- #define numberOfSeconds(_time_) (_time_ % SECS_PER_MIN)
- #define numberOfMinutes(_time_) ((_time_ / SECS_PER_MIN) % SECS_PER_MIN)
- #define numberOfHours(_time_) (( _time_% SECS_PER_DAY) / SECS_PER_HOUR)
- #define dayOfWeek(_time_) ((( _time_ / SECS_PER_DAY + 4) % DAYS_PER_WEEK)+1) // 1 = Sunday
- #define elapsedDays(_time_) ( _time_ / SECS_PER_DAY) // this is number of days since Jan 1 1970
- #define elapsedSecsToday(_time_) (_time_ % SECS_PER_DAY) // the number of seconds since last midnight
- // The following macros are used in calculating alarms and assume the clock is set to a date later than Jan 1 1971
- // Always set the correct time before settting alarms
- #define previousMidnight(_time_) (( _time_ / SECS_PER_DAY) * SECS_PER_DAY) // time at the start of the given day
- #define nextMidnight(_time_) ( previousMidnight(_time_) + SECS_PER_DAY ) // time at the end of the given day
- #define elapsedSecsThisWeek(_time_) (elapsedSecsToday(_time_) + ((dayOfWeek(_time_)-1) * SECS_PER_DAY) ) // note that week starts on day 1
- #define previousSunday(_time_) (_time_ - elapsedSecsThisWeek(_time_)) // time at the start of the week for the given time
- #define nextSunday(_time_) ( previousSunday(_time_)+SECS_PER_WEEK) // time at the end of the week for the given time
-
-
- /* Useful Macros for converting elapsed time to a timestamp_t */
- #define minutesTotimestamp_t ((M)) ( (M) * SECS_PER_MIN)
- #define hoursTotimestamp_t ((H)) ( (H) * SECS_PER_HOUR)
- #define daysTotimestamp_t ((D)) ( (D) * SECS_PER_DAY) // fixed on Jul 22 2011
- #define weeksTotimestamp_t ((W)) ( (W) * SECS_PER_WEEK)
-
- // leap year calulator expects year argument as years offset from 1970
- #define LEAP_YEAR(Y) ( ((1970+Y)>0) && !((1970+Y)%4) && ( ((1970+Y)%100) || !((1970+Y)%400) ) )
-
- static const uint8_t monthDays[] = { 31,28,31,30,31,30,31,31,30,31,30,31 }; // API starts months from 1, this array starts from 0
-
- __attribute__((__optimize__("O2")))
- void breakTime(const timestamp_t timeInput, tmElements_t &tm) {
- // break the given timestamp_t into time components
- // this is a more compact version of the C library localtime function
- // note that year is offset from 1970 !!!
-
- uint8_t year;
- uint8_t month, monthLength;
- uint32_t time;
- unsigned long days;
-
- time = (uint32_t)timeInput;
- tm.Second = time % 60;
- time /= 60; // now it is minutes
- tm.Minute = time % 60;
- time /= 60; // now it is hours
- tm.Hour = time % 24;
- time /= 24; // now it is days
- tm.Wday = ((time + 4) % 7) + 1; // Sunday is day 1
-
- year = 0;
- days = 0;
- while ((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= time) {
- year++;
- }
- tm.Year = year; // year is offset from 1970
-
- days -= LEAP_YEAR(year) ? 366 : 365;
- time -= days; // now it is days in this year, starting at 0
-
- days = 0;
- month = 0;
- monthLength = 0;
- for (month = 0; month<12; month++) {
- if (month == 1) { // february
- if (LEAP_YEAR(year)) {
- monthLength = 29;
- }
- else {
- monthLength = 28;
- }
- }
- else {
- monthLength = monthDays[month];
- }
-
- if (time >= monthLength) {
- time -= monthLength;
- }
- else {
- break;
- }
- }
- tm.Month = month + 1; // jan is month 1
- tm.Day = time + 1; // day of month
- }
-
- __attribute__((__optimize__("O2")))
- timestamp_t makeTimestamp(const tmElements_t &tm) {
- // assemble time elements into timestamp_t
- // note year argument is offset from 1970 (see macros in time.h to convert to other formats)
- // previous version used full four digit year (or digits since 2000),i.e. 2009 was 2009 or 9
-
- int i;
- uint32_t seconds;
-
- // seconds from 1970 till 1 jan 00:00:00 of the given year
- seconds = tm.Year*(SECS_PER_DAY * 365);
- for (i = 0; i < tm.Year; i++) {
- if (LEAP_YEAR(i)) {
- seconds += SECS_PER_DAY; // add extra days for leap years
- }
- }
-
- // add days for this year, months start from 1
- for (i = 1; i < tm.Month; i++) {
- if ((i == 2) && LEAP_YEAR(tm.Year)) {
- seconds += SECS_PER_DAY * 29;
- }
- else {
- seconds += SECS_PER_DAY * monthDays[i - 1]; //monthDay array starts from 0
- }
- }
- seconds += (tm.Day - 1) * SECS_PER_DAY;
- seconds += tm.Hour * SECS_PER_HOUR;
- seconds += tm.Minute * SECS_PER_MIN;
- seconds += tm.Second;
- return (timestamp_t)seconds;
- }
- /*=====================================================*/
- /* Low level system time functions */
-
- //TODO : + and - operator between tmElements_t and timestamp_t
|