我正在编写一个 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。
您可能在某些未显示的代码中做错了。
这对我来说效果很好:
#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 是星期二。但不要问我这个公式为什么以及如何运作。
正如其他人指出的那样,查找星期几并不是一件容易的事。通常我喜欢修改海报的代码并用它来回答,但是这个计算有很多内容:它很复杂。
这里有一个解决方案,用于发现以前开发的工作日。它有丰富的注释,希望能解释您需要知道的一切:它为什么起作用,它是如何工作的,等等。
可以在这里获取可运行的代码以显示其工作原理。
希望有帮助。
#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