如何在 C 中创建一个计算特定日期的工作日的函数?

问题描述 投票:0回答:2

我正在编写一个 C 程序,它有一个可以保存日期变量的数据结构,但它不适用于工作日。 出现错误:“表达式必须具有整数类型”

该函数是这样构建的,包括一个计算工作日的公式:

void dayOfWeek(sDate date){
    if(date.Month > 3) date.Year = date.Year - 1;
    date.WeekDay = ((date.Day + floor (2.6 * ((date.Month + 9) % 12 + 1) - 0.2) + date.Year % 100 + floor (date.Year % 100 / 4) + floor (date.Year / 400) - 2 * floor (date.Year / 100) - 1) % 7 + 7) % 7 + 1;
}

日期数据结构内容 int 值,如下所示(德语):

typedef enum {So, Mo, Di, Mi, Do, Fr, Sa} eDayofTheWeek;

typedef struct{
    int Day;
    int Month;
    int Year;
    eDayofTheWeek WeekDay;
} sDate;

我尝试将大部分公式设置为一个变量,该变量首先包含模运算符之前的所有内容

int w;
w = ((date.Day + floor (2.6 * ((date.Month + 9) % 12 + 1) - 0.2) + date.Year % 100 + floor (date.Year % 100 / 4) + floor (date.Year / 400) - 2 * floor (date.Year / 100) - 1);
date.Weekday =( w % 7 + 7) % 7 + 1;

这只导致工作日值为0。其他公式也让值为0。

c dayofweek
2个回答
1
投票

您可能在某些未显示的代码中做错了。

这对我来说效果很好:

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

typedef enum { So, Mo, Di, Mi, Do, Fr, Sa } eDayofTheWeek;

int main()
{
  int Day = 5;
  int Month = 12;
  int Year = 2023;
  int w = (Day + floor(2.6 * ((Month + 9) % 12 + 1) - 0.2) + Year % 100 + floor(Year % 100 / 4) + floor(Year / 400) - 2 * floor(Year / 100) - 1);
  
  int Weekday = (w % 7 + 7) % 7 + 1;
  printf("Weekday = %d\n", Weekday);

  eDayofTheWeek WeekDay = Weekday;
  // add more test code here.
  // maybe the problem is in your test code you didn't show
}

我得到的输出:

Weekday = 2

这对我来说看起来是正确的,2 是星期二。但不要问我这个公式为什么以及如何运作。


0
投票

正如其他人指出的那样,查找星期几并不是一件容易的事。通常我喜欢修改海报的代码并用它来回答,但是这个计算有很多内容:它很复杂。

这里有一个解决方案,用于发现以前开发的工作日。它有丰富的注释,希望能解释您需要知道的一切:它为什么起作用,它是如何工作的,等等。

可以在这里获取可运行的代码以显示其工作原理。

希望有帮助。

#include <stdio.h>

// Boolean Macro for determining if year argument is a leap year.
// Principle: Each year evenly divisible by 4 is a leap year with the
//            exception of centennials - only centennials evenly divisible
//            by 400 are leap years.
#define IS_LEAP_YEAR(yr) (!((yr)%400) || (!((yr)%4) && (((yr)%100)))  )

int month_days[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
char *ascii_days[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};


/*------------------------------------------------------------------------
 
 weekday()
 
 Purpose: Given the date, month, and year, return a value (0-6) for
           which day of the week, where **** 0 = Monday. ****

 Params: date, month, and year integers
 
 Notes: uses global month_days[] array and IS_LEAP_YEAR macro

*------------------------------------------------------------------------*/
static int weekday(long date, long month, long year)
{
long days, wkday ,  mn;
long num_lp_yrs;

    /* Notice we say,  "year-1" because this param year is not complete and hence not counted. 
    */
    num_lp_yrs = (year-1)/4;  /* How many leap years since the year zero and param? One every 4 yrs, but...*/
    num_lp_yrs -= (year-1)/100; /*...centennials are not leap years...*/
    num_lp_yrs += (year-1)/400;   /*...unless that centennial is a multiple of 400*/
    days = (year-1)*365 + num_lp_yrs; /*total number of days*/

    /* Now, let's get the days spent of the param (incomplete) year 
    * by examining month and day of the year */
    mn = month;
    if(mn < 0)  /*loop safety*/
        mn=0;

    /* Tick off each month by adding applicable days per month from the days-per-month array */
    while(mn--)
    {
        days += month_days[(int)mn];
    }

    /* If this is a leap year and we are past Feb, better add Feb 29th 
    * (Feb = 28 in our fixed, std-year array)*/
    if(IS_LEAP_YEAR(year) && month > 2)
    {
        days++;
    }

    /* Finally, add in the date given. 
    ** NOTE:  Say "date-1" if you want week starting Monday (Mon = 0). 
    **       This is a crude way to cause Sunday to be skipped.
    **       Just say "date" for Sun = 0 */
    days += date;

    /* 7 days in a week, so... modulo nicely tells the weekday*/
    wkday = days%7;

    return (int)wkday;
}


int main() 
{
    int day_of_week = weekday(5, 12, 2023);
    char *sDay = ascii_days[day_of_week];

    printf("Week day is: %s\n", sDay);

    return 0;
}

输出:

Week day is: Tue
© www.soinside.com 2019 - 2024. All rights reserved.