C Program to find day of week given date
Asked Answered
G

18

18

Is there a way to find out day of the week given date in just one line of C code?

For example

Given 19-05-2011(dd-mm-yyyy) gives me Thursday

Greenburg answered 19/5, 2011 at 5:6 Comment(3)
See Zeller's congruence for an explicit formula to calculate the day of the week. And I'm not aware of any limit on the length of lines in C, so you can reformat any program to fit into one line...Kurzawa
I believe you always need some anchor, i.e. a date for which you know the day of week, e.g. "1 Jan 1900 was a Monday" in @maerics's answer. I suppose that other suggested algorithms have such an anchore built-inModicum
Check this link. It also contains an explanation of how the calculation is done. Hope it helps. cprogramming.language-tutorial.com/2012/01/…Kino
N
18

A one-liner is unlikely, but the strptime function can be used to parse your date format and the struct tm argument can be queried for its tm_wday member on systems that modify those fields automatically (e.g. some glibc implementations).

int get_weekday(char * str) {
  struct tm tm;
  memset((void *) &tm, 0, sizeof(tm));
  if (strptime(str, "%d-%m-%Y", &tm) != NULL) {
    time_t t = mktime(&tm);
    if (t >= 0) {
      return localtime(&t)->tm_wday; // Sunday=0, Monday=1, etc.
    }
  }
  return -1;
}

Or you could encode these rules to do some arithmetic in a really long single line:

  • 1 Jan 1900 was a Monday.
  • Thirty days has September, April, June and November; all the rest have thirty-one, saving February alone, which has twenty-eight, rain or shine, and on leap years, twenty-nine.
  • A leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400.

EDIT: note that this solution only works for dates after the UNIX epoch (1970-01-01T00:00:00Z).

Nightstick answered 19/5, 2011 at 5:11 Comment(0)
C
32

As reported also by Wikipedia, in 1990 Michael Keith and Tom Craver published an expression to minimise the number of keystrokes needed to enter a self-contained function for converting a Gregorian date into a numerical day of the week.

The expression does preserve neither y nor d, and returns a zero-based index representing the day, starting with Sunday, i.e. if the day is Monday the expression returns 1.

A code example which uses the expression follows:

int d    = 15   ; //Day     1-31
int m    = 5    ; //Month   1-12`
int y    = 2013 ; //Year    2013` 

int weekday  = (d += m < 3 ? y-- : y - 2, 23*m/9 + d + 4 + y/4- y/100 + y/400)%7;  

The expression uses the comma operator, as discussed in this answer.

Enjoy! ;-)

Caudad answered 20/1, 2014 at 13:40 Comment(1)
This code appears to be wrong. I made a sketch to compare 3 codes, and it gave an error: github.com/arduino-libraries/RTCZero/issues/…Sextant
N
18

A one-liner is unlikely, but the strptime function can be used to parse your date format and the struct tm argument can be queried for its tm_wday member on systems that modify those fields automatically (e.g. some glibc implementations).

int get_weekday(char * str) {
  struct tm tm;
  memset((void *) &tm, 0, sizeof(tm));
  if (strptime(str, "%d-%m-%Y", &tm) != NULL) {
    time_t t = mktime(&tm);
    if (t >= 0) {
      return localtime(&t)->tm_wday; // Sunday=0, Monday=1, etc.
    }
  }
  return -1;
}

Or you could encode these rules to do some arithmetic in a really long single line:

  • 1 Jan 1900 was a Monday.
  • Thirty days has September, April, June and November; all the rest have thirty-one, saving February alone, which has twenty-eight, rain or shine, and on leap years, twenty-nine.
  • A leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400.

EDIT: note that this solution only works for dates after the UNIX epoch (1970-01-01T00:00:00Z).

Nightstick answered 19/5, 2011 at 5:11 Comment(0)
Z
9

Here's a C99 version based on wikipedia's article about Julian Day

#include <stdio.h>

const char *wd(int year, int month, int day) {
  /* using C99 compound literals in a single line: notice the splicing */
  return ((const char *[])                                         \
          {"Monday", "Tuesday", "Wednesday",                       \
           "Thursday", "Friday", "Saturday", "Sunday"})[           \
      (                                                            \
          day                                                      \
        + ((153 * (month + 12 * ((14 - month) / 12) - 3) + 2) / 5) \
        + (365 * (year + 4800 - ((14 - month) / 12)))              \
        + ((year + 4800 - ((14 - month) / 12)) / 4)                \
        - ((year + 4800 - ((14 - month) / 12)) / 100)              \
        + ((year + 4800 - ((14 - month) / 12)) / 400)              \
        - 32045                                                    \
      ) % 7];
}

int main(void) {
  printf("%d-%02d-%02d: %s\n", 2011, 5, 19, wd(2011, 5, 19));
  printf("%d-%02d-%02d: %s\n", 2038, 1, 19, wd(2038, 1, 19));
  return 0;
}

By removing the splicing and spaces from the return line in the wd() function, it can be compacted to a 286 character single line :)

Zambrano answered 19/5, 2011 at 10:45 Comment(8)
cool. I guess the JND formula uses some built-in knowledge of day of week of any other date, like January 1, 4713 BC? I don't think you can do it without some anchorModicum
Yes, of course. The main thing is to be able to generate a sequential value for successive dates. Once you get that, you "adjust" the value to a known date by tweaking the -32045 part of the calculation. You can use the same formula with a different adjustment value and create the "davka day number" :-)Zambrano
Why on earth are there all the backslashes at the ends of the lines in the code? None of them are necessary; this isn't a macro, and it isn't a string constant.Replicate
@JonathanLeffler: the op wanted "just one line of C code"Zambrano
This function isn't a macro. Nuke the \Exhibit
@Barry: I tried to write "just one line of C code" as op wanted. The \ keeps my code in a single line but with a format that looks line it's multi line.Zambrano
The one-line version works in programs compiled as c99. Why would this version be preferable?Acriflavine
@DavidPetersonHarvey: you're right. There's no advantage in the 2nd version. Deleted (it's in the Edits history)Zambrano
C
1

This is my implementation. It's very short and includes error checking. If you want dates before 01-01-1900, you could easily change the anchor to the starting date of the Gregorian calendar.

#include <stdio.h>

int main(int argv, char** arv) {
    int month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    char* day[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};   
    int d, m, y, i; 

    printf("Fill in a date after 01-01-1900 as dd-mm-yyyy: ");
    scanf("%d-%d-%d",  &d, &m, &y);

    // correction for leap year
    if (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))
        month[1] = 29;

    if (y < 1900 || m < 1 || m > 12 || d < 1 || d > month[m - 1]) {
        printf("This is an invalid date.\n");
        return 1;
    }

    for (i = 1900; i < y; i++)
        if (i % 4 == 0 && (i % 100 != 0 || i % 400 == 0))
            d += 366;
        else
            d += 365;

    for (i = 0; i < m - 1; i++) 
        d += month[i];

    printf("This is a %s.\n", day[d % 7]);
    return 0;
}
Creolacreole answered 4/12, 2011 at 14:39 Comment(0)
S
1

The answer I came up with:

const int16_t TM_MON_DAYS_ACCU[12] = {
    0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
};

int tm_is_leap_year(unsigned year) {
    return ((year & 3) == 0) && ((year % 400 == 0) || (year % 100 != 0));
}

// The "Doomsday" the the day of the week of March 0th,
// i.e the last day of February.
// In common years January 3rd has the same day of the week,
// and on leap years it's January 4th.
int tm_doomsday(int year) {
    int result;
    result  = TM_WDAY_TUE;
    result += year;       // I optimized the calculation a bit:
    result += year >>= 2; // result += year / 4
    result -= year /= 25; // result += year / 100
    result += year >>= 2; // result += year / 400
    return result;
}

void tm_get_wyday(int year, int mon, int mday, int *wday, int *yday) {
    int is_leap_year = tm_is_leap_year(year);
    // How many days passed since Jan 1st?
    *yday = TM_MON_DAYS_ACCU[mon] + mday + (mon <= TM_MON_FEB ? 0 : is_leap_year) - 1;
    // Which day of the week was Jan 1st of the given year?
    int jan1 = tm_doomsday(year) - 2 - is_leap_year;
    // Now just add these two values.
    *wday = (jan1 + *yday) % 7;
}

with these defines (matching struct tm of time.h):

#define TM_WDAY_SUN 0
#define TM_WDAY_MON 1
#define TM_WDAY_TUE 2
#define TM_WDAY_WED 3
#define TM_WDAY_THU 4
#define TM_WDAY_FRI 5
#define TM_WDAY_SAT 6

#define TM_MON_JAN  0
#define TM_MON_FEB  1
#define TM_MON_MAR  2
#define TM_MON_APR  3
#define TM_MON_MAY  4
#define TM_MON_JUN  5
#define TM_MON_JUL  6
#define TM_MON_AUG  7
#define TM_MON_SEP  8
#define TM_MON_OCT  9
#define TM_MON_NOV 10
#define TM_MON_DEC 11
Steamheated answered 14/5, 2014 at 20:46 Comment(2)
I would definitely use enum's instead those #define's - with the inherent comment that some people recommend not to use the numerical values of enum's. Any reason you chose #define's? I am just trying to learn smth.Coronado
I am aware that "MON" comes from the standard (short for "month"), but for a few good seconds I wondered why you cared about the MONdays of different months :)Coronado
U
1
#include<stdio.h>
#include<math.h>
#include<conio.h>
int fm(int date, int month, int year) {
int fmonth, leap;
if ((year % 100 == 0) && (year % 400 != 0))
leap = 0;
   else if (year % 4 == 0)
  leap = 1;
else
  leap = 0;

  fmonth = 3 + (2 - leap) * ((month + 2) / (2 * month))+ (5 * month + month / 9) / 2;

 fmonth = fmonth % 7;

  return fmonth;
}
int day_of_week(int date, int month, int year) {

   int dayOfWeek;
   int YY = year % 100;
   int century = year / 100;

   printf("\nDate: %d/%d/%d \n", date, month, year);

   dayOfWeek = 1.25 * YY + fm(date, month, year) + date - 2 * (century % 4);

   //remainder on division by 7
   dayOfWeek = dayOfWeek % 7;

   switch (dayOfWeek) {
      case 0:
         printf("weekday = Saturday");
         break;
      case 1:
         printf("weekday = Sunday");
         break;
      case 2:
         printf("weekday = Monday");
         break;
      case 3:
         printf("weekday = Tuesday");
         break;
      case 4:
         printf("weekday = Wednesday");
         break;
      case 5:
         printf("weekday = Thursday");
         break;
      case 6:
         printf("weekday = Friday");
         break;
      default:
         printf("Incorrect data");
   }
   return 0;
}
int main() {
   int date, month, year;

   printf("\nEnter the year ");
   scanf("%d", &year);

   printf("\nEnter the month ");
   scanf("%d", &month);

   printf("\nEnter the date ");
   scanf("%d", &date);

   day_of_week(date, month, year);

   return 0;
}

OUTPUT: Enter the year 2012

Enter the month 02

Enter the date 29

Date: 29/2/2012

weekday = Wednesday

Ungotten answered 11/10, 2014 at 12:12 Comment(0)
P
1

This is question 20.31 in the C FAQ list. It lists three answers, two of which are amenable to one-liners.

  1. Modified Zeller's congruence: j = y/100; k = y%100; dow = (d + 26 * (m + 1) / 10 + k + k/4 + j/4 + 5*j) % 7;

  2. Tomohiko Sakamoto's method: static int t[] = {0,3,2,5,0,3,5,1,4,6,2,4}; y -= m < 3; dow = (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;

There's a further condensation of Sakamoto's method using an ASCII string instead of the t array: dow = (y + y/4 - y/100 + y/400 + "-bed=pen+mad."[m] + d) % 7;

The basic idea underlying all of these methods is the same: boil the date down to a monotonically-increasing sequence of day numbers (taking month lengths and leap years into account), then reduce that day number modulo 7.

Petronille answered 12/9, 2021 at 12:11 Comment(0)
S
1

I would like to leave this observation: I made a sketch (Arduino) to compare 3 codes, and one gave an error: 27-01-2021: (Wednesday) x (Saturday) x (Wednesday)

It may be interesting to test the codes before using:

// Get weekday codes comparison, by Rtek1000
#include "Time.h"

char daysOfWeek[7][10] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  Serial.println("\r\nStart");

  char line1[30] = { 0 };

  for (uint16_t y = 1970; y < 2100; y++) {
    for (byte m = 1; m < 12; m++) {
      for (byte d = 1; d < 28; d++) {
        byte wd0 = get_weekday_time_lib(d, m, y);
        byte wd1 = getDayOfWeek(d, m, y);
        byte wd2 = get_weekday(d, m, y);

        if ((wd0 != wd1) || (wd0 != wd2) || (wd1 != wd2)) {
          sprintf(line1, "%02d-%02d-%04u: ",
                  d, m, y);
          Serial.print(line1);

          Serial.print(" - Fail - wd0 (time lib):");
          Serial.print(wd0, DEC);
          Serial.print(" (");
          Serial.print(daysOfWeek[wd0 - 1]);
          Serial.print(") wd1:");
          Serial.print(wd1, DEC);
          Serial.print(" (");
          Serial.print(daysOfWeek[wd1 - 1]);
          Serial.print(") wd2:");
          Serial.print(wd2, DEC);
          Serial.print(" (");
          Serial.print(daysOfWeek[wd2 - 1]);
          Serial.println(")");

          while (1)
            ;
        }
      }
    }

    Serial.print("Year: ");
    Serial.println(y);
  }
}

void loop() {
  // put your main code here, to run repeatedly:
}

time_t t;
tmElements_t tm;

uint8_t get_weekday_time_lib(byte d, byte m, uint16_t yyyy) {
  tm.Year = CalendarYrToTm(yyyy);
  tm.Month = m;
  tm.Day = d;
  tm.Hour = 12;
  tm.Minute = 0;
  tm.Second = 0;

  t = makeTime(tm);

  return weekday(t);
}

// source: // http://stackoverflow.com/a/21235587
// returns 0=Sunday, etc
uint8_t getDayOfWeek(byte d, byte m, uint16_t yyyy) {
  return ((d += m < 3 ? yyyy-- : yyyy - 2, 23 * m / 9 + d + 4 + yyyy / 4 - yyyy / 100 + yyyy / 400) % 7) + 1;
}

// source: https://www.hackster.io/erikuchama/day-of-the-week-calculator-cde704
byte get_weekday(byte d, byte m, uint16_t yyyy) {
  int yy = 0;          // Last 2 digits of the year (ie 2016 would be 16)
  int c = 0;           // Century (ie 2016 would be 20)
  int mTable = 0;      // Month value based on calculation table
  int SummedDate = 0;  // Add values combined in prep for Mod7 calc
  int DoW = 0;         // Day of the week value (0-6)
  int leap = 0;        // Leap Year or not
  int cTable = 0;      // Century value based on calculation table

  // Leap Year Calculation
  if ((fmod(yyyy, 4) == 0 && fmod(yyyy, 100) != 0) || (fmod(yyyy, 400) == 0)) {
    leap = 1;
  } else {
    leap = 0;
  }

  // Limit results to year 1900-2299 (to save memory)
  while (yyyy > 2299) { yyyy = yyyy - 400; }
  while (yyyy < 1900) { yyyy = yyyy + 400; }

  // Calculating century
  c = yyyy / 100;

  // Calculating two digit year
  yy = fmod(yyyy, 100);

  // Century value based on Table
  if (c == 19) { cTable = 1; }
  if (c == 20) { cTable = 0; }
  if (c == 21) { cTable = 5; }
  if (c == 22) { cTable = 3; }

  // Jan and Feb calculations affected by leap years
  if (m == 1) {
    if (leap == 1) {
      mTable = 6;
    } else {
      mTable = 0;
    }
  }
  if (m == 2) {
    if (leap == 1) {
      mTable = 2;
    } else {
      mTable = 3;
    }
  }
  // Other months not affected and have set values
  if (m == 10) { mTable = 0; }
  if (m == 8) { mTable = 2; }
  if (m == 3 || m == 11) { mTable = 3; }
  if (m == 4 || m == 7) { mTable = 6; }
  if (m == 5) { mTable = 1; }
  if (m == 6) { mTable = 4; }
  if (m == 9 || m == 12) { mTable = 5; }

  // Enter the data into the formula
  SummedDate = d + mTable + yy + (yy / 4) + cTable;

  // Find remainder
  DoW = fmod(SummedDate, 7);  // 0-6

  // // Remainder determines day of the week
  // if(DoW == 0) { Serial.println("Saturday"); }
  // if(DoW == 1) { Serial.println("Sunday"); }
  // if(DoW == 2) { Serial.println("Monday"); }
  // if(DoW == 3) { Serial.println("Tuesday"); }
  // if(DoW == 4) { Serial.println("Wednesday"); }
  // if(DoW == 5) { Serial.println("Thursday"); }
  // if(DoW == 6) { Serial.println("Friday"); }

  if (DoW == 0) {  // Saturday?
    DoW = 7;
  }

  return DoW;  // 1-7
}

Tested on Arduino UNO (NANO, PRO MINI or any Arduino with ATmega328).

Ref.: https://github.com/arduino-libraries/RTCZero/issues/31#issuecomment-1937779178

Sextant answered 11/2 at 15:15 Comment(0)
P
0

I think you can find that in glib: http://developer.gnome.org/glib/unstable/glib-Date-and-Time-Functions.html#g-date-get-day

Regards

Primus answered 19/5, 2011 at 5:11 Comment(0)
M
0

This one works: I took January 2006 as a reference. (It is a Sunday)

int isLeapYear(int year) {

     if(((year%4==0)&&(year%100!=0))||((year%400==0))) 
        return 1;
     else 
        return 0;

 }

int isDateValid(int dd,int mm,int yyyy) {

    int isValid=-1; 
    if(mm<0||mm>12) {
        isValid=-1;
    }
    else {

    if((mm==1)||(mm==3)||(mm==5)||(mm==7)||(mm==8)||(mm==10)||(mm==12)) {
           if((dd>0)&&(dd<=31))
             isValid=1;
    }  else if((mm==4)||(mm==6)||(mm==9)||(mm==11)) {
         if((dd>0)&&(dd<=30))
             isValid=1;
    }  else {
             if(isLeapYear(yyyy)){
                 if((dd>0)&&dd<30)
                     isValid=1;
             } else {
                   if((dd>0)&&dd<29)
                     isValid=1;
             }
        }  



    }
               return isValid;



 }


int calculateDayOfWeek(int dd,int mm,int yyyy)  {

                if(isDateValid(dd,mm,yyyy)==-1) {
                    return -1;
                }

                 int days=0;
                  int i; 

                   for(i=yyyy-1;i>=2006;i--) {
                         days+=(365+isLeapYear(i));

                     }
                     printf("days after years is %d\n",days);

                   for(i=mm-1;i>0;i--) {

                       if((i==1)||(i==3)||(i==5)||(i==7)||(i==8)||(i==10)) {

                           days+=31;
                       }
                       else if((i==4)||(i==6)||(i==9)||(i==11)) {
                           days+=30;
                       } else {

                           days+= (28+isLeapYear(i));

                       }


                   }
                       printf("days after months is %d\n",days);

                   days+=dd;

                   printf("days after days is %d\n",days);

                   return ((days-1)%7);                


              }
Moth answered 8/7, 2011 at 18:51 Comment(0)
O
0
#include<stdio.h>
static char day_tab[2][13] = {
        {0,31,28,31,30,31,30,31,31,30,31,30,31},
        {0,31,29,31,30,31,30,31,31,30,31,30,31}
        };
int main()
{
     int year,month;
     scanf("%d%d%d",&year,&month,&day);
     printf("%d\n",day_of_year(year,month,day));
     return 0;
}
int day_of_year(int year ,int month,int day)
{
        int i,leap;
        leap = year%4 == 0 && year%100 != 0 || year%400 == 0;
        if(month < 1 || month >12)
        return -1;
        if (day <1 || day > day_tab[leap][month])
        return -1;
        for(i= 1;i<month ; i++)
        {
                day += day_tab[leap][year];
        }
        return day;
}
Oraliaoralie answered 2/7, 2013 at 11:17 Comment(0)
B
0
/*
Program to calculate the day on a given date by User
*/

#include<stdio.h>
#include<conio.h>
#include<process.h>
void main()
{
int dd=0,mm=0,i=0,yy=0,odd1=0,todd=0;//variable declaration for inputing the date
int remyr=0,remyr1=0,lyrs=0,oyrs=0,cyr=0,upyr=0,leap=0;//variable declaration for calculation of odd days
int montharr[12]={31,28,31,30,31,30,31,31,30,31,30,31};//array of month days
clrscr();
printf("Enter the date as DD-MM-YY for which you want to know the day\t:");
scanf("%d%d%d",&dd,&mm,&yy);  //input the date
/*
check out correct date or not?
*/
if(yy%100==0)
    {
    if(yy%400==0)
        {
        //its the leap year
        leap=1;
        if(dd>29&&mm==2)
            {

            printf("You have entered wrong date");
            getch();
            exit(0);
            }
        }
    else if(dd>28&&mm==2)
        {
        //not the leap year
        printf("You have entered wrong date");
        getch();
        exit(0);

        }
    }
else if(yy%4==0)
    {
    //again leap year
    leap=1;
    if(dd>29&mm==2)
        {
        printf("You have entered wrong date");
        getch();
        exit(0);

        }
    }
else if(dd>28&&mm==2)
    {
    //not the leap year
    printf("You have entered wrong date");
    getch();
    exit(0);

    }
//if the leap year feb month contains 29 days
if(leap==1)
{
montharr[1]=29;

}
//check date,month,year should not be beyond the limits

if((mm>12)||(dd>31)|| (yy>5000))
    {
    printf("Your date is wrong");
    getch();
    exit(0);

    }
//odd months should not contain more than 31 days
if((dd>31 && (mm == 1||mm==3||mm==5||mm==7||mm==8||mm==10||mm==12)))
    {
    printf("Your date is wrong");
    getch();
    exit(0);

    }
//even months should not contains more than 30 days

if((dd>30 && (mm == 4||mm==6||mm==9||mm==11)))
    {
    printf("Your date is wrong");
    getch();
    exit(0);

    }

//logic to calculate odd days.....
printf("\nYou have entered date: %d-%d-%d ",dd,mm,yy);
remyr1=yy-1;
remyr=remyr1%400;

cyr=remyr/100;
if(remyr==0)
    {
    oyrs=0;
    }
else if(cyr==0 && remyr>0)
    {
    oyrs=0;
    }


else if(cyr==1)
    {
    oyrs=5;
    }
else if(cyr==2)
    {
    oyrs=3;
    }
else if(cyr==3)
    {
    oyrs=1;
    }

    upyr=remyr%100;
    lyrs=upyr/4;
    odd1=lyrs+upyr;
    odd1=odd1%7;
    odd1=odd1+oyrs;
    for(i=0;i<mm-1;i++)
        {
        odd1=odd1+montharr[i];
        }
    todd=odd1+dd;
    if(todd>7)
        todd=todd%7;    //total odd days gives the re quired day....
    printf("\n\nThe day on %d-%d-%d :",dd,mm,yy);

    if(todd==0)
        printf("Sunday");
    if(todd==1)
        printf("Monday");
    if(todd==2)
        printf("Tuesday");
    if(todd==3)
        printf("Wednesday");
    if(todd==4)
        printf("Thrusday");
    if(todd==5)
        printf("Friday");
    if(todd==6)
        printf("Saturday");
getch();
}
Bighorn answered 13/5, 2014 at 5:13 Comment(0)
L
0

Here is a simple code that I created in c that should fix your problem :

#include <conio.h>

int main()
{
  int y,n,oy,ly,td,a,month,mon_,d,days,down,up; // oy==ordinary year, td=total days, d=date

    printf("Enter the year,month,date: ");
    scanf("%d%d%d",&y,&month,&d);
    n= y-1; //here we subtracted one year because we have to find on a particular day of that year, so we will not count whole year.
    oy= n%4;

    if(oy==0) // for leap year
      {
         mon_= month-1;
         down= mon_/2;  //down means months containing 30 days.
           up= mon_-down; // up means months containing 31 days.
           if(mon_>=2)
             {
               days=(up*31)+((down-1)*30)+29+d; // here in down case one month will be of feb so we subtracted 1 and after that seperately
               td= (oy*365)+(ly*366)+days;      // added 29 days as it is the if block of leap year case.
             }
           if(mon_==1)
             {
               days=(up*31)+d;
               td= (oy*365)+(ly*366)+days;
             } 
           if(mon_==0)
             {
               days= d;
               td= (oy*365)+(ly*366)+days;
             }    
      }
    else
      {
         mon_= month-1;
         down= mon_/2;
           up= mon_-down;
           if(mon_>=2)
             {
               days=(up*31)+((down-1)*30)+28+d;
               td= (oy*365)+(ly*366)+days;
             }
           if(mon_==1)
             {
               days=(up*31)+d;
               td= (oy*365)+(ly*366)+days;
             } 
           if(mon_==0)
             {
               days= d;
               td= (oy*365)+(ly*366)+days;
             }    
      }  

    ly= n/4;
     a= td%7;

     if(a==0)
       printf("\nSunday");
     if(a==1)
       printf("\nMonday");
     if(a==2)
       printf("\nTuesday");
     if(a==3)
       printf("\nWednesday");
     if(a==4)
       printf("\nThursday");
     if(a==5)
       printf("\nFriday");
     if(a==6)
       printf("\nSaturday");
  return 0;   
}
Lions answered 24/4, 2018 at 9:53 Comment(1)
Please explain your lines of code so other users can understand its functionalityWorshipful
T
0

For Day of Week, years 2000 - 2099.

uint8_t rtc_DayOfWeek(uint8_t year, uint8_t month, uint8_t day)
{
    //static const uint8_t month_offset_table[] = {0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5}; // Typical table.

    // Added 1 to Jan, Feb. Subtracted 1 from each instead of adding 6 in calc below.

    static const uint8_t month_offset_table[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};

    // Year is 0 - 99, representing years 2000 - 2099

    // Month starts at 0.

    // Day starts at 1.

    // Subtract 1 in calc for Jan, Feb, only in leap years.
    // Subtracting 1 from year has the effect of subtracting 2 in leap years, subtracting 1 otherwise.
    // Adding 1 for Jan, Feb in Month Table so calc ends up subtracting 1 for Jan, Feb, only in leap years.
    // All of this complication to avoid the check if it is a leap year.
    if (month < 2) {
        year--;
    }

    // Century constant is 6. Subtract 1 from Month Table, so difference is 7.

    // Sunday (0), Monday (1) ...

    return (day + month_offset_table[month] + year + (year >> 2)) % 7;

} /* end rtc_DayOfWeek() */
Trimmer answered 2/5, 2018 at 22:3 Comment(0)
L
0

I wrote a small function to do this in C inspired by Conway's doomsday algorithm.

It was written with 8-bit microcontrollers in mind and the "year" argument is a year from 0 to 99 only (representing 2000 to 2099). I wrote it to compile down nice and small on avr-gcc. It uses no lookup table (I got the code smaller without).

// day of week, Thomas Rutter
// y should be a year 0 to 99 (meaning 2000 to 2099)
// m and d are 1-based (1-12, 1-31)
// returns 0 = sunday, ..., 6 = saturday

uint8_t dayofweek(uint8_t y, uint8_t m, uint8_t d)
{
    uint8_t x = y + 24 - (m < 3);
    x = x + (x >> 2) + d - m;
    if (m & 1)
        x += (m & 8) ? 4 : 3;
    if (m < 3)
        x += 3;

    return x % 7;
}

In my own version, the mod operator at the bottom was replaced with my own optimised code as the platform I was using has no MUL or DIV and I wanted it 1 to 7 instead of 0 to 6.

This could be adapted to work with other centuries or specify the year in full - I just didn't need to do so for my own use.

Lanam answered 12/9, 2021 at 11:41 Comment(0)
S
0

See strftime and %u or %w qualifiers

Solutrean answered 12/9, 2021 at 13:51 Comment(0)
J
0

note that this solution only works for Unix time after the UNIX epoch (1970-01-01T00:00:00Z).

#include<stdio.h>
#include<time.h>

static const char wday_name[][4] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
#define DoWi(t) ((int)((t)/86400+4)%7)   // Day of Week as integer:  Sun=0, Mon=1, Tue=2, ...
#define DoWs(t) wday_name[DoWi(t)]       // Day of Week as string:  Sun, Mon, Tue, ...

int main()
{
    time_t t; 

    time (&t);
    printf ("The current time is: %s", ctime (&t));
    printf ("Day of week is: %d %s", DoWi(t), DoWs(t));

    return 0;
}

sample output:

The current time is: Sat Mar  2 08:59:28 2024
Day of week is: 6 Sat
Juieta answered 2/3 at 9:3 Comment(0)
D
-2
#include<stdio.h>
int main(void) {
int n,y;
int ly=0;
int mon;
printf("enter the date\n");
scanf("%d",&n);
printf("enter the month in integer\n");
scanf("%d",&mon);
mon=mon-1;
printf("enter year\n");
scanf("%d",&y);
int dayT;
dayT=n%7;
if((y%4==0&&y%100!=0)|(y%4==0&&y%100==0&&y%400==0))
{
    ly=y;
    printf("the given year is a leap year\n");
}
char a[12]={6,2,2,5,0,3,5,1,4,6,2,4};
if(ly!=0)
{
    a[0]=5;
    a[1]=1;
}
int m,p;
m=a[mon];
int i,j=0,t=1;
for(i=1600;i<=3000;i++)
{
 i=i+99;
    if(i<y)
    {

        if(t==1)
        {
        p=5;t++;
        }
        else if(t==2)
        {
            p=3;
            t++;
        }
        else if(t==3)
        {
            p=1;
            t++;
        }
        else
        {
            p=0;
            t=1;
        }

}}
int q,r,s;
q=y%100;
r=q%7;
s=q/4;
int yTerm;
yTerm=p+r+s;
int w=dayT+m+yTerm;
w=w%7;
if(w==0)
printf("SUNDAY");
else if(w==1)
printf("MONDAY");
else if(w==2)
printf("TUESDAY");
else if(w==3)
printf("WEDNESDAY");
else if(w==4)
printf("THURSDAY");
else if(w==5)
printf("FRIDAY");
else
printf("SATURDAY");
return 0;

}

Degeneration answered 18/1, 2017 at 14:8 Comment(3)
Please make an edit to explain your code. At this time this is a code dump. When providing an answer please explain why your answer is right.Degradable
youtube.com/… this link will give all things to understand this program.....thats the base algorithmDegeneration
@SurajSunny: Please consider editing your answer to include a summary of the information provided in the youtube link. Stack Overflow expects your answer to be independent of any links. See meta.stackoverflow.com/q/8259Radman

© 2022 - 2024 — McMap. All rights reserved.