计算从某个日期开始往前或往后天数的日期

来源:互联网 发布:自然语言处理 源码 编辑:程序博客网 时间:2024/05/16 17:59

基本需求:给出一个日期,可以是当天日期,计算往前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;}


当然如果需要计算的年份比1901还小,只要修改下base_yy的值即可。

大家有什么其它更好的算法可以一起分享下。

此文在看了一篇“一个精巧的日期算法”后,自己想了一个算法实现,网上那个精巧算法更加精简。


0 0
原创粉丝点击