C語言手刻unix timestamp
今天突然被RD主管抓去討論MCU通訊如何減少無用空間的問題,
由於時間資料是由RTC(Real-Time Clock)模組回傳的data,
格式是yyyy-mm-dd hh:MM:ss,
yyyy分成2個bytes,其餘各佔1個bytes,共7 bytes,
經討論後希望用一個long儲存unix timestamp,
在32bits MCU的環境下就只須佔用4 bytes,
因為MCU不支援time.h之類的lib,
只好自己手刻一個順便記錄下來。
思路
Unix timestamp的定義為自1970/01/01 00:00:00 以來的秒數,
第一個反應是會遇到閏年問題,
然後思考了一下,由於定義的時間是在1月1日的0時0秒,
所以相減不需要做任何借位,
只需將過去的總天數加總,加上當天的時、分、秒,
就會得到完整的時間差,
然後總天數的獲取又分為年跟月,
針對閏年的部份做相對應的處理(閏年1年有366天,2月有29日),
最後對時區進行修正就完成了。
Code
#include<stdio.h>
#include<stdlib.h>
u_long datetime_to_timestamp(int year, int month, int day, int hour, int minute, int second){
u_long result;
int passed_days = 0;
int month_array[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
//該月以前的天數
for(int i = 1; i < month; i++){
passed_days += month_array[i];
//閏年的二月多一天
if( i == 2 && (year%400==0||(year%4==0 && year%100!=0)) ){
passed_days += 1;
}
}
//該年以前的天數
while(--year >= 1970){
if( year%400==0 || ( year%4==0 && year%100!=0 ) )
passed_days += 366;
else
passed_days += 365;
}
//(該月1號為止的總天數 + 當天 - 1號)轉秒 + 時轉秒 + 分轉秒 + 秒
//28800是台灣時間UTC+8修正為UTC+0
result = (passed_days + day - 1)*24*3600 + hour*3600 + minute*60 + second - 28800;
return result;
}
int main(){
printf("%u\n", datetime_to_timestamp(2040,1,7,0,0,0));
}
Filed under: C - @ 2021 年 7 月 2 日 下午 1:51
標籤: C