This is my first post on this forum. I have read the guidelines and will try to adhere to them, but I apologize if I miss something. The code I am posting is intended to duplicate the output of "date -u" in the XV6 OS. It does this, with the exception of dates before the 1700s (This wasn't relevant to the task, and the math is a little different, from what I read). My goal with this post is to seek advice on improving the code in terms of safety and performance, with an emphasis on best practices that I can generalize to future C code (I realize this may not be as doable for something intended to run in XV6). Advice on both my code and better techniques for posting here is appreciated!
#include "types.h"
#include "stat.h"
#include "user.h"
#include "date.h"
int check_leap(int year);
void print_day(int year, int month, int day);
void print_month(int month);
int month_key(int month);
int
main(void)
{
struct rtcdate current_date;
if(date(¤t_date) != 0)
exit();
print_day(current_date.year, current_date.month, current_date.day);
print_month(current_date.month);
printf(1, " %d",current_date.day);
printf(1," %d:%d:%d", current_date.hour, current_date.minute, current_date.second);
printf(1," %d", current_date.year);
printf(1," UTC\n");
exit();
}
int
check_leap(int year)
{
if(year % 4 == 0)
{
if(year % 100 == 0)
{
if(year % 400 == 0)
return 1; //Leap year
}
}
return 0;
}
int
month_key(int month)
{
int key;
switch (month)
{
case 1: key = 1;
break;
case 2: key = 4;
break;
case 3: key = 4;
break;
case 4: key = 0;
break;
case 5: key = 2;
break;
case 6: key = 5;
break;
case 7: key = 0;
break;
case 8: key = 3;
break;
case 9: key = 6;
break;
case 10: key = 1;
break;
case 11: key = 4;
break;
case 12: key = 6;
break;
default: key = -1;
break;
}
return key;
}
void
print_day(int year, int month, int day)
{
int week_day;
int decade = year % 100;
int century = year / 100;
int leap = check_leap(year);
int key = month_key(month);
if(key < 0)
{
printf(1, "%s", "Invalid value for month!\n");
exit();
}
week_day = decade / 4;
week_day += day;
week_day += key;
if((leap) && ((month == 1) || (month == 2)))
{
week_day -= 1;
}
switch (century)
{
case 17: week_day += 4;
break;
case 18: week_day += 2;
break;
case 19: break;
case 20: week_day += 6;
break;
default: printf(1, "%s", "Centuries before 1700 or after 2000 not yet supported. \n");
break;
}
week_day += decade;
week_day = (week_day % 7) - 1;
if(week_day < 0 || week_day > 6)
{
printf(1, "Invalid Day error!"); //TS code- to be removed
}
switch(week_day)
{
case 0: printf(1, "Sun ");
break;
case 1: printf(1, "Mon ");
break;
case 2: printf(1, "Tue ");
break;
case 3: printf(1, "Wed ");
break;
case 4: printf(1, "Thu ");
break;
case 5: printf(1, "Fri ");
break;
case 6: printf(1, "Sat ");
break;
default: printf(1, "Unknown day!");
break;
}
return;
}
void
print_month(int month)
{
switch (month)
{
case 1: printf(1, "Jan");
break;
case 2: printf(1, "Feb");
break;
case 3: printf(1, "Mar");
break;
case 4: printf(1, "Apr");
break;
case 5: printf(1, "May");
break;
case 6: printf(1, "Jun");
break;
case 7: printf(1, "Jul");
break;
case 8: printf(1, "Aug");
break;
case 9: printf(1, "Sep");
break;
case 10: printf(1, "Oct");
break;
case 11: printf(1, "Nov");
break;
case 12: printf(1, "Dec");
break;
default: printf(1, "Month Error");
break;
}
return;
}
check_leap()
. The change from Juliann to Gregorian calendar and it leap year rules only begin in 1582. The new rule were only accepted by the majority of the planet in the 19xx, well past 1700s. The old rules continue is use today in select venues. \$\endgroup\$