8位单片机可用的 mktime localtime函数
扫描二维码
随时随地手机看文章
最近在做一个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 t= %dn", (int32_t)timep);
164 pT->tm_year += 1900;
165 pT->tm_mon += 1;
166 printf("fun_mktime t= %dn", cur_tim = (uint32_t)fun_mktime(pT));
167
168 printf("localtime t= %d-%d-%d %d:%d:%dn", 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:%dn", 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 秒的差值