int date8_add(char *date8,char ymd,int value,char *date8added); int checkdate8(char *date8); long int days_from_8zeros(char *date8); int get_data8_from_days(long int days,char *date8); //功能:计算某年月日前后一定年数(或月数、天数)的年月日 //输入: // 1. date8 计算基准日期 // 2. ymd 表示下一变量的单位 'y'-年 'm'-月 'd'-日 // 3. value 偏移量:年数、月数、天数 //输出: // 1. date8added 计算后结果 //返回: // 0 成功 // -1 date8非法 // -2 ymd非法 // -3 value非法 // -4 转换后date8added的年份小于公元1年 // -5 转换后date8added的年份大于公元9999年 // -6 转换后date8added非法,例如得到结果为2002/02/30 int date8_add(char *date8,char ymd,int value,char *date8added) { char strtmp[10]; long int days; int c,vyear,vmonth,vday; int errbz;
// 检查参数date8的合法性 errbz=checkdate8(date8); if (errbz!=0) return(-1); // 检查参数ymd的合法性 if ( ymd!='y' && ymd!='m' && ymd!='d') return(-2); // 检查参数value的合法性(简单检查) //if ( value < -9999 || value > 9999 ) return(-3); // 当增加量为年数时,计算结果并返回 if (ymd=='y') { memset(strtmp,0,sizeof(strtmp)); memcpy(strtmp,date8+0,4); sscanf(strtmp,"%d",&vyear); vyear+=value; if ( vyear<1 ) return(-4); //小于公元1年 if ( vyear>9999 ) return(-5); //大于公元9999年 strcpy(date8added,date8); sprintf(strtmp,"%04d",vyear); memcpy(date8added,strtmp,4); errbz=checkdate8(date8added); if (errbz!=0) return(-6); //计算所得结果非法 return(0); } // 当增加量为月数时,计算结果并返回 if (ymd=='m') { vyear=0; vmonth=0; vday=0; memset(strtmp,0,sizeof(strtmp)); memcpy(strtmp,date8+0,4); sscanf(strtmp,"%d",&vyear); memset(strtmp,0,sizeof(strtmp)); memcpy(strtmp,date8+4,2); sscanf(strtmp,"%d",&vmonth); memset(strtmp,0,sizeof(strtmp)); memcpy(strtmp,date8+6,2); sscanf(strtmp,"%d",&vday); vmonth=vyear*12+vmonth+value; vmonth--; vyear=vmonth/12; vmonth=vmonth%12; vmonth++; if (vyear<1) return(-4); if (vyear>9999) return(-5); sprintf(date8added,"%04d%02d%02d",vyear,vmonth,vday); errbz=checkdate8(date8added); if (errbz!=0) return(-6); return(0); } // 当增加量为天数时,计算结果并返回 if (ymd=='d') { days=days_from_8zeros(date8); days+=value; if (days<=366) return(-4); //年号为0000 if (days>3652425) return(-5); //年号超出9999 errbz=get_data8_from_days(days,date8added); if (errbz!=0) return(-1); return(0); } } //检查日期YyyyMmdd //输入:date8 日期字符串 //返回:0-正确 -1-错误 int checkdate8(char *date8) { int c; int errdate=0; char str_year[5]=""; char str_mon[3]=""; char str_day[3]=""; int int_year,int_mon,int_day; int leap_year; // 1-闰年 0-不是闰年
errdate=0; if ( strlen(date8) != 8 ) errdate=1; if (errdate!=1) { for (c=0;c<10;c++) { if (date8[c]==' ') errdate=1; } if ( date8[0] < '0' || date8[0] > '9' ) errdate=1; if ( date8[1] < '0' || date8[1] > '9' ) errdate=1; if ( date8[2] < '0' || date8[2] > '9' ) errdate=1; if ( date8[3] < '0' || date8[3] > '9' ) errdate=1; if ( date8[4] < '0' || date8[4] > '9' ) errdate=1; if ( date8[5] < '0' || date8[5] > '9' ) errdate=1; if ( date8[6] < '0' || date8[6] > '9' ) errdate=1; if ( date8[7] < '0' || date8[7] > '9' ) errdate=1; } if (errdate!=1) { str_year[0]=date8[0]; str_year[1]=date8[1]; str_year[2]=date8[2]; str_year[3]=date8[3]; str_year[4]='\0'; str_mon[0]=date8[4]; str_mon[1]=date8[5]; str_mon[2]='\0'; str_day[0]=date8[6]; str_day[1]=date8[7]; str_day[2]='\0'; int_year=atoi(str_year); int_mon=atoi(str_mon); int_day=atoi(str_day); if ( ((int_year%4)==0 && (int_year%100)!=0) || (int_year%400)==0 ) leap_year=1; else leap_year=0; if ( leap_year==0 && int_mon==2 && int_day>28 ) errdate=1; if ( leap_year==1 && int_mon==2 && int_day>29 ) errdate=1; if ( int_mon==1 && int_day>31 ) errdate=1; if ( int_mon==3 && int_day>31 ) errdate=1; if ( int_mon==5 && int_day>31 ) errdate=1; if ( int_mon==7 && int_day>31 ) errdate=1; if ( int_mon==8 && int_day>31 ) errdate=1; if ( int_mon==10 && int_day>31 ) errdate=1; if ( int_mon==12 && int_day>31 ) errdate=1; if ( int_mon==4 && int_day>30 ) errdate=1; if ( int_mon==6 && int_day>30 ) errdate=1; if ( int_mon==9 && int_day>30 ) errdate=1; if ( int_mon==11 && int_day>30 ) errdate=1; } if ( int_mon<1 || int_mon>12 ) errdate=1; if ( int_day<1 ) errdate=1; if (errdate==0) return(0); return(-1); } //功能:计算日期YyyyMmDd距离虚拟的公元00000000的天数 //输入:date8 //返回:所求天数 long int days_from_8zeros(char *date8) { int leap; //0-平年 1-闰年 long int days; int vyear,vmonth,vday; int c; char strtmp[10];
vyear=vmonth=vday=0; memset(strtmp,0,sizeof(strtmp)); memcpy(strtmp,date8+0,4); sscanf(strtmp,"%d",&vyear); memset(strtmp,0,sizeof(strtmp)); memcpy(strtmp,date8+4,2); sscanf(strtmp,"%d",&vmonth); memset(strtmp,0,sizeof(strtmp)); memcpy(strtmp,date8+6,2); sscanf(strtmp,"%d",&vday); days=0; for (c=0;c<vyear;c++) { leap=0; if ( ((c%4)==0&&(c%100)!=0) || (c%400)==0 ) leap=1; if (leap==0) days+=365; if (leap==1) days+=366; }
c=vyear; leap=0; if ( ((c%4)==0&&(c%100)!=0) || (c%400)==0 ) leap=1; for (c=1;c<vmonth;c++) { if (c==1) days+=31; if (c==2 && leap==0) days+=28; if (c==2 && leap==1) days+=29; if (c==3) days+=31; if (c==4) days+=30; if (c==5) days+=31; if (c==6) days+=30; if (c==7) days+=31; if (c==8) days+=31; if (c==9) days+=30; if (c==10) days+=31; if (c==11) days+=30; if (c==12) days+=31; } days+=vday; return(days); } //功能:根据到虚拟的公元00000000的天数计算日期 //输入:days //输出:date8 //返回:0 成功 -1 失败 int get_data8_from_days(long int days,char *date8) { long int daystmp; int leap; // 0-平年 1-闰年 int c; int vyear,vmonth,vday;
if (days<=0) return(-1); daystmp=0; for (c=0;c<=9999;c++) { leap=0; if ( ((c%4)==0&&(c%100)!=0) || (c%400)==0 ) leap=1; if (leap==0) daystmp+=365; if (leap==1) daystmp+=366; if (c==9999 && days>daystmp) return(-1); if (days<=daystmp) { vyear=c; if (leap==0) daystmp-=365; if (leap==1) daystmp-=366; break; } } c=vyear; leap=0; if ( ((c%4)==0&&(c%100)!=0) || (c%400)==0 ) leap=1; for (c=1;c<=12;c++) { // 以下这段程序借用vday if (c==1) vday=31; if (c==2 && leap==0) vday=28; if (c==2 && leap==1) vday=29; if (c==3) vday=31; if (c==4) vday=30; if (c==5) vday=31; if (c==6) vday=30; if (c==7) vday=31; if (c==8) vday=31; if (c==9) vday=30; if (c==10) vday=31; if (c==11) vday=30; if (c==12) vday=31; daystmp+=vday; if (days<=daystmp) { vmonth=c; daystmp-=vday; break; } } vday=days-daystmp; sprintf(date8,"%04d%02d%02d",vyear,vmonth,vday); return(0); } //功能:返回指定的年月日 //输入: // 1. YyyyMmDd y [-+]val 返回YyyyMmDd前/后val年对应日的年月日 // 2. YyyyMmDd m [-+]val 返回YyyyMmDd前/后val月对应日的年月日 // 3. YyyyMmDd d [-+]val 返回YyyyMmDd前/后val日对应日的年月日 main(int argc,char *argv[]) { char date8[9]; char ymd[2]; long int val; char date8added[9];
char strtmp[10]; int c; int errbz; //printf("%d\n",days_from_8zeros("00000131")); //printf("%d\n",days_from_8zeros("00010131")); //printf("%d\n",days_from_8zeros("00020401")); //printf("%d\n",days_from_8zeros("20020510")); //printf("%d\n",days_from_8zeros("20020531")); //printf("%d\n",days_from_8zeros("99991231")); //printf("ret:%4d ",get_data8_from_days(31,strtmp));printf("%s\n",strtmp); //printf("ret:%4d ",get_data8_from_days(397,strtmp));printf("%s\n",strtmp); //printf("ret:%4d ",get_data8_from_days(822,strtmp));printf("%s\n",strtmp); //printf("ret:%4d ",get_data8_from_days(731346,strtmp));printf("%s\n",strtmp); //printf("ret:%4d ",get_data8_from_days(731367,strtmp));printf("%s\n",strtmp); //printf("ret:%4d ",get_data8_from_days(3652425,strtmp));printf("%s\n",strtmp); //printf("ret:%4d ",get_data8_from_days(3652426,strtmp));printf("%s\n",strtmp); errbz=0; //初步检查输入合法性 if(errbz==0 && argc!=4) errbz=-999; //参数数量错误 if(errbz==0 && strlen(argv[1])!=8) errbz=-1; //参数YyyyMmDd非法--长度错 if(errbz==0 && strlen(argv[2])!=1) errbz=-2; //参数ymd非法--长度错 //将参数赋值到变量 if (errbz==0) { memset(date8,0,sizeof(date8)); memset(ymd,0,sizeof(ymd)); val=0; strncpy(date8,argv[1],8); strncpy(ymd,argv[2],1); sscanf(argv[3],"%d",&val); } //调用函数计算新的日期值 if (errbz==0) { memset(date8added,0,sizeof(date8added)); errbz=date8_add(date8,ymd[0],val,date8added); } // 将结算结果或错误信息用printf输出 if (errbz==0) printf("%s\n",date8added); if (errbz==-999) printf("%d Usage: date8add YyyyMmDd {ymd} [+|-]value\n",errbz); if (errbz==-1) printf("%d Usage: date8add YyyyMmDd {ymd} [+|-]value\n",errbz); if (errbz==-2) printf("%d Usage: date8add YyyyMmDd {ymd} [+|-]value\n",errbz); if (errbz==-3) printf("%d Usage: date8add YyyyMmDd {ymd} [+|-]value\n",errbz); if (errbz==-4) printf("%d result is valid\n",errbz); if (errbz==-5) printf("%d result is valid\n",errbz); if (errbz==-6) printf("%d result is valid\n",errbz); } |