STM32F103時間戳與常用時間格式互換算法


 1. 常用時間格式轉時間戳

 1 /*
 2  * 輸入UTC、GMT時,得到時間戳,Linux源代碼
 3  */
 4 uint32_t mktime (unsigned int year, unsigned int mon,
 5                                             unsigned int day, unsigned int hour,
 6                                             unsigned int min, unsigned int sec)     
 7 {
 8     if (0 >= (int) (mon -= 2)){    /**//* 1..12 -> 11,12,1..10 */
 9          mon += 12;      /**//* Puts Feb last since it has leap day */
10          year -= 1;
11     }
12  
13     return (((
14              (unsigned long) (year/4 - year/100 + year/400 + 367*mon/12 + day) +
15              year*365 - 719499
16           )*24 + hour /**//* now have hours */
17        )*60 + min /**//* now have minutes */
18     )*60 + sec; /**//* finally seconds */
19 }

來源: 網絡

2.時間戳轉常用時間格式

 1 /*
 2  * 時間戳轉換為普通時間
 3  */
 4 void TimestampToNormalTime(struct RTC_DateTimeTypeDef *time, uint32_t Timestamp)
 5 {
 6     
 7     uint16_t year = 1970;
 8     uint32_t Counter = 0, CounterTemp; //隨着年份迭加,Counter記錄從1970 年 1 月 1 日(00:00:00 GMT)到累加到的年份的最后一天的秒數
 9     uint8_t Month[12] = {31, 28, 31, 30, 31, 30,          31, 31, 30, 31, 30, 31};
10     uint8_t i;
11     
12     while(Counter <= Timestamp)     //假設今天為2018年某一天,則時間戳應小於等於1970-1-1 0:0:0 到 2018-12-31 23:59:59的總秒數
13     {                                                             
14         CounterTemp = Counter;             //CounterTemp記錄完全1970-1-1 0:0:0 到 2017-12-31 23:59:59的總秒數后退出循環
15         Counter += 31536000; //加上今年(平年)的秒數
16         if(IsLeapYear(year))
17         {
18             Counter += 86400; //閏年多加一天
19         }
20         year++;
21     }
22     time->year = year - 1; //跳出循環即表示到達計數值當前年
23     Month[1] = (IsLeapYear(time->year)?29:28);
24     Counter = Timestamp - CounterTemp; //Counter = Timestamp - CounterTemp  記錄2018年已走的總秒數
25     CounterTemp = Counter/86400;          //CounterTemp = Counter/(24*3600)  記錄2018年已【過去】天數
26     Counter -= CounterTemp*86400;        //記錄今天已走的總秒數
27     time->hour = Counter / 3600; //時                       得到今天的小時
28     time->minute = Counter % 3600 / 60; //
29     time->second = Counter % 60; //
30     for(i=0; i<12; i++)
31     {
32         if(CounterTemp < Month[i])                                        //不能包含相等的情況,相等會導致最后一天切換到下一個月第一天時
33         {                                                                                                //(即CounterTemp已走天數剛好為n個月完整天數相加時(31+28+31...)),
34             time->month = i + 1;                                                  // 月份不加1,日期溢出(如:出現32號)
35             time->date = CounterTemp + 1;                                 //應不作處理,CounterTemp = Month[i] = 31時,會繼續循環,月份加一,
36             break;                                                                                //日期變為1,剛好符合實際日期
37         }
38         CounterTemp -= Month[i];
39     }
40     getWEEK(time);
41 }
42 /*
43  * 判斷閏年平年
44  */
45 uint8_t IsLeapYear(uint16_t year)
46 {
47     if(((year)%4==0 && (year)%100!=0) || (year)%400==0)
48         return 1; //是閏年
49     return 0;   //是平年
50 }
51 
52 /*
53  *  函數功能:根據具體日期得到星期
54  *  吉姆拉爾森公式  week=(date+2*month+3*(month+1)/5+year+year/4-y/100+y/400)%7
55  *  注 : 把一月 二月看成是上一年的13 14月    ,    得到結果 0 -- 6 
56  */
57 void getWEEK(struct RTC_DateTimeTypeDef *time)
58 {
59     u16 YY = 0;
60     u8 MM = 0;
61     if(time->month==1 || time->month==2)
62     {
63         MM = time->month + 12;
64         YY = time->year - 1;
65     }else{
66         MM = time->month;
67         YY = time->year;
68     }
69     time->week = ( (time->date+2*MM+3*(MM+1)/5+YY+YY/4-YY/100+YY/400)%7 ) + 1;
70 }                     //(29 + 16 + 5 + 2018 +2018/4 - 2018/100 + 2018/400)%7
71                                             //(29 + 16 + 5 + 18 +18/4 - 18/100 + 18/400)%7

自己編寫 暫未發現有bug

3.UTC轉北京時間

 1 /*
 2  * UTC、GMT時間轉換為北京時間
 3  */
 4 void GMTtoBeijingTime(struct RTC_DateTimeTypeDef *GMTtime, struct RTC_DateTimeTypeDef *Beijingtime)
 5 {    
 6     Beijingtime->year  =  GMTtime->year;
 7     Beijingtime->month =  GMTtime->month;
 8     Beijingtime->date  =  GMTtime->date;
 9     Beijingtime->hour   = GMTtime->hour;
10     Beijingtime->minute = GMTtime->minute;
11     Beijingtime->second = GMTtime->second;
12     
13     if(GMTtime->hour+8 > 23)  //東八區已是第二天
14     {
15         Beijingtime->hour = GMTtime->hour + 8 - 24;  //東八區真實時間(小時)
16         //大月
17         if((GMTtime->month==1)||(GMTtime->month==3)||(GMTtime->month==5)||(GMTtime->month==7)||(GMTtime->month==8)||(GMTtime->month==10)||(GMTtime->month==12))
18         {
19             if(GMTtime->date==31) //如果此時UTC時是大月最后一天,則東八區當前時為下一月1號
20             {
21                 Beijingtime->date = 1;
22                 Beijingtime->month++;
23                 if(Beijingtime->month > 12) ////如果此時UTC時是12月最后一天,則東八區當前時則為下一年1月1日
24                 {
25                     Beijingtime->month = 1;
26                     Beijingtime->year++;
27                 }
28             }else{                   //如果此時UTC時不是大月最后一天
29                 Beijingtime->date++;                
30             }
31         }
32         //二月
33         else if(GMTtime->month==2)
34         {
35             if((IsLeapYear(GMTtime->year)==1&&GMTtime->date==28) || (GMTtime->date<28))  //如果UTC時是閏年,且UTC時為28號,則東八區現在為29號 或者 小於28號,則加一
36             {
37                 Beijingtime->date++;
38             }
39             else if((IsLeapYear(GMTtime->year)==0&&Beijingtime->date==28) || (Beijingtime->date==29))  //如果UTC時是平年且UTC時為28號 或者 為29號,則東八區現在為3月1日
40             {
41                 Beijingtime->date = 1;
42                 Beijingtime->month++;
43             }
44         }
45         //小月
46         else
47         {
48             if(GMTtime->date==30) //如果此時UTC時是小月最后一天,則東八區當前時則為下一月1號
49             {
50                 Beijingtime->date = 1;
51                 Beijingtime->month++;
52             }else{                   //如果此時UTC時不是小月最后一天
53                 Beijingtime->date++;
54             }
55         }
56     }else{            //如果此時UTC時與東八區時同一天          
57         Beijingtime->hour = GMTtime->hour + 8;
58     }
59     
60     getWEEK(Beijingtime);
61 }

自己編寫 暫未發現有bug


自動校時(GPS、WiFi)時,獲得UTC時間,可直接轉為北京時間存儲(DS1302)。或UTC轉時間戳存儲(STM32F1),讀出時間戳后加上 8*3600秒后轉為常用時間格式。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM