最近專案中需要上傳包含時間戳的裝置資料到伺服器平台。原本想把「年」,「月」,「日」,「時」,「分」, 「秒」分別用乙個uint8_t的資料型別去儲存,即占用6個位元組。但是在平台配置協議時,只有一種叫「unix時間戳」的資料型別。unix時間戳只占用4個位元組,而且unix時間戳在伺服器端更加通用,但是在微控制器上沒有想linux環境下現成的time(),localtime(),mktime()等庫函式呼叫。所以考慮自己實現unix時間戳和北京時間的相互轉換。
unix時間戳:
是從2023年1月1日00:00:00開始到當前時刻經過的秒數。
例如:乙個小時表示為unix時間戳格式為:3600秒;一天表示為unix時間戳為86400秒。
當然由於時區的關係,北京時間在算出來的秒數後面需要加上8個小時(8*3600秒)。
比如在linux中,我們獲取unix時間戳可以用:
typedef long time_t; /* time value */
time_t time(time_t * timer)
呼叫後會返回乙個time_t型別的值(即long)。由於在大多數32位的裝置上,long為4個位元組有符號數,所以最大秒數為:2^23,大約2023年就會存在溢位的問題。所以後面的裝置都用64位去儲存,當然這不是本文**的地方。
為什麼使用unix時間戳?
在伺服器端使用unix時間戳更加通用。
北京時間轉unix時間戳:
這個轉換比較簡單,用當前的時間的年月日時分秒,依次減去1970/1/1 00:00:00即可。只要注意閏年的情況就行,最後注意需要加上北京時區的8個小時。
不嚴謹的說每隔4年就有乙個閏年(此處暫不考慮2023年這樣的非閏年,因為time_t限制,可取的範圍只有1970~2038),所以可以將4年看做乙個週期(即365+365+365+366=1461天)。通過總天數除以1461得到週期的個數,然後1970加上週期的個數乘以4就是年份。總天數對1461取餘就是這個週期內的天數,然後根據平閏年去判斷年月日時分秒。
#include
#include
#include "stdint.h"
#define fouryearday (365+365+365+366) //4年乙個週期內的總天數(1970~2038不存在2100這類年份,故暫不優化)
#define timezone (8) //北京時區調整
typedef struct rtc_time_struct
rtc_time_t;
static uint8_t month_day[12]=; //平年
static uint8_t leap_month_day[12]=; //閏年
const uint16_t dayperyear[4] = ;
// 判斷是否是閏年
// year: 需要判斷的年
// return:1:閏年
// 0: 平年
uint8_t isleapyear(uint16_t year)
else
}
return res;
}
// 將unix時間戳轉換為北京時間
// unixtime: 需要判斷的unix時間戳
// *tempbeijing:返回的北京時間
// return:none
// note:沒對輸入引數正確性做判斷
void covunixtimestp2beijing(uint32_t unixtime, rtc_time_t *tempbeijing)
//2.計算哪一月的哪一天
pr = isleapyear(tempbeijing->ui8year)?leap_month_day:month_day;
while(remaindayofyear > *(pr+tempbeijing->ui8month))
tempbeijing->ui8month++; //month
tempbeijing->ui8dayofmonth = remaindayofyear; //day
//3.計算當天時間
tempbeijing->ui8hour = totlesecnum/3600;
tempbeijing->ui8minute = (totlesecnum%3600)/60; //error:變數搞錯
tempbeijing->ui8second = (totlesecnum%3600)%60;
//4.時區調整
tempbeijing->ui8hour +=timezone;
if(tempbeijing->ui8hour>23)
}
// 將北京時間轉換為unix時間戳
// year: 需要判斷的年
// return:unix時間戳(從1970/1/1 00:00:00 到現在的秒數)
// note:沒對輸入引數正確性做判斷
uint32_t covbeijing2unixtimestp(rtc_time_t *beijingtime)
else
tempyear++;
}
//2.月的天數
while(tempmonth < beijingtime->ui8month-1)
else
tempmonth++;
}
//3.天數
daynum += (beijingtime->ui8dayofmonth-1);
//4.時分秒
secnum = daynum*24*60*60; //s
secnum += beijingtime->ui8hour*60*60;
secnum += beijingtime->ui8minute*60;
secnum += beijingtime->ui8second;
//5.時區調整
secnum -= timezone*60*60;
return secnum;
}
//測試主函式
int main()
執行結果如下:
通過站長工具驗證,測試ok:
C 北京時間與UNIX時間戳互轉
獲取從格林威治時間到當前某一時刻的總毫秒數 北京時間 精確到毫秒,否到秒 返回乙個長整數時間戳 public static long getunixtimestamp datetime datetime,bool accuratetomilliseconds 將unix時間戳轉為北京時間 時間戳 精...
python正常時間和unix時間戳相互轉換的方法
python正常時間和unix時間戳相互轉換的方法 本文例項講述了python 例如 1332888820 格式轉換成 2012 03 28 06 53 40的形式 coding utf 8 import time def timestamp datetime value format y m d ...
UTC時間與北京時間相互轉換
時間戳是指格林威治時間1970年01月01日00時00分00秒 北京時間1970年01月01日08時00分00秒 起至現在的總秒數。public class homecontroller controller public class homecontroller controller 將時間轉換成...