基本需求:给出一个日期,可以是当天日期,计算往前N天或者往后N天的日期。
给出的算法基本思路:
1.设定一个基础日期,比如1901-1-1
2.先算出给定日期和基础日期之间的天数n
3.往前m天或往后m天,则得到的日期天数n1=n+/- m
4.n1天数用基础天数做为起点,算出日期
const int month_days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int month_days_leap[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int days_number = 365;
const int days_number_leap = 366;
const int base_yy = 1901;
inline bool is_leap_year(const int yy)
{
if( (yy % 4 == 0 && yy % 100 != 0) || yy % 400 == 0)
return true;
else
return false;
}
// 计算从base_yy-1-1到当前年份的天数
int date2offset(const int yy, const int mm, const int dd)
{
if(yy < base_yy)
return -1;
int number_d = 0;
int i = 0;
int diff = yy - base_yy;
while (i < diff) {
if(is_leap_year(base_yy + i))
number_d += days_number_leap;
else
number_d += days_number;
i ++;
}
const int *pd = is_leap_year(yy) ? month_days_leap : month_days;
i = 1;
while(i < mm)
{
number_d += pd[i - 1];
i++;
}
number_d = number_d + (dd - 1);
return number_d;
}
//天数转换成具体日期
int offset2date(const int number_d, int &yy, int &mm, int &dd)
{
if(number_d < 0){
printf("wrong number_d :%d\n", number_d);
return -1;
}
//实际年份应该在year1之后
int year1 = number_d / days_number_leap + base_yy;
int days = date2offset(year1, 1, 1);
while (days <= number_d)
{
bool bleap = is_leap_year(year1);
int days_add = days + (bleap ? days_number_leap : days_number);
if( days_add < number_d)
{
year1 ++;
days = days_add;
}else if(days_add == number_d)
{
yy = year1 + 1;
mm = 1;
dd = 1;
break;
}else
{
yy = year1;
const int *pd = bleap ? month_days_leap : month_days;
int i = 0;
while(i < 12)
{
int add_mm = days + pd[i];
if(add_mm < number_d)
{
i++;
days = add_mm;
}else if(add_mm == number_d)
{
mm = i + 2;
if(mm == 13)
{
printf("wrong month\n");
yy ++;
mm = 1;
}
dd = 1;
break;
}else{
mm = i + 1;
dd = number_d - days + 1;
break;
}
}//end while i < 12
break;
}//end else
}
return 0;
}
void getdays(const int yy, const int mm, const int dd, const int days)
{
printf("in:%04d-%02d-%02d, days = %d\n", yy, mm, dd, days);
int number = date2offset(yy, mm, dd);
printf("number = %d\n", number);
int y1 = 0;
int m1 = 0;
int d1 = 0;
offset2date(number + days, y1, m1, d1);
printf("out:%04d-%02d-%02d\n", y1, m1, d1);
}
int main(int argc, const char * argv[])
{
int yy = 2014;
int mm = 8;
int dd = 31;
int days = -10000;
getdays(yy, mm, dd, days);
return 0;
}
大家有什么其它更好的算法可以一起分享下。
此文在看了一篇“一个精巧的日期算法”后,自己想了一个算法实现,网上那个精巧算法更加精简。