sample output:
September 2014
Sun Mon Tue Wed Thu Fri Sta
1 2 3 4 5 6
7 8 9 <10> 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
the code is based a date utility from this blog.
#include <stdio.h>
#include <string.h>
#include <time.h>
typedef struct date_s date_t;
struct date_s
{
int serial;
};
#define is_leap(y) (((y) % 400 == 0)||((0 == (y)%4) && (0 != (y) % 100)))
int year_days[2] = {365, 366};
unsigned char month_days[2][12] = {
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } };
enum
{
base_year =2014, //the base date shall be Jan, 1
base_weekday = 3 //0: Sunday, 1: Monday ... 6: Saturday
};
date_t to_date(int yyyymmdd)
{
int y, m, d, serial = 0;
y = yyyymmdd / 10000;
m = yyyymmdd / 100 % 100;
d = yyyymmdd % 100;
serial += d - 1;
while(m > 1)
{
--m;
serial += month_days[is_leap(y)][m-1];
}
while(y > base_year)
{
serial += year_days[is_leap(y)];
--y;
}
while(y < base_year)
{
serial -= year_days[is_leap(y)];
++y;
}
date_t date = {serial};
return date;
}
int date_diff(date_t const& d1, date_t const& d2)
{
return d1.serial - d2.serial;
}
date_t date_advance(date_t const& d, int diff)
{
date_t date = {d.serial + diff};
return date;
}
//only for human readable output/log
int to_yyymmdd(date_t const& date)
{
int y = base_year, m = 1, d = 1;
while(to_date(y*10000+ m * 100 + d).serial < date.serial)
{
++d;
if(d > month_days[is_leap(y)][m-1])
{
d = 1;
++m;
}
if(m > 12)
{
m = 1;
++y;
}
}
while(to_date(y*10000+ m * 100 + d).serial > date.serial)
{
--d;
if(0 == d)
{
--m;
if(m == 0)
{
m = 12;
--y;
}
d = month_days[is_leap(y)][m-1];
}
}
return y*10000+100*m+d;
}
//only for human readable output/log
int weekday(date_t const& date)
{
int remaining = date.serial % 7;
int w = base_weekday;
while(remaining > 0)
{
++w;
if(w == 7)
{
w = 0;
}
--remaining;
}
while(remaining < 0)
{
--w;
if(w == -1)
{
w = 6;
}
++remaining;
}
return w;
}
char const* const weekdays[7] = {"Sunday", "Monday", "Tuesday",
"Wednesday", "Thursday", "Friday", "Saturday"};
char const* const months[12] = {
"January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "December", "November"
};
int main()
{
int y, m, d;
time_t rawtime = time(NULL);
struct tm* thetime = localtime(&rawtime);
y = thetime->tm_year + 1900;
m = thetime->tm_mon + 1;
d = thetime->tm_mday;
char const * title = "Sun Mon Tue Wed Thu Fri Sta";
printf("%*.0d%s %4d\n%s\n",
(strlen(title) - strlen(months[m-1])- 5) / 2, 0, months[m-1], y, title);
int wd = weekday(to_date(y*10000+ m*100 + 1)), w;
for( w = 0; w < wd; ++w)
printf(" ");
for(int i = 1; i <= month_days[is_leap(y)][m-1]; ++i, ++w)
{
if(w == 7)
{
w = 0;
puts(""); //new line
}
if(d == i)
{
if( i < 10)
printf(" <%d>", i);
else
printf("<%2d>", i);
}
else
{
printf("%3d ", i);
}
}
return 0;
}