From fa7df64f523968c9e9d679950943befe45460269 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Mon, 11 Jun 2012 10:05:24 +1000 Subject: [PATCH] Calculating the day of week from a date --- libraries/RTC/RTC.cpp | 41 ++++++++++++++++++++++ libraries/RTC/RTC.h | 13 +++++++ libraries/RTC/examples/DumpRTC/DumpRTC.pde | 5 +++ libraries/RTC/examples/TestRTC/TestRTC.pde | 5 +++ 4 files changed, 64 insertions(+) diff --git a/libraries/RTC/RTC.cpp b/libraries/RTC/RTC.cpp index 83c6e906..4edfa6bf 100644 --- a/libraries/RTC/RTC.cpp +++ b/libraries/RTC/RTC.cpp @@ -66,6 +66,21 @@ static uint8_t monthLengths[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; +static unsigned int monthOffsets[] = { + 0, + 31, + 31 + 28, + 31 + 28 + 31, + 31 + 28 + 31 + 30, + 31 + 28 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 +}; + inline bool isLeapYear(unsigned int year) { if ((year % 100) == 0) @@ -368,6 +383,32 @@ void RTC::adjustYears(RTCDate *date, uint8_t flags) date->day = len; } +/** + * \enum RTC::DayOfWeek + * \brief Day of the week corresponding to a date. + * + * \sa dayOfWeek() + */ + +/** + * \brief Returns the day of the week corresponding to \a date. + * + * This function is only guaranteed to produce meaningful values + * for years between 2000 and 2099. + */ +RTC::DayOfWeek RTC::dayOfWeek(const RTCDate *date) +{ + // The +4 here adjusts for Jan 1, 2000 being a Saturday. + unsigned long daynum = date->day + 4; + daynum += monthOffsets[date->month - 1]; + if (date->month > 2 && isLeapYear(date->year)) + ++daynum; + daynum += 365UL * (date->year - 2000); + if (date->year > 2000) + daynum += ((date->year - 2001) / 4) + 1; + return (DayOfWeek)((daynum % 7) + 1); +} + /** * \class RTCTime RTC.h * \brief Stores time information from a realtime clock chip. diff --git a/libraries/RTC/RTC.h b/libraries/RTC/RTC.h index 923287d7..9338ab3a 100644 --- a/libraries/RTC/RTC.h +++ b/libraries/RTC/RTC.h @@ -52,6 +52,17 @@ public: RTC(); ~RTC(); + enum DayOfWeek + { + Monday = 1, + Tuesday, + Wednesday, + Thursday, + Friday, + Saturday, + Sunday, + }; + virtual bool hasUpdates(); virtual void readTime(RTCTime *value); @@ -82,6 +93,8 @@ public: static void adjustMonths(RTCDate *date, uint8_t flags); static void adjustYears(RTCDate *date, uint8_t flags); + static DayOfWeek dayOfWeek(const RTCDate *date); + private: unsigned long midnight; RTCDate date; diff --git a/libraries/RTC/examples/DumpRTC/DumpRTC.pde b/libraries/RTC/examples/DumpRTC/DumpRTC.pde index d5d2d821..b2aa3645 100644 --- a/libraries/RTC/examples/DumpRTC/DumpRTC.pde +++ b/libraries/RTC/examples/DumpRTC/DumpRTC.pde @@ -11,6 +11,10 @@ This example is placed into the public domain. SoftI2C i2c(A4, A5); DS3232RTC rtc(i2c); +const char *days[] = { + "Mon, ", "Tue, ", "Wed, ", "Thu, ", "Fri, ", "Sat, ", "Sun, " +}; + const char *months[] = { " Jan ", " Feb ", " Mar ", " Apr ", " May ", " Jun ", " Jul ", " Aug ", " Sep ", " Oct ", " Nov ", " Dec " @@ -52,6 +56,7 @@ void loop() { Serial.println(); Serial.print("Date: "); + Serial.print(days[RTC::dayOfWeek(&date) - 1]); Serial.print(date.day, DEC); Serial.print(months[date.month - 1]); Serial.print(date.year); diff --git a/libraries/RTC/examples/TestRTC/TestRTC.pde b/libraries/RTC/examples/TestRTC/TestRTC.pde index 3c440086..bf458eb2 100644 --- a/libraries/RTC/examples/TestRTC/TestRTC.pde +++ b/libraries/RTC/examples/TestRTC/TestRTC.pde @@ -38,6 +38,10 @@ DS3232RTC rtc(i2c); char buffer[64]; size_t buflen; +const char *days[] = { + "Mon, ", "Tue, ", "Wed, ", "Thu, ", "Fri, ", "Sat, ", "Sun, " +}; + const char *months[] = { " Jan ", " Feb ", " Mar ", " Apr ", " May ", " Jun ", " Jul ", " Aug ", " Sep ", " Oct ", " Nov ", " Dec " @@ -192,6 +196,7 @@ void cmdDate(const char *args) // Read the current date. rtc.readDate(&date); + Serial.print(days[RTC::dayOfWeek(&date) - 1]); Serial.print(date.day, DEC); Serial.print(months[date.month - 1]); Serial.println(date.year, DEC);