自己写的日期相加函数(C语言)
2006-08-18 11:19
585 查看
由于需要处理相对日期的问题,想要找个日期相加的函数,查了一下网上,没有找到想要的东东,所以,只好自己来写一个差不多的了!
由于我要的函数,要直接能够相加年月日三项,并且我能得到的数据格式是: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;
}
由于我要的函数,要直接能够相加年月日三项,并且我能得到的数据格式是: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;
}
相关文章推荐
- 自己写的日期相加函数(C语言)_根据ORACLE数据库的方式改进版
- 自己动手写C语言浮点数转换字符串函数
- 自己动手写C语言格式化输出函数(一)
- ABAP 日期相加减的函数
- 自己编写c语言实现的字符串操作函数
- c语言:实现一个函数,打印乘法口诀表,口诀表的行数和列数自己指定
- C语言简单的日期校验函数
- 请用C语言在32位环境下,设计一个32位无符号长整数求和函数,相加之和存储在两个32位无符号整数
- 自己整理的一个javascript日期处理函数
- c语言:实现一个函数,打印乘法口诀表,口诀表的行数和列数自己指定
- 用C语言写自己的printf函数
- 用c语言实现一个自己的atof()函数
- C语言strtok()函数:分割字符串(自己实现strtok)
- [原创] 自己写的日期转换为时间戳函数
- (转)---C语言中格式化日期时间asctime()函数详细讲解
- ASP中DateAdd函数中日期相加或相减使用方法
- ASP中DateAdd函数中日期相加或相减使用方法
- C语言自己写的函数出现“error LNK2001: 无法解析的外部符号“
- C语言10的n次方pow函数不好用,自己写一个简单的
- C语言字符切割函数的实现——不需要自己指定分配多少个字符串分组