Adafruit_RTCLib

Fork of Adafruit_RTCLib by Neal Horman

Committer:
nkhorman
Date:
Wed Jul 18 01:28:21 2012 +0000
Revision:
1:2c4e81ecda67
Parent:
0:7f90c8e04249
fix / add comments

Who changed what in which revision?

UserRevisionLine numberNew 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