自己写的日期相加函数(C语言)

由于需要处理相对日期的问题,想要找个日期相加的函数,查了一下网上,没有找到想要的东东,所以,只好自己来写一个差不多的了!

由于我要的函数,要直接能够相加年月日三项,并且我能得到的数据格式是:YYMMDD这样的,也就是说,只要处理到2000年到2099年之间就可以了!
相加的值也是这样格式,表示要加上N年N月N天。

年这部分好办,直接相加就可以了,超过2099年的话,报错就OK了。
月这部分比较麻烦,第一次我是按自然月相加的 ,没考虑当月里的天的值。函数是这样的:

#define TRUE 1
#define true 1
#define false 0
#define SUCCESS 0

#include <stdio.h>

unsigned char *asc_bcd(unsigned char *Ptd ,unsigned char Lgd,unsigned char *Pts,unsigned char Lgs)
{
    unsigned char I;

    if( Lgd > Lgs/2)
    {
        memset( Ptd, 0x00, Lgd ) ;
        Ptd = Ptd + Lgd - ((Lgs + 1) / 2) ;
    }
    for ( I = 0 ; I < ((Lgs+1) / 2) ; I++)
    {
        if ( (!(Lgs % 2) && !I) || I ) *Ptd =  (*Pts++ << 4) & 0xF0 ;
        *Ptd = *Ptd + (*Pts++ & 0x0F)  ;
        Ptd++ ;
    }
    return((unsigned char*)Ptd);
}

unsigned long bcd_long( unsigned char *Pts, unsigned char Ls )
{
    unsigned char I,Oct;
    unsigned long Lg1,Lg2;

    Lg1 = 0 ;
    Lg2 = 1 ;
    Pts += (Ls+1)/2;
    for (I = 0; I< Ls ; I++)
    {
        if ( I % 2) Oct = (*Pts >> 4 ) & 0x0F;
        else Oct = *--Pts & 0x0F;
        Lg1 += Lg2 * Oct ;
        if (Lg2 == 1000000000L ) Lg2 = 0 ;
        else Lg2 *= 10 ;
    }
    return (Lg1) ;
}

unsigned char *long_bcd(unsigned char *Ptd ,unsigned char Lgd,unsigned long *Pts)
{
    unsigned int I;
    unsigned char *Pt0,Tb[5];
    unsigned long Lg1,Lg2;

    Lg1 = *Pts;
    Lg2 = 100000000L ;
    for (I = 0; I< 5; I++)
    {
        Tb[I] = (unsigned char)(Lg1 / Lg2) ;
        Tb[I] = ((Tb[I] / 10 ) << 4 ) + (Tb[I] % 10);
        Lg1 = Lg1 % Lg2;
        Lg2 = Lg2 / 100;
    }

    memset( Ptd, 0x00, Lgd ) ;
    Ptd += Lgd ;
    Pt0 = Ptd ;
    if ( Lgd > 5) Lgd = 5 ;
    for ( I=0; I < Lgd;I++) *--Ptd = Tb[4-I] ;

    return((unsigned char*)Pt0);
}

unsigned char UTIL_IsLeapYear(unsigned short Year)
{
    if(  (Year%4) != 0)
    {
        return false;
    }else
    {
        if(  (Year%100) != 0)
        {
            return true;
        }else
        {
            if(  (Year%400) != 0)
                return false;
            else
                return true;
        }
    }
}

unsigned char UTIL_Date_Add_old(unsigned char *pucSrcDate,unsigned char *pucAddDate,unsigned char* pucDesDate)
{
    unsigned char ucYear,ucMonth,ucDay;
    unsigned char ucAddYear,ucAddMonth,ucAddDay;
   
    unsigned char ucYearResult,ucMonthResult,ucDayResult;
    unsigned char ucMonthTmp,ucDayTmp;
    unsigned char ucDayPerMonth,ucMonthToYear;
   
    unsigned short uiYear;
    unsigned long ulYear,ulMonth,ulDay;
   
    ucYear = bcd_long(pucSrcDate,2);
    ucMonth = bcd_long(pucSrcDate+1,2);
    ucDay = bcd_long(pucSrcDate+2,2);
    printf("Source Date: Year=%2d,Month=%2d,Day=%2d/n",ucYear,ucMonth,ucDay);
   
    ucAddYear = bcd_long(pucAddDate,2);
    ucAddMonth = bcd_long(pucAddDate+1,2);
    ucAddDay = bcd_long(pucAddDate+2,2);
    printf("Dest Date: AddYear=%2d,AddMonth=%2d,AddDay=%2d/n",ucAddYear,ucAddMonth,ucAddDay);
   
    if(ucMonth>12)
        return 1;
    if(ucDay>31)
        return 2;
   
   
   
    ucYearResult = ucYear + ucAddYear;
    ucMonthResult = ucMonth + ucAddMonth;
    ucDayResult = ucDay + ucAddDay;
   
    if(ucMonthResult > 12)
    {
        ucYearResult++; //如果月相加的结果大于12,则向前进位一年
        //ucManyMonthFlag = true;
    }   
   
    uiYear = 2000 + ucYearResult;//得到完整表示的年
   
    ucMonthTmp = ucMonthResult % 12;//月份结果
    ucDayTmp = ucDayResult;

    do
    {   
        switch(ucMonthTmp)
        {
            case 0://12月
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
                ucDayPerMonth = 31;
                break;
            case 4:
            case 6:
            case 9:
            case 11:
                ucDayPerMonth = 30;
                break;
            case 2:
                if(UTIL_IsLeapYear(uiYear)==TRUE)//用完整表示的年计算是不是闰年
                    ucDayPerMonth = 29;
                else
                    ucDayPerMonth = 28;
                break;
            default:
                //其实走不到这里,整数与12模的结果只能在0到11之间
                break;   
        }
        if(ucDayTmp > ucDayPerMonth)
        {
            ucDayTmp = ucDayTmp - ucDayPerMonth;
            ucMonthTmp ++;   
            ucMonthTmp %= 12;
           
            if(ucMonthTmp == 1)
            {
                uiYear++;//如果当月是12月,且天数大于31,则年进位
                if(uiYear > 2099)
                      return 3;
            }
               
        }
        else
        {
            break;
        }
    }
    while(1);
   
    ucMonthResult = ucMonthTmp;
    if(ucMonthResult == 0)//如果是0表示是12月
        ucMonthResult = 12;
       
    ucDayResult = ucDayTmp;
    ucYearResult = uiYear - 2000;
   
    ulYear = ucYearResult;
    ulMonth = ucMonthResult;
    ulDay = ucDayResult;
   
    long_bcd(pucDesDate,1,&ulYear);
    long_bcd(pucDesDate+1,1,&ulMonth);
    long_bcd(pucDesDate+2,1,&ulDay);
   
    printf("/nResult: Year=%2d,Month=%2d,Day=%2d/n",ucYearResult,ucMonthResult,ucDayResult);
    return 0;
}

传进去的参数是BCD串,因为正式用的时候,得到的就是BCD值。测试时是手输的,得先用asc_bcd函数转一下。传进去的当前日期,会先进行判断,是不是基本合法的格式,只是简单判断一下是不是超过月限和天限值。

测试的main基本是这样的:

int main()
{
    unsigned char aucSrcDate[7],aucAddDate[7],aucSrcDateTmp[4],aucAddDateTmp[4],aucDesDate[4];
    unsigned char ucFlag = 1;
    unsigned char ucResult,ucI;
   
    printf("/n----------------------------------------------------/n");
    printf("           Add Year Function Test/n");
    printf("----------------------------------------------------/n");
   
    while(ucFlag)
    {
        memset(aucSrcDate,0,sizeof(aucSrcDate));
        memset(aucAddDate,0,sizeof(aucAddDate));
        memset(aucSrcDateTmp,0,sizeof(aucSrcDateTmp));
        memset(aucAddDateTmp,0,sizeof(aucAddDateTmp));
        memset(aucDesDate,0,sizeof(aucDesDate));
       
        printf("/nPlease Input Now Date with Format YYMMDD:/n");
        scanf("%s",aucSrcDate);
        printf("/n");
        printf("Please Input You Want Add Date with Format YYMMDD:/n");
        scanf("%s",aucAddDate);
        printf("/n");
        asc_bcd(aucSrcDateTmp,3,aucSrcDate,6);
        asc_bcd(aucAddDateTmp,3,aucAddDate,6);
       
        ucResult = UTIL_Date_Add(aucSrcDateTmp,aucAddDateTmp,aucDesDate);
        printf("/n/n====================================/n");
        for(ucI=0;ucI<4;ucI++)
            printf("%02x ",aucDesDate[ucI]);
        printf("/n/n====================================/n");
        if(ucResult == 0)           
            printf("/n==============================================/nPlease Manual Count The Result is Right or Not!/n");
        if(ucResult == 1)
            printf("/n!!!Error!! Error Input Month!Please Check!/n");
        if(ucResult ==2)
            printf("/n!!!Error !! Error Input Day Value,Please Check!/n");
        if(ucResult == 3)
           printf("/n!!!Error!! The Year Value Is Too Big,Please Re Input!/n");
        printf("/n-----------------------------------------------/n");
        printf("If You Want To Continue?(Y/N)");
        ucFlag = getch();
       
        if(ucFlag == 'Y'|| ucFlag=='y')
            ucFlag = 1;
        else
            ucFlag = 0;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值