8位單片機(jī)可用的 mktime localtime函數(shù)
掃描二維碼
隨時(shí)隨地手機(jī)看文章
最近在做一個(gè)8位單片機(jī)項(xiàng)目,其中用到了時(shí)間戳轉(zhuǎn)換函數(shù),這個(gè)在32位機(jī)上一個(gè)庫(kù)函數(shù)就解決了問(wèn)題,沒(méi)想到在8位單片機(jī)中沒(méi)有對(duì)應(yīng)庫(kù)(time.h),沒(méi)有辦法只有自己來(lái)寫。
目標(biāo):1,滿足和庫(kù)函數(shù)mktime localtime所計(jì)算出的數(shù)據(jù)一至;2,考慮8位單片機(jī)的處理能力慢軟件效率問(wèn)題。
分享給大家,方便有同樣需求的朋友。
gcc 環(huán)境進(jìn)行測(cè)試:
測(cè)試程序:
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 : 時(shí)間轉(zhuǎn)為時(shí)間戳
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 //計(jì)算總共有多少個(gè)閏年
38 tmp = (pT->tm_year / 4 - pT->tm_year / 100 + pT->tm_year / 400) - (1970 / 4 - 1970 / 100 + 1970 / 400);
39
40 //如果當(dāng)年是閏年,需要減去當(dāng)年的閏年
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 : 時(shí)間戳轉(zhuǎn)為時(shí)間
69 * Input : struct tm *pT: 輸出的時(shí)間緩沖區(qū) uint32_t tim:當(dāng)前時(shí)間戳
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 }
測(cè)試結(jié)果:
linux time = 1480133002
fun_mktime = 1480161802
localtime = 2016-11-26 12:3:22
fun_localtime = 2016-11-26 12:3:22
linux time 是庫(kù)函數(shù)mktime計(jì)算結(jié)果,因?yàn)檫M(jìn)行了時(shí)區(qū)處理,所以與fun_mktime計(jì)算出來(lái)剛好是8 * 3600 秒的差值