Adafruit_RTCLib
Fork of Adafruit_RTCLib by
DateTime.cpp@0:7f90c8e04249, 2012-07-17 (annotated)
- Committer:
- nkhorman
- Date:
- Tue Jul 17 05:49:20 2012 +0000
- Revision:
- 0:7f90c8e04249
land the adafruit rtc library with changes for LPC1768
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
nkhorman | 0:7f90c8e04249 | 1 | // Code by JeeLabs http://news.jeelabs.org/code/ |
nkhorman | 0:7f90c8e04249 | 2 | // Released to the public domain! Enjoy! |
nkhorman | 0:7f90c8e04249 | 3 | |
nkhorman | 0:7f90c8e04249 | 4 | /* |
nkhorman | 0:7f90c8e04249 | 5 | * Taken from https://github.com/adafruit/RTClib |
nkhorman | 0:7f90c8e04249 | 6 | * and modified for LPC1768 by Neal Horman July 2012 |
nkhorman | 0:7f90c8e04249 | 7 | */ |
nkhorman | 0:7f90c8e04249 | 8 | |
nkhorman | 0:7f90c8e04249 | 9 | #include "DateTime.h" |
nkhorman | 0:7f90c8e04249 | 10 | |
nkhorman | 0:7f90c8e04249 | 11 | #define SECONDS_PER_DAY 86400L |
nkhorman | 0:7f90c8e04249 | 12 | #define SECONDS_FROM_1970_TO_2000 946684800 |
nkhorman | 0:7f90c8e04249 | 13 | |
nkhorman | 0:7f90c8e04249 | 14 | //////////////////////////////////////////////////////////////////////////////// |
nkhorman | 0:7f90c8e04249 | 15 | // utility code, some of this could be exposed in the DateTime API if needed |
nkhorman | 0:7f90c8e04249 | 16 | |
nkhorman | 0:7f90c8e04249 | 17 | static const uint8_t daysInMonth [] = { 31,28,31,30,31,30,31,31,30,31,30,31 }; //has to be const or compiler compaints |
nkhorman | 0:7f90c8e04249 | 18 | |
nkhorman | 0:7f90c8e04249 | 19 | // number of days since 2000/01/01, valid for 2001..2099 |
nkhorman | 0:7f90c8e04249 | 20 | static uint16_t date2days(uint16_t y, uint8_t m, uint8_t d) |
nkhorman | 0:7f90c8e04249 | 21 | { |
nkhorman | 0:7f90c8e04249 | 22 | if (y >= 2000) |
nkhorman | 0:7f90c8e04249 | 23 | y -= 2000; |
nkhorman | 0:7f90c8e04249 | 24 | |
nkhorman | 0:7f90c8e04249 | 25 | uint16_t days = d; |
nkhorman | 0:7f90c8e04249 | 26 | for (uint8_t i = 1; i < m; ++i) |
nkhorman | 0:7f90c8e04249 | 27 | days += daysInMonth[i - 1]; |
nkhorman | 0:7f90c8e04249 | 28 | |
nkhorman | 0:7f90c8e04249 | 29 | if (m > 2 && y % 4 == 0) |
nkhorman | 0:7f90c8e04249 | 30 | ++days; |
nkhorman | 0:7f90c8e04249 | 31 | |
nkhorman | 0:7f90c8e04249 | 32 | return days + 365 * y + (y + 3) / 4 - 1; |
nkhorman | 0:7f90c8e04249 | 33 | } |
nkhorman | 0:7f90c8e04249 | 34 | |
nkhorman | 0:7f90c8e04249 | 35 | static long time2long(uint16_t days, uint8_t h, uint8_t m, uint8_t s) |
nkhorman | 0:7f90c8e04249 | 36 | { |
nkhorman | 0:7f90c8e04249 | 37 | return ((days * 24L + h) * 60 + m) * 60 + s; |
nkhorman | 0:7f90c8e04249 | 38 | } |
nkhorman | 0:7f90c8e04249 | 39 | |
nkhorman | 0:7f90c8e04249 | 40 | //////////////////////////////////////////////////////////////////////////////// |
nkhorman | 0:7f90c8e04249 | 41 | // DateTime implementation - ignores time zones and DST changes |
nkhorman | 0:7f90c8e04249 | 42 | // NOTE: also ignores leap seconds, see http://en.wikipedia.org/wiki/Leap_second |
nkhorman | 0:7f90c8e04249 | 43 | |
nkhorman | 0:7f90c8e04249 | 44 | DateTime::DateTime (uint32_t t) |
nkhorman | 0:7f90c8e04249 | 45 | { |
nkhorman | 0:7f90c8e04249 | 46 | t -= SECONDS_FROM_1970_TO_2000; // bring to 2000 timestamp from 1970 |
nkhorman | 0:7f90c8e04249 | 47 | |
nkhorman | 0:7f90c8e04249 | 48 | ss = t % 60; |
nkhorman | 0:7f90c8e04249 | 49 | t /= 60; |
nkhorman | 0:7f90c8e04249 | 50 | mm = t % 60; |
nkhorman | 0:7f90c8e04249 | 51 | t /= 60; |
nkhorman | 0:7f90c8e04249 | 52 | hh = t % 24; |
nkhorman | 0:7f90c8e04249 | 53 | |
nkhorman | 0:7f90c8e04249 | 54 | uint16_t days = t / 24; |
nkhorman | 0:7f90c8e04249 | 55 | uint8_t leap; |
nkhorman | 0:7f90c8e04249 | 56 | |
nkhorman | 0:7f90c8e04249 | 57 | for (yOff = 0; ; ++yOff) |
nkhorman | 0:7f90c8e04249 | 58 | { |
nkhorman | 0:7f90c8e04249 | 59 | leap = yOff % 4 == 0; |
nkhorman | 0:7f90c8e04249 | 60 | if (days < 365 + leap) |
nkhorman | 0:7f90c8e04249 | 61 | break; |
nkhorman | 0:7f90c8e04249 | 62 | days -= 365 + leap; |
nkhorman | 0:7f90c8e04249 | 63 | } |
nkhorman | 0:7f90c8e04249 | 64 | |
nkhorman | 0:7f90c8e04249 | 65 | for (m = 1; ; ++m) |
nkhorman | 0:7f90c8e04249 | 66 | { |
nkhorman | 0:7f90c8e04249 | 67 | uint8_t daysPerMonth = daysInMonth[m - 1]; |
nkhorman | 0:7f90c8e04249 | 68 | |
nkhorman | 0:7f90c8e04249 | 69 | if (leap && m == 2) |
nkhorman | 0:7f90c8e04249 | 70 | ++daysPerMonth; |
nkhorman | 0:7f90c8e04249 | 71 | if (days < daysPerMonth) |
nkhorman | 0:7f90c8e04249 | 72 | break; |
nkhorman | 0:7f90c8e04249 | 73 | days -= daysPerMonth; |
nkhorman | 0:7f90c8e04249 | 74 | } |
nkhorman | 0:7f90c8e04249 | 75 | d = days + 1; |
nkhorman | 0:7f90c8e04249 | 76 | } |
nkhorman | 0:7f90c8e04249 | 77 | |
nkhorman | 0:7f90c8e04249 | 78 | DateTime::DateTime (uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec) |
nkhorman | 0:7f90c8e04249 | 79 | { |
nkhorman | 0:7f90c8e04249 | 80 | if (year >= 2000) |
nkhorman | 0:7f90c8e04249 | 81 | year -= 2000; |
nkhorman | 0:7f90c8e04249 | 82 | yOff = year; |
nkhorman | 0:7f90c8e04249 | 83 | m = month; |
nkhorman | 0:7f90c8e04249 | 84 | d = day; |
nkhorman | 0:7f90c8e04249 | 85 | hh = hour; |
nkhorman | 0:7f90c8e04249 | 86 | mm = min; |
nkhorman | 0:7f90c8e04249 | 87 | ss = sec; |
nkhorman | 0:7f90c8e04249 | 88 | } |
nkhorman | 0:7f90c8e04249 | 89 | |
nkhorman | 0:7f90c8e04249 | 90 | static uint8_t conv2d(const char* p) |
nkhorman | 0:7f90c8e04249 | 91 | { uint8_t v = 0; |
nkhorman | 0:7f90c8e04249 | 92 | |
nkhorman | 0:7f90c8e04249 | 93 | if ('0' <= *p && *p <= '9') |
nkhorman | 0:7f90c8e04249 | 94 | v = *p - '0'; |
nkhorman | 0:7f90c8e04249 | 95 | |
nkhorman | 0:7f90c8e04249 | 96 | return 10 * v + *++p - '0'; |
nkhorman | 0:7f90c8e04249 | 97 | } |
nkhorman | 0:7f90c8e04249 | 98 | |
nkhorman | 0:7f90c8e04249 | 99 | // A convenient constructor for using "the compiler's time": |
nkhorman | 0:7f90c8e04249 | 100 | // DateTime now (__DATE__, __TIME__); |
nkhorman | 0:7f90c8e04249 | 101 | // NOTE: using PSTR would further reduce the RAM footprint |
nkhorman | 0:7f90c8e04249 | 102 | DateTime::DateTime (const char* date, const char* time) |
nkhorman | 0:7f90c8e04249 | 103 | { |
nkhorman | 0:7f90c8e04249 | 104 | // sample input: date = "Dec 26 2009", time = "12:34:56" |
nkhorman | 0:7f90c8e04249 | 105 | yOff = conv2d(date + 9); |
nkhorman | 0:7f90c8e04249 | 106 | // Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec |
nkhorman | 0:7f90c8e04249 | 107 | switch (date[0]) |
nkhorman | 0:7f90c8e04249 | 108 | { |
nkhorman | 0:7f90c8e04249 | 109 | case 'J': m = date[1] == 'a' ? 1 : m = date[2] == 'n' ? 6 : 7; break; |
nkhorman | 0:7f90c8e04249 | 110 | case 'F': m = 2; break; |
nkhorman | 0:7f90c8e04249 | 111 | case 'A': m = date[2] == 'r' ? 4 : 8; break; |
nkhorman | 0:7f90c8e04249 | 112 | case 'M': m = date[2] == 'r' ? 3 : 5; break; |
nkhorman | 0:7f90c8e04249 | 113 | case 'S': m = 9; break; |
nkhorman | 0:7f90c8e04249 | 114 | case 'O': m = 10; break; |
nkhorman | 0:7f90c8e04249 | 115 | case 'N': m = 11; break; |
nkhorman | 0:7f90c8e04249 | 116 | case 'D': m = 12; break; |
nkhorman | 0:7f90c8e04249 | 117 | } |
nkhorman | 0:7f90c8e04249 | 118 | |
nkhorman | 0:7f90c8e04249 | 119 | d = conv2d(date + 4); |
nkhorman | 0:7f90c8e04249 | 120 | hh = conv2d(time); |
nkhorman | 0:7f90c8e04249 | 121 | mm = conv2d(time + 3); |
nkhorman | 0:7f90c8e04249 | 122 | ss = conv2d(time + 6); |
nkhorman | 0:7f90c8e04249 | 123 | } |
nkhorman | 0:7f90c8e04249 | 124 | |
nkhorman | 0:7f90c8e04249 | 125 | uint8_t DateTime::dayOfWeek() const |
nkhorman | 0:7f90c8e04249 | 126 | { uint16_t day = date2days(yOff, m, d); |
nkhorman | 0:7f90c8e04249 | 127 | |
nkhorman | 0:7f90c8e04249 | 128 | return (day + 6) % 7; // Jan 1, 2000 is a Saturday, i.e. returns 6 |
nkhorman | 0:7f90c8e04249 | 129 | } |
nkhorman | 0:7f90c8e04249 | 130 | |
nkhorman | 0:7f90c8e04249 | 131 | uint32_t DateTime::unixtime(void) const |
nkhorman | 0:7f90c8e04249 | 132 | { uint16_t days = date2days(yOff, m, d); |
nkhorman | 0:7f90c8e04249 | 133 | |
nkhorman | 0:7f90c8e04249 | 134 | return time2long(days, hh, mm, ss) + SECONDS_FROM_1970_TO_2000; // seconds from 1970 to 2000 |
nkhorman | 0:7f90c8e04249 | 135 | } |
nkhorman | 0:7f90c8e04249 | 136 | |
nkhorman | 0:7f90c8e04249 | 137 | #ifdef WANT_RTC_MILLIS |
nkhorman | 0:7f90c8e04249 | 138 | //////////////////////////////////////////////////////////////////////////////// |
nkhorman | 0:7f90c8e04249 | 139 | // RTC_Millis implementation |
nkhorman | 0:7f90c8e04249 | 140 | |
nkhorman | 0:7f90c8e04249 | 141 | long RTC_Millis::offset = 0; |
nkhorman | 0:7f90c8e04249 | 142 | |
nkhorman | 0:7f90c8e04249 | 143 | void RTC_Millis::adjust(const DateTime& dt) |
nkhorman | 0:7f90c8e04249 | 144 | { |
nkhorman | 0:7f90c8e04249 | 145 | offset = dt.unixtime() - millis() / 1000; |
nkhorman | 0:7f90c8e04249 | 146 | } |
nkhorman | 0:7f90c8e04249 | 147 | |
nkhorman | 0:7f90c8e04249 | 148 | DateTime RTC_Millis::now() |
nkhorman | 0:7f90c8e04249 | 149 | { |
nkhorman | 0:7f90c8e04249 | 150 | return (uint32_t)(offset + millis() / 1000); |
nkhorman | 0:7f90c8e04249 | 151 | } |
nkhorman | 0:7f90c8e04249 | 152 | |
nkhorman | 0:7f90c8e04249 | 153 | //////////////////////////////////////////////////////////////////////////////// |
nkhorman | 0:7f90c8e04249 | 154 | #endif |