×
嵌入式 > 技术百科 > 详情

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

发布时间:2020-05-27 发布时间:
|

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

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

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

 

gcc 环境进行测试:

测试程序:

  1 #include

  2 #include

  3 #include

  4 #include

  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 = %d ", (int32_t)timep);

164   pT->tm_year += 1900;

165   pT->tm_mon += 1;

166   printf("fun_mktime = %d ", cur_tim = (uint32_t)fun_mktime(pT));

167 

168   printf("localtime = %d-%d-%d %d:%d:%d ", 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 = %d-%d-%d %d:%d:%d ", 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 秒的差值

 



 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
磁吸式充电器又来了.但这回它设计得有点尴尬