C Program to find day of week given date

后端 未结 14 1310
梦谈多话
梦谈多话 2020-11-29 05:14

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

相关标签:
14条回答
  • 2020-11-29 05:14

    Not in one line of code, there's nothing for dealing with dates in the C standard library. It would be fairly simple to write a function based on the Doomsday algorithm, or similar, though.

    0 讨论(0)
  • 2020-11-29 05:17

    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 :)

    0 讨论(0)
  • 2020-11-29 05:17
    #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

    0 讨论(0)
  • 2020-11-29 05:18
    /*
    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();
    }
    
    0 讨论(0)
  • 2020-11-29 05:19

    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
    
    0 讨论(0)
  • 2020-11-29 05:29

    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).

    0 讨论(0)
提交回复
热议问题