Code:
// date.h ///////////////////////////////////////////////////
#ifndef DATE_H_
#define DATA_H_
typedef struct {
int year; // 1800 and above (because of dayOfWeek)
int month; // 1 to 12
int day; // 1 to max for month (and leap year status)
} Date;
Date * Date_new (int year, int month, int day);
void Date_delete (Date **date);
void Date_print (Date *date);
int Date_isLeapYear (Date *date);
const char *Date_dayOfWeek (Date *date);
#endif
// date.c ///////////////////////////////////////////////////
#include "date.h"
#include <stdio.h>
#include <stdlib.h>
static const char * const month_names[] = {
"January", "February", "March", "April",
"May", "June", "July", "August",
"September", "October", "November", "December"
};
static const char * const day_names[] = {
"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"
};
static const int month_lengths[] = {
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
static int isLeapYear(int y) {
return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0;
}
int Date_isLeapYear(Date *date) {
return isLeapYear(date->year);
}
// Somewhat cheesy day-of-week algorithm.
// Only works from year 1800 on.
// January 1, 1800 is a Wednesday (day 3)
const char *Date_dayOfWeek(Date *date) {
int y = date->year - 1800;
int d = 3 + y * 365 + y / 4 - y / 100 + (y + 200) / 400;
for (int m = 0; m < date->month - 1; m++)
d += month_lengths[m];
if (date->month <= 2 && isLeapYear(date->year))
d--; // remove leap day that was added previously
d += date->day - 1;
return day_names[d % 7];
}
Date *Date_new(int year, int month, int day) {
if (year < 1800) {
printf("bad year\n");
return NULL;
}
if (month < 1 || month > 12) {
printf("bad month\n");
return NULL;
}
if (day < 1 || day > month_lengths[month-1]
+ (month==2 && isLeapYear(year))) {
printf("bad day\n");
return NULL;
}
Date *date = malloc(sizeof *date);
date->year = year;
date->month = month;
date->day = day;
return date;
}
void Date_delete(Date **date) {
free(*date);
*date = NULL;
}
void Date_print(Date *date) {
printf("%s %d, %d\n", month_names[date->month - 1],
date->day, date->year);
}
// main.c ////////////////////////////////////////////////
#include <stdio.h>
#include "date.h"
int main() {
Date *date = NULL;
int y, m, d;
printf("Enter year, month, day: ");
scanf("%d %d %d", &y, &m, &d);
date = Date_new(y, m, d);
if (date == NULL)
return 0;
Date_print(date);
printf("%s\n", Date_dayOfWeek(date));
Date_delete(&date);
return 0;
}