基本需求:给出一个日期,可以是当天日期,计算往前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; }
大家有什么其它更好的算法可以一起分享下。
此文在看了一篇“一个精巧的日期算法”后,自己想了一个算法实现,网上那个精巧算法更加精简。