Program to find the day of the week for a given date

  • Post author:
  • Post last modified:December 19, 2023
  • Reading time:4 mins read

1.0 Day of Week

The Gregorian calendar was adopted in 1582. The formula to find the day of the week for any date after 1582 is,

d = N + ⌊2.6M - 0.2⌋ + Y + ⌊Y/4⌋ + ⌊C/4⌋ - 2C 
    - (1 + L)⌊M/11⌋ (mod 7)

where,
d is the day of the week. d is 0 for Sunday, 1 for Monday, …, 6 for Saturday.
N is the day of the month.
M is the month. M = 1 for March, 2 for April, …, 10 for December, 11 for January and 12 for February.
Y is the last two digits of the year.
C is the first two digits of the year. For example, for the year 2023, C is 20 and Y is 23.
L is 1 for leap years, 0 otherwise. Any year divisible by 4 and not divisible by 100 is a leap year. However, the years divisible by 400 are also leap years. For example, the years 1992, 2000 and 2016 are leap years whereas 1800, 1900 and 2023 are not.

2.0 Example Program

An example program in C implementing the above formula is given below. We have a function, day_of_week (), which takes in day, month and year as integers, dd, mm and yyyy. The month argument is the usual 1 for January, 2 for February, …, and 12 for December.

// day_of_week.c: find the day of the week for a given date

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int day_of_week (int day, int month, int year) // returns 0 for Sunday, 1 for Monday ...
{
    int N = day;
    int M = (month <= 2) ? month + 10 : month - 2;
    int C = year / 100;
    int Y = year % 100;
    int L = year % 4 == 0 && year % 100 != 0 || year % 400 == 0;

    int temp = N + floor (2.6 * M - 0.2) + Y + floor (Y / 4) + floor (C / 4)
	    - 2 * C - (1 + L) * floor (M / 11);
    // if temp is negative, add a multiple of 7 to make it positive
    if (temp < 0) {
	int n = ceil ((double) (abs (temp)) / 7);
	temp += 7 * n;
    }
    return temp % 7;
}


#define BUFFER_SIZE 1024
char buffer [BUFFER_SIZE];

int main (int argc, char *argv [])
{
    int day, month, year;

    printf ("Date (dd mm yyyy) : ");
    while (fgets (buffer, sizeof (buffer), stdin)) {
        sscanf (buffer, "%d %d %d", &day, &month, &year);
	int weekday = day_of_week (day, month, year);
	switch (weekday) {
            case 0: printf ("Sunday\n");
		    break;
            case 1: printf ("Monday\n");
		    break;
            case 2: printf ("Tuesday\n");
		    break;
            case 3: printf ("Wednesday\n");
		    break;
            case 4: printf ("Thursday\n");
		    break;
            case 5: printf ("Friday\n");
		    break;
            case 6: printf ("Saturday\n");
		    break;
            default: printf ("Error (%d)\n", weekday);

	}
	printf ("Date (dd mm yyyy) : ");
    }
    printf ("\n");
    return 0;
}

In most cases, the expression temp is positive and temp mod 7 is calculated as temp % 7, giving the day of the week. However, in some cases, especially for the dates at start of a century, like January 1, 1900, or January 1, 2000, the expression temp becomes negative. In these cases, we add a multiple of 7 to it to make it a positive number, and then the % operator can be used for finding the modulus.

We can compile and run the above program.

$ gcc day_of_week.c -o day_of_week -lm
$ ./day_of_week 
Date (dd mm yyyy) : 11 11 2023
Saturday
Date (dd mm yyyy) : 1 1 2000
Saturday
Date (dd mm yyyy) : 29 02 1984
Wednesday
Date (dd mm yyyy) : 1 1 2100
Friday
Date (dd mm yyyy) : 
$ 

3.0 Reference

  • Ivan Niven, Herbert S. Zuckerman and Hugh L. Montgomery, An Introduction to the Theory of Numbers, Fifth Edition, Wiley, 1991.
Share

Karunesh Johri

Software developer, working with C and Linux.