選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

132 行
4.7 KiB

  1. #include "Time2.h"
  2. /*==============================================================================*/
  3. /* Useful Constants */
  4. #define SECS_PER_MIN (60UL)
  5. #define SECS_PER_HOUR (3600UL)
  6. #define SECS_PER_DAY (SECS_PER_HOUR * 24UL)
  7. #define DAYS_PER_WEEK (7UL)
  8. #define SECS_PER_WEEK (SECS_PER_DAY * DAYS_PER_WEEK)
  9. #define SECS_PER_YEAR (SECS_PER_WEEK * 52UL)
  10. #define SECS_YR_2000 (946684800UL) // the time at the start of y2k
  11. /* Useful Macros for getting elapsed time */
  12. #define numberOfSeconds(_time_) (_time_ % SECS_PER_MIN)
  13. #define numberOfMinutes(_time_) ((_time_ / SECS_PER_MIN) % SECS_PER_MIN)
  14. #define numberOfHours(_time_) (( _time_% SECS_PER_DAY) / SECS_PER_HOUR)
  15. #define dayOfWeek(_time_) ((( _time_ / SECS_PER_DAY + 4) % DAYS_PER_WEEK)+1) // 1 = Sunday
  16. #define elapsedDays(_time_) ( _time_ / SECS_PER_DAY) // this is number of days since Jan 1 1970
  17. #define elapsedSecsToday(_time_) (_time_ % SECS_PER_DAY) // the number of seconds since last midnight
  18. // The following macros are used in calculating alarms and assume the clock is set to a date later than Jan 1 1971
  19. // Always set the correct time before settting alarms
  20. #define previousMidnight(_time_) (( _time_ / SECS_PER_DAY) * SECS_PER_DAY) // time at the start of the given day
  21. #define nextMidnight(_time_) ( previousMidnight(_time_) + SECS_PER_DAY ) // time at the end of the given day
  22. #define elapsedSecsThisWeek(_time_) (elapsedSecsToday(_time_) + ((dayOfWeek(_time_)-1) * SECS_PER_DAY) ) // note that week starts on day 1
  23. #define previousSunday(_time_) (_time_ - elapsedSecsThisWeek(_time_)) // time at the start of the week for the given time
  24. #define nextSunday(_time_) ( previousSunday(_time_)+SECS_PER_WEEK) // time at the end of the week for the given time
  25. /* Useful Macros for converting elapsed time to a timestamp_t */
  26. #define minutesTotimestamp_t ((M)) ( (M) * SECS_PER_MIN)
  27. #define hoursTotimestamp_t ((H)) ( (H) * SECS_PER_HOUR)
  28. #define daysTotimestamp_t ((D)) ( (D) * SECS_PER_DAY) // fixed on Jul 22 2011
  29. #define weeksTotimestamp_t ((W)) ( (W) * SECS_PER_WEEK)
  30. // leap year calulator expects year argument as years offset from 1970
  31. #define LEAP_YEAR(Y) ( ((1970+Y)>0) && !((1970+Y)%4) && ( ((1970+Y)%100) || !((1970+Y)%400) ) )
  32. 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
  33. __attribute__((__optimize__("O2")))
  34. void breakTime(timestamp_t timeInput, tmElements_t &tm) {
  35. // break the given timestamp_t into time components
  36. // this is a more compact version of the C library localtime function
  37. // note that year is offset from 1970 !!!
  38. uint8_t year;
  39. uint8_t month, monthLength;
  40. uint32_t time;
  41. unsigned long days;
  42. time = (uint32_t)timeInput;
  43. tm.Second = time % 60;
  44. time /= 60; // now it is minutes
  45. tm.Minute = time % 60;
  46. time /= 60; // now it is hours
  47. tm.Hour = time % 24;
  48. time /= 24; // now it is days
  49. tm.Wday = ((time + 4) % 7) + 1; // Sunday is day 1
  50. year = 0;
  51. days = 0;
  52. while ((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= time) {
  53. year++;
  54. }
  55. tm.Year = year; // year is offset from 1970
  56. days -= LEAP_YEAR(year) ? 366 : 365;
  57. time -= days; // now it is days in this year, starting at 0
  58. days = 0;
  59. month = 0;
  60. monthLength = 0;
  61. for (month = 0; month<12; month++) {
  62. if (month == 1) { // february
  63. if (LEAP_YEAR(year)) {
  64. monthLength = 29;
  65. }
  66. else {
  67. monthLength = 28;
  68. }
  69. }
  70. else {
  71. monthLength = monthDays[month];
  72. }
  73. if (time >= monthLength) {
  74. time -= monthLength;
  75. }
  76. else {
  77. break;
  78. }
  79. }
  80. tm.Month = month + 1; // jan is month 1
  81. tm.Day = time + 1; // day of month
  82. }
  83. __attribute__((__optimize__("O2")))
  84. timestamp_t makeTime(tmElements_t &tm) {
  85. // assemble time elements into timestamp_t
  86. // note year argument is offset from 1970 (see macros in time.h to convert to other formats)
  87. // previous version used full four digit year (or digits since 2000),i.e. 2009 was 2009 or 9
  88. int i;
  89. uint32_t seconds;
  90. // seconds from 1970 till 1 jan 00:00:00 of the given year
  91. seconds = tm.Year*(SECS_PER_DAY * 365);
  92. for (i = 0; i < tm.Year; i++) {
  93. if (LEAP_YEAR(i)) {
  94. seconds += SECS_PER_DAY; // add extra days for leap years
  95. }
  96. }
  97. // add days for this year, months start from 1
  98. for (i = 1; i < tm.Month; i++) {
  99. if ((i == 2) && LEAP_YEAR(tm.Year)) {
  100. seconds += SECS_PER_DAY * 29;
  101. }
  102. else {
  103. seconds += SECS_PER_DAY * monthDays[i - 1]; //monthDay array starts from 0
  104. }
  105. }
  106. seconds += (tm.Day - 1) * SECS_PER_DAY;
  107. seconds += tm.Hour * SECS_PER_HOUR;
  108. seconds += tm.Minute * SECS_PER_MIN;
  109. seconds += tm.Second;
  110. return (timestamp_t)seconds;
  111. }
  112. /*=====================================================*/
  113. /* Low level system time functions */
  114. //TODO : + and - operator between tmElements_t and timestamp_t