首页 > 代码库 > 8位单片机可用的 mktime localtime函数

8位单片机可用的 mktime localtime函数

8位单片机可用的 mktime  localtime函数及源码

 

最近在做一个8位单片机项目,其中用到了时间戳转换函数,这个在32位机上一个库函数就解决了问题,没想到在8位单片机中没有对应库(time.h),没有办法只有自己来写。

目标:1,满足和库函数mktime  localtime所计算出的数据一至;2,考虑8位单片机的处理能力慢软件效率问题。

分享给大家,方便有同样需求的朋友。

 

gcc 环境进行测试:

测试程序:

  1 #include <stdio.h>  2 #include <stdint.h>  3 #include <time.h>  4 #include <string.h>  5   6 #if 0  7 struct tm {  8     int tm_sec;   /* seconds after the minute, 0 to 60  9                      (0 - 60 allows for the occasional leap second) */ 10     int tm_min;   /* minutes after the hour, 0 to 59 */ 11     int tm_hour;  /* hours since midnight, 0 to 23 */ 12     int tm_mday;  /* day of the month, 1 to 31 */ 13     int tm_mon;   /* months since January, 0 to 11 */ 14     int tm_year;  /* years since 1900 */ 15 //    int tm_wday;  /* days since Sunday, 0 to 6 */ 16 //    int tm_yday;  /* days since January 1, 0 to 365 */ 17 //    int tm_isdst; /* Daylight Savings Time flag */ 18 }; 19 #endif 20 static const char mon_list[12]             = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 21 static const char leap_mon_list[12]        = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 22  23 /******************************************************************************* 24 * Function Name : fun_mktime 25 * Description   : 时间转为时间戳 26 * Input         :  27 * Output        :  28 * Other         :  29 * Date          : 2016.11.14 30 *******************************************************************************/ 31 int32_t fun_mktime(struct tm *pT) 32 { 33     const char *pDays = NULL; 34     int32_t tmp = 0; 35     int16_t i = 0; 36      37     //计算总共有多少个闰年 38     tmp = (pT->tm_year  / 4 - pT->tm_year / 100 + pT->tm_year / 400) - (1970 / 4 - 1970 / 100 + 1970 / 400); 39  40     //如果当年是闰年,需要减去当年的闰年 41     if ((pT->tm_year % 4 == 0) && ((pT->tm_year  % 100 != 0) || (pT->tm_year  % 400 == 0))) 42     { 43         tmp = tmp - 1 + (pT->tm_year - 1970) * 365; 44         pDays = leap_mon_list; 45     } 46     else 47     { 48         tmp = tmp + (pT->tm_year - 1970) * 365; 49         pDays = mon_list; 50     } 51  52     for (i = 0; i < pT->tm_mon - 1; i++) 53         tmp += pDays[i]; 54  55     tmp = tmp + pT->tm_mday - 1; 56  57     tmp = tmp * 24 + pT->tm_hour; 58  59     tmp = tmp * 60 + pT->tm_min; 60  61     tmp = tmp * 60 + pT->tm_sec; 62      63     return tmp; 64 } 65  66 /******************************************************************************* 67 * Function Name : fun_localtime 68 * Description   : 时间戳转为时间 69 * Input         :   struct tm *pT: 输出的时间缓冲区   uint32_t tim:当前时间戳 70 * Output        :  71 * Other         :  72 * Date          : 2016.11.14 73 *******************************************************************************/ 74 void fun_localtime(struct tm *pT, int32_t tim) 75 { 76   const char *pDays = NULL; 77  78   uint16_t index = 0; 79  80   memset(pT, 0, sizeof(*pT)); 81  82   //year initialization 83   if (tim > 0x5685C180L)            // 2016-1-1 0:0:0 84   { 85     pT->tm_year = 2016; 86     tim -= 0x5685C180L; 87   }  88   else if (tim > 0x4B3D3B00L)       // 2010-1-1 0:0:0 89   { 90     pT->tm_year = 2010;   91     tim -= 0x4B3D3B00L; 92   } 93   else if (tim > 0x386D4380L)       // 2000-1-1 0:0:0 94   { 95     pT->tm_year = 2000;   96     tim -= 0x386D4380L; 97   } 98   else  99   {100     pT->tm_year = 1970;   101   }102 103   //now have year104   while (tim >= 366L * 24 * 60 * 60)105   {106     if ((pT->tm_year % 4 == 0) && ((pT->tm_year  % 100 != 0) || (pT->tm_year  % 400 == 0)))107       tim -= 366L * 24 * 60 * 60;108     else 109       tim -= 365L * 24 * 60 * 60;110 111     pT->tm_year++;112   }113 114   // then 365 * 24 * 60 * 60 < tim < 366 * 24 * 60 * 60115   if (!(((pT->tm_year % 4 == 0) && ((pT->tm_year  % 100 != 0) || (pT->tm_year  % 400 == 0)))) 116     && (tim > 365L * 24 * 60 * 60))117   {118     tim -= 365L * 24 * 60 * 60; 119     pT->tm_year++;120   }121 122   // this year is a leap year?123   if (((pT->tm_year % 4 == 0) && ((pT->tm_year  % 100 != 0) || (pT->tm_year  % 400 == 0))))124     pDays = leap_mon_list;125   else 126     pDays = mon_list;127 128   pT->tm_mon = 1;129   // now have mon130   while (tim > pDays[index] * 24L * 60 * 60)131   {132     tim -= pDays[index] * 24L * 60 * 60;133     index++;134     pT->tm_mon++;135   }136   137   // now have days138   pT->tm_mday = tim / (24L * 60 * 60) + 1;139   tim = tim % (24L * 60 * 60);140 141   // now have hour142   pT->tm_hour = tim / (60 * 60);143   tim = tim % (60 * 60);144 145   // now have min 146   pT->tm_min = tim / 60;147   tim = tim % 60;148 149   pT->tm_sec = tim;  150 }151 152 153 int main (void *parg)154 {155   struct tm *pT = {0};156   time_t timep = 0;157   uint32_t cur_tim = 0;158 159   time(&timep);160 161   pT = localtime(&timep);162 163   printf("linux time \t= %d\n", (int32_t)timep);164   pT->tm_year += 1900;165   pT->tm_mon += 1;166   printf("fun_mktime \t= %d\n", cur_tim = (uint32_t)fun_mktime(pT));167 168   printf("localtime \t= %d-%d-%d %d:%d:%d\n", pT->tm_year, pT->tm_mon, pT->tm_mday, pT->tm_hour, pT->tm_min, pT->tm_sec);169   memset(pT, 0, sizeof(*pT));170   fun_localtime(pT, cur_tim);171   printf("fun_localtime \t= %d-%d-%d %d:%d:%d\n", pT->tm_year, pT->tm_mon, pT->tm_mday, pT->tm_hour, pT->tm_min, pT->tm_sec);172   return 0;173 }

 

测试结果:

 

linux time      = 1480133002fun_mktime      = 1480161802localtime       = 2016-11-26 12:3:22fun_localtime   = 2016-11-26 12:3:22

 

linux time 是库函数mktime计算结果,因为进行了时区处理,所以与fun_mktime计算出来刚好是8 * 3600 秒的差值

 

 

此函数在C51下进行过测试,符合要求。

8位单片机可用的 mktime localtime函数