Fixed: I had to do it with a pointer to call the values(I also changed the formular but I´m sure the old one would also work. The problem was the missing pointer):
sAppointment Calendar[MAXAPPOINTMENTS];
int dayOfWeek(sDate *date){
static int jMonth[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
int d = date->Day;
int m = date->Month;
int y = date->Year;
if(m < 3) y--;
return(y + (y/4) - (y/100) + (y/400) + jMonth[m - 1] + d) % 7;
}
I am writing a C Program which has a datastructure in which the variables of a date can be saved but it does not work for the weekday. It appears an error: "expression must have integral type"
The function is build like this, including a formular to calculate the weekday:
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;
}
The date datastructure contents int values which looks like this (german language):
typedef enum {So, Mo, Di, Mi, Do, Fr, Sa} eDayofTheWeek;
typedef struct{
int Day;
int Month;
int Year;
eDayofTheWeek WeekDay;
} sDate;
I tried to set most of the formular to a variable which first containts everything before the modulo operator
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;
This only led to the weekday value being 0. Other formulars also let the value of being 0.
OP's code has at least these problems:
No update for caller
void dayOfWeek(sDate date){
does not provide any result back to the caller ("This only led to the weekday value being 0"). Instead, pass by reference.
void dayOfWeek(sDate *date) {
// ^
%
not valid with floating point
Before applying %
, convert the value to an int
. Note: C does not has a modulo operator but a remainder operator.
Wrong test
// if(date.Month > 3) date.Year = date.Year - 1;
if(date.Month < 3) { date.Year = date.Year - 1; maybe adjust Month }
I was unable to fully fix OP's code.
Consider avoiding one-liner code and instead provide more clarity.
Below works for month and day outside the usual range.
#define MARCH 3
#define DaysPer400Years (400*365LL + 97)
#define DaysPer100Years (100*365LL + 24)
#define DaysPer4Years (4*365LL + 1)
#define DaysPer1Year 365LL
#define DayNumber1970Jan1 719469
#define MonthsPerYear 12
long long DayNumber0(int year, int Month, int Day, long epoch) {
long long dn = Day;
long long y = year;
y += Month / 12;
Month %= 12;
while (Month < MARCH) {
Month += 12;
y--;
}
// And then a miracle occurs. Scale by 30.59375 and add an offset.
dn += ((Month - MARCH) * (7832 / 4) + (140 / 4)) >> (8 - 2);
dn += (y / 400) * DaysPer400Years;
y %= 400;
dn += (y / 100) * DaysPer100Years;
y %= 100;
dn += (y / 4) * DaysPer4Years;
y %= 4;
dn += y * DaysPer1Year;
return dn - epoch;
}
int WeekDay_chux(int year, int Month, int Day) {
#define WEEK_JAN1AD1_OFFSET 5
int dow = DayNumber0(year, Month, Day, WEEK_JAN1AD1_OFFSET) % 7;
return (dow + 7 )%7;
}
Note that DaysPer400Years
is a multiple of 7 (for the Gregorian Calendar). Thus we can take short cuts and start with year %= 400
to work with smaller numbers.