265 lines
6.2 KiB
C
265 lines
6.2 KiB
C
/* ----------------------------------------------------------------------------
|
|
* -- _____ ______ _____ -
|
|
* -- |_ _| | ____|/ ____| -
|
|
* -- | | _ __ | |__ | (___ Institute of Embedded Systems -
|
|
* -- | | | '_ \| __| \___ \ Zuercher Hochschule Winterthur -
|
|
* -- _| |_| | | | |____ ____) | (University of Applied Sciences) -
|
|
* -- |_____|_| |_|______|_____/ 8401 Winterthur, Switzerland -
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
/**
|
|
* @file
|
|
* @brief Lab P02 weekday
|
|
*/
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
|
|
|
|
// *** TASK1: typedef enum types for month_t (Jan=1,...Dec} ***
|
|
// BEGIN-STUDENTS-TO-ADD-CODE
|
|
typedef enum {Jan=1, Feb, Mar, Apr, May, June, July, Aug, Sept, Oct, Nov, Dec} month_t;
|
|
|
|
// END-STUDENTS-TO-ADD-CODE
|
|
|
|
|
|
|
|
// *** TASK1: typedef struct for date_t ***
|
|
// BEGIN-STUDENTS-TO-ADD-CODE
|
|
typedef struct {int year, month, day;} date_t;
|
|
|
|
// END-STUDENTS-TO-ADD-CODE
|
|
|
|
|
|
|
|
// *** TASK2: typedef enum weekday_t (Sun=0, Mon, ...Sat) ***
|
|
// BEGIN-STUDENTS-TO-ADD-CODE
|
|
typedef enum {Sun=0, Mon, Tue, Wed, Thu, Fri, Sat} weekday_t;
|
|
|
|
// END-STUDENTS-TO-ADD-CODE
|
|
|
|
/**
|
|
* @brief TASK1: Checks if the given date is a leap year.
|
|
* @returns 0 = is not leap year, 1 = is leap year
|
|
*/
|
|
// BEGIN-STUDENTS-TO-ADD-CODE
|
|
int is_leap_year(date_t date){
|
|
int ergebnis;
|
|
if(date.year % 400 == 0){
|
|
ergebnis = 1;
|
|
}
|
|
else if (date.year % 100 == 0){
|
|
ergebnis = 0;
|
|
}
|
|
else if(date.year % 4 == 0){
|
|
ergebnis = 1;
|
|
}
|
|
else {
|
|
ergebnis = 0;
|
|
}
|
|
return ergebnis;
|
|
}
|
|
|
|
// END-STUDENTS-TO-ADD-CODE
|
|
|
|
|
|
/**
|
|
* @brief TASK1: Calculates the length of the month given by the data parameter
|
|
* @returns 28, 29, 30, 31 if a valid month, else 0
|
|
*/
|
|
// BEGIN-STUDENTS-TO-ADD-CODE
|
|
int get_month_length(date_t date){
|
|
int ergebnis = 0;
|
|
switch (date.month) {
|
|
case Jan:
|
|
ergebnis = 31;
|
|
break;
|
|
case Feb:
|
|
if(is_leap_year(date)){
|
|
ergebnis = 29;
|
|
}
|
|
else {
|
|
ergebnis = 28;
|
|
}
|
|
break;
|
|
case Mar:
|
|
ergebnis = 31;
|
|
break;
|
|
case Apr:
|
|
ergebnis = 30;
|
|
break;
|
|
case May:
|
|
ergebnis = 31;
|
|
break;
|
|
case June:
|
|
ergebnis = 30;
|
|
break;
|
|
case July:
|
|
ergebnis = 31;
|
|
break;
|
|
case Aug:
|
|
ergebnis = 31;
|
|
break;
|
|
case Sept:
|
|
ergebnis = 30;
|
|
break;
|
|
case Oct:
|
|
ergebnis = 31;
|
|
break;
|
|
case Nov:
|
|
ergebnis = 30;
|
|
break;
|
|
case Dec:
|
|
ergebnis = 31;
|
|
break;
|
|
}
|
|
return ergebnis;
|
|
}
|
|
|
|
// END-STUDENTS-TO-ADD-CODE
|
|
|
|
/**
|
|
* @brief TASK1: Checks if the given date is in the gregorian date range
|
|
* @returns 0 = no, 1 = yes
|
|
*/
|
|
// BEGIN-STUDENTS-TO-ADD-CODE
|
|
int is_gregorian_date(date_t date) {
|
|
int ergebnis = 1;
|
|
if((date.year == 1582 && date.month <= Oct && date.day < 15) || date.year < 1582 || (date.year > 9999)){
|
|
return 0;
|
|
}
|
|
else {
|
|
return 1;
|
|
}
|
|
|
|
}
|
|
|
|
// END-STUDENTS-TO-ADD-CODE
|
|
|
|
|
|
/**
|
|
* @brief TASK1: Checks if the given date is a valid date.
|
|
* @returns 0 = is not valid date, 1 = is valid date
|
|
*/
|
|
// BEGIN-STUDENTS-TO-ADD-CODE
|
|
int is_valid_date(date_t date) {
|
|
int ergebnis = 1;
|
|
int ml = get_month_length(date);
|
|
|
|
|
|
if((int)ml < (int)date.day ){//|| date.month < 1 || date.month > 12 || is_gregorian_date == 0){
|
|
|
|
return 0;
|
|
}
|
|
else {
|
|
printf("Länge Monat: %d\n", get_month_length(date));
|
|
printf("Länge Monat: %d\n", ml);
|
|
printf("Tag: %d\n", date.day);
|
|
printf("Monat: %d\n", date.month);
|
|
printf("Jahr: %d\n", date.year);
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// END-STUDENTS-TO-ADD-CODE
|
|
|
|
|
|
/**
|
|
* @brief TASK2: calculated from a valid date the weekday
|
|
* @returns returns a weekday in the range Sun...Sat
|
|
*/
|
|
// BEGIN-STUDENTS-TO-ADD-CODE
|
|
weekday_t calculate_weekday(date_t date) {
|
|
int m = 1 + (date.month + 9) % 12;
|
|
int a;
|
|
if(date.month < Mar){
|
|
a = date.year - 1;
|
|
}
|
|
else {
|
|
a = date.year;
|
|
}
|
|
int y = a % 100;
|
|
int c = a / 100;
|
|
weekday_t weekday = ((date.day + (13 * m - 1) / 5 + y + y / 4 + c / 4 - 2 * c) % 7 + 7) % 7;
|
|
return weekday;
|
|
}
|
|
|
|
// END-STUDENTS-TO-ADD-CODE
|
|
|
|
|
|
|
|
/**
|
|
* @brief TASK2: print weekday as 3-letter abreviated English day name
|
|
*/
|
|
// BEGIN-STUDENTS-TO-ADD-CODE
|
|
void print_weekday(weekday_t day) {
|
|
int ergebnis = 0;
|
|
switch (day) {
|
|
case Sun:
|
|
printf("Sun");
|
|
break;
|
|
case Mon:
|
|
printf("Mon");
|
|
break;
|
|
case Tue:
|
|
printf("Tue");
|
|
break;
|
|
case Wed:
|
|
printf("Wed");
|
|
break;
|
|
case Thu:
|
|
printf("Thu");
|
|
break;
|
|
case Fri:
|
|
printf("Fri");
|
|
break;
|
|
case Sat:
|
|
printf("Sat");
|
|
break;
|
|
default:
|
|
assert(!"day is out-of-range");
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
// END-STUDENTS-TO-ADD-CODE
|
|
|
|
/**
|
|
* @brief main function
|
|
* @param argc [in] number of entries in argv
|
|
* @param argv [in] program name plus command line arguments
|
|
* @returns returns success if valid date is given, failure otherwise
|
|
*/
|
|
int main(int argc, const char *argv[])
|
|
{
|
|
// TASK1: parse the mandatory argument into a date_t variable and check if the date is valid
|
|
// BEGIN-STUDENTS-TO-ADD-CODE
|
|
date_t date;
|
|
int res = sscanf(argv[1]
|
|
, "%d-%d-%d"
|
|
, &date.year, &date.month, &date.day
|
|
);
|
|
if (res != 3 || is_valid_date(date) == 0) {
|
|
printf("Fehler\n");
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
// END-STUDENTS-TO-ADD-CODE
|
|
|
|
|
|
// TASK2: calculate the weekday and print it in this format: "%04d-%02d-%02d is a %s\n"
|
|
// BEGIN-STUDENTS-TO-ADD-CODE
|
|
printf("%04d-%02d-%02d is a ", date.year, date.month, date.day);
|
|
print_weekday(calculate_weekday(date));
|
|
printf("\n");
|
|
|
|
// END-STUDENTS-TO-ADD-CODE
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|