I am using MCP7940 RTC from microchip it requires to enter the day of the week as part of updating RTC with date. So how should I calculate day of the week based on the date provided by the user?
4 Answers
If you want to calculate the day-of-week yourself, here's a C implementation of part of a Perl module I wrote about 20 years ago. I like this algorithm because it doesn't require any looping or a table of month lengths. Note that int
s are assumed to be 32 bits.
/* Returns the number of days to the start of the specified year, taking leap
* years into account, but not the shift from the Julian calendar to the
* Gregorian calendar. Instead, it is as though the Gregorian calendar is
* extrapolated back in time to a hypothetical "year zero".
*/
int leap (int year)
{
return year*365 + (year/4) - (year/100) + (year/400);
}
/* Returns a number representing the number of days since March 1 in the
* hypothetical year 0, not counting the change from the Julian calendar
* to the Gregorian calendar that occured in the 16th century. This
* algorithm is loosely based on a function known as "Zeller's Congruence".
* This number MOD 7 gives the day of week, where 0 = Monday and 6 = Sunday.
*/
int zeller (int year, int month, int day)
{
year += ((month+9)/12) - 1;
month = (month+9) % 12;
return leap (year) + month*30 + ((6*month+5)/10) + day + 1;
}
/* Returns the day of week (1=Monday, 7=Sunday) for a given date.
*/
int dow (int year, int month, int day)
{
return (zeller (year, month, day) % 7) + 1;
}

- 168,369
- 17
- 228
- 393
-
A table with the number of days from March 1 to the first day of a given month would probably end up being smaller and faster than the code to evaluate the given formula, especially if one is only interested in dates in the range 2000-2099. – supercat Mar 13 '15 at 01:36
-
@supercat: Why don't you show us what that code would look like? – Dave Tweed Mar 13 '15 at 01:42
According to the datasheet at address 0x03 in table 4-1 there is a field 'Day'. At the end of the line there is a short description:
\begin{array}{|c|c|c|} \text{Address} & \text{Bit7:3} & \text{Bit2:0} & \text{Function} & \text{Range} \\ \hline \text{0x03}&\text{...}&\text{Day}&\text{Day}&\text{1-7} \end{array}
This means that the day can be set to any number ranging from 1 through 7. You can pick your own convention which day of the week is. On POSIX systems Monday is defined as 1, I think that is a good standard. Then Tuesday = 2; Wednesday = 3; ...
Day = 0 is not documented, so don't use it.
On Linux this number can easily be found using the command date +%u
, which today answers 6
as it is saturday. If you want to calculate this locally on your PIC, you'll have to find the C-library that implements the formula, I believe strftime
in <time.h>
does just that, but I'm not enough C programmer to explain how to use that particular library. It is a commonly used library, so documentation is easy to find.

- 33,033
- 16
- 93
- 160
-
1Monday is also day 1 (Sunday day 7) in the ISO-8601 international standard. – Joris Groosman Feb 04 '16 at 08:29
Day of week is Arbitrary. You define it. You could use the Julian Sunday = Day 1. You could use Monday as Day 1 because Sunday is the 7th day. You could use Friday as Day 1 because it's the first day of the weekend. You could use Tuesday as Day 1 because you hate Mondays.

- 72,580
- 7
- 90
- 202
-
3This is not an answer. It seems to be a rant of some sort, but I can't figure out what the point is. The original question was how to get from a particular date to the correct day of the week. – Dave Tweed Apr 20 '13 at 16:09
-
@DaveTweed I'm explaining that the Day of the Week is arbitrary. It has no fixed meaning to the RTC. Until OP defines what he believes Day 1 would be, it's impossible to get the "correct day of the week" as you put it. – Passerby Apr 20 '13 at 16:17
-
1If you believe the question was incomplete, then this should have been posted as a comment, not an answer. – Dave Tweed Apr 20 '13 at 17:28
-
1The fact that it's arbitrary doesn't mean that it can't be calculated, once you set your standard. – Joris Groosman Feb 04 '16 at 08:31
I suggest you use the RTClib library
#include <Wire.h>
#include "RTClib.h"
RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
void setup () {
Serial.begin(9600);
delay(3000); // wait for console opening
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
if (rtc.lostPower()) {
Serial.println("RTC lost power, lets set the time!");
// Comment out below lines once you set the date & time.
// Following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// Following line sets the RTC with an explicit date & time
// for example to set January 27 2017 at 12:56 you would call:
// rtc.adjust(DateTime(2017, 1, 27, 12, 56, 0));
}
}
void loop () {
DateTime now = rtc.now();
Serial.println("Current Date & Time: ");
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(" (");
Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
Serial.print(") ");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
Serial.println("Unix Time: ");
Serial.print("elapsed ");
Serial.print(now.unixtime());
Serial.print(" seconds/");
Serial.print(now.unixtime() / 86400L);
Serial.println(" days since 1/1/1970");
// calculate a date which is 7 days & 30 seconds into the future
DateTime future (now + TimeSpan(7,0,0,30));
Serial.println("Future Date & Time (Now + 7days & 30s): ");
Serial.print(future.year(), DEC);
Serial.print('/');
Serial.print(future.month(), DEC);
Serial.print('/');
Serial.print(future.day(), DEC);
Serial.print(' ');
Serial.print(future.hour(), DEC);
Serial.print(':');
Serial.print(future.minute(), DEC);
Serial.print(':');
Serial.print(future.second(), DEC);
Serial.println();
Serial.println();
delay(1000);
}

- 8,705
- 21
- 30
- 42
-
-
1OK, so you tell to use some random library but fail to mention from where this library is available and under what circumstances it can be used, such as supported platforms or software license. – Justme Jul 23 '22 at 08:58