C51计算时间差

来源:互联网 发布:电魂网络前景 编辑:程序博客网 时间:2024/06/06 18:02

用2个BCD码数组存储进场时间和出场时间:

unsigned char idata in[5] = {0x10,0x07,0x14,0x20,0x15};//2010年7月14日20时15分

unsigned char idata out[5] = {0x10,0x07,0x15,0x08,0x14};//2010年7月15日8时14分

unsigned char idata in_time[5];//存进场时间的16进制数

unsigned char idata out_time[5];//存出场时间的16进制数

 

首先把这两个数组的BCD码转成HEX码

转换算法:比如把BCD码12h转换成16进制,用12h-6,得到0ch,就是对应的16进制数。十位为n,就用BCD码-n*6,如23h,23h-2*6=17h,17h就是BCD码23

/*

把一个BCD码数组转换成16进制数组

*/

void Bcd_to_Hex(unsigned char *bcd_array,unsigned char *hex_array,unsigned char n)

{

       unsigned char i = 0;

       unsigned char temp;

       for(i = 0;i < n;i++)

       {

              temp = (bcd_array[i] & 0xf0) >> 4;

              hex_array[i] = bcd_array[i];

    while(temp--)

    {

           hex_array[i] = hex_array[i] - 0x06;

    }

  }

}    

然后调用函数difftime(unsigned char *in_time,unsigned char *out_time)得到进出时间相隔多少分钟

 

/*

计算车在场内停留的时间,单位分钟

能计算的最长停留时间是65535/(24*60)=45.5天

*/

unsigned int difftime(unsigned char *in_time,unsigned char *out_time)

{

       int days,months,years,result;

       char leap,temp_year,temp,temp_hour;

       int code monthday[2][12] = {

              {31,28,31,30,31,30,31,31,30,31,30,31},//平年每月天数

              {31,29,31,30,31,30,31,31,30,31,30,31} //闰年每月天数

       };

      

       leap = leapyear(out_time[0]);

      

       years = out_time[0] - in_time[0];

       months = out_time[1] - in_time[1];

       days = out_time[2] - in_time[2];

       temp_year = in_time[0];

   

    if((years > 0) && (in_time[1] > 2))

       {

              if(leapyear(temp_year))

                     days--;                         //如果进场时间是闰年,且月份大于2,那么要减1天,因为2月29日没算进去

       }    

       while(years > 0)

       {

              if(leapyear(temp_year))

                     days += 366;

              else

                     days += 365;

              temp_year++;

              years--;

       }

      

       temp = in_time[1];  //暂存进场时间月份

       if(months > 0)

       {

              while(months > 0)

              {

                     days += monthday[leap][temp++ - 1];// temp先减1,然后再自加1,减1是因为monthday[][]下标是从零开始

                     months --;

              }

       }

       else

       {

              while(months < 0)

              {

                     temp--;

                     days -= monthday[leap][temp - 1];

                     months++;

              }

       }

        

       temp = out_time[4];       //暂存出场时间的分钟

       temp_hour = out_time[3];  //暂存出场时间的小时

       if(temp < in_time[4])

       {

              temp += 60;  //如果出场时间的分钟小于进场时间的分钟,那么出场时间分钟加60

              temp_hour -= 1;//出场时间小时减1

       }

      

       result = days * 24 * 60 + (temp_hour - in_time[3]) *60 + temp - in_time[4];

      

       return result;

}    

 

 

判断年是否闰年的函数如下:

算法:先判断年是否可以被4整除,如果不可以,不是闰年,如果可以,继续判断,看是否可以被100整除,如果不可以,则是闰年,如1996,如果可以被100整除,继续判断,看是否可以被400整除,如果可以则是闰年,如果不可以,则不是。如1900可以被4整除,继续判断,可以被100整除,继续判断,不可以被400整除,则不是闰年。2000则是闰年。

/*

判断是否是闰年 闰年返回1,平年返回0

*/

char leapyear(unsigned char year)

{

       unsigned int y;

       y = year + 2000;

       if ((y % 400 == 0) || ((y %100 != 0) && (y %4 == 0)))

              return 1;

       else

              return 0;

}

 

写成c文件如下:

unsigned char idata in[5] = {0x10,0x07,0x14,0x20,0x15};//2010年7月14日20时15分

unsigned char idata out[5] = {0x10,0x07,0x15,0x08,0x14};//2010年7月15日8时14分

unsigned char idata in_time[5];//存进场时间的16进制数

unsigned char idata out_time[5];//存出场时间的16进制数

 

void main()

{

  Unsigned int i = 0;

  Bcd_to_Hex(in,in_time,5);

  i = difftime(in_time,out_time);

}

运行得i = 0x2cf 即719分钟,与实际时间差相符。