#include <cassert>
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, //Jan
28, //Feb
31, //Mar
30, //Apr
31, //May
30, //Jun
31, //Jul
31, //Aug
30, //Sep
31, //Oct
30, //Nov
31 //Dec
},
{
31, //Jan
29, //Feb
31, //Mar
30, //Apr
31, //May
30, //Jun
31, //Jul
31, //Aug
30, //Sep
31, //Oct
30, //Nov
31 //Dec
}
};
enum
{
base_year =2013, //the base date shall be Jan, 1
base_weekday = 2 //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",
"Wendsday", "Thursday", "Friday", "Staturday"};
int main()
{
date_t d1 = to_date(20120304), d2 = to_date(20140418);
int diff = date_diff(d1, d2);//d1-d2 == diff
date_t d3 = date_advance(d1, -diff); //d2 = d1 - diff
assert(d3.serial == d2.serial);
return 0;
}
a utility to compare date diff and date advance^_^
最新推荐文章于 2025-06-06 17:40:50 发布
