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 year
104   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 * 60
115   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 mon
130   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 days
138   pT->tm_mday = tim / (24L * 60 * 60) + 1;
139   tim = tim % (24L * 60 * 60);
140 
141   // now have hour
142   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      = 1480133002
fun_mktime      = 1480161802
localtime       = 2016-11-26 12:3:22
fun_localtime   = 2016-11-26 12:3:22

 

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

 

 

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

posted @ 2016-11-26 12:13  Hiker天下  阅读(3379)  评论(0编辑  收藏  举报