C++時間的處理
文|Seraph
01 | 時間術語
平太陽時
由於真太陽的執行速度和時角變化率不均勻,不適於作為計量均勻時間的基準,在天文學中引入平太陽。它在天赤道上作勻速運動,其速度與真太陽的平均速度相一致。
世界時 UT
Universal Time,是一種以格林尼治子夜起算的平太陽時。分別有UT0、UT1、UT2。
UT0:是由一個天文臺的天文觀測直接測定的世界時,沒有考慮極移造成的天文臺地理座標變化。該系統曾長期被認為是穩定均勻的時間計量系統,得到過廣泛應用。又稱格林尼治平時 GMT。
UT1:系統是在UT0的基礎上加入了極移改正Δλ ,修正地軸擺動的影響。UT1是目前使用的世界時標準。被作為目前世界民用時間標準UTC在增減閏秒時的參照標準。
UT2:系統是UT1的平滑處理版本,在UT1基礎上加入了地球自轉速率的季節性改正ΔT 。
格林尼治平時 GMT
Greenwich Mean Time 是指位於英國倫敦郊區的皇家格林尼治天文臺當地的平太陽時。
協調世界時 UTC
Coordinated Universal Time 是最主要的世界時間標準,其以原子時秒長為基礎,在時刻上儘量接近於格林尼治標準時間。
UTC時區
如果本地時間比UTC時間快,例如中國時間比UTC快8小時,就會寫作UTC+8,俗稱東八區。相反,如果本地時間比UTC時間慢,例如夏威夷的時間比UTC時間慢10小時,就會寫作UTC-10,俗稱西十區。
UNIX 時間
又稱POSIX
時間是UNIX
或類UNIX
系統使用的時間表示方式:從協調世界時(UTC
)1970年1月1日0時0分0秒起至現在的總秒數,不考慮閏秒。
2038年問題:當前大部分系統使用的時32位二進位制數字來表示時間,可以表示136年的秒數,表示協調世界時間1901年12月13星期五20時45分52秒至2038年1月19日3時14分07秒(二進位制:01111111 11111111 11111111 11111111)。超過該表示範圍,軟體便會發送問題,導致系統癱瘓。
閏秒
是在協調世界時中增加或減少一秒,使它與平太陽時貼近所做調整。
02 | 軟體上對時間的理解
大部分軟體都是使用UTC時間,UNIX時間僅是一種UTC時間的表示方法。
03 | C++時間結構定義
time_t
32位或64位的長度資料,用來儲存從1970年1月1日0時0分0秒到現在經過的秒數。
timeval 結構體
由linux系統在_timeval.h
檔案中定義,如需使用的包含<sys/time.h>
即可。
struct timeval { long tv_sec; /*秒*/ long tv_usec; /*微秒*/ };
tm 結構體
struct tm { int tm_sec;// seconds after the minute - [0, 60] including leap second int tm_min;// minutes after the hour - [0, 59] int tm_hour;// hours since midnight - [0, 23] int tm_mday;// day of the month - [1, 31] int tm_mon;// months since January - [0, 11] int tm_year;// years since 1900 int tm_wday;// days since Sunday - [0, 6] int tm_yday;// days since January 1 - [0, 365] int tm_isdst; // daylight savings time flag };
這裡的year是從1900年開始的。
04 時間函式
以下函式的引數和返回值,尤其要注意是否是本地時區的值。
函式名 | 函式原型 | 功能 |
---|---|---|
asctime |
char *asctime(const struct tm* );
|
將tm結構時間轉換成字串 |
ctime |
char *ctime(const time_t*);
|
將time_t時間轉換成字串(本地時區值) |
difftime |
double difftime(time_t , time_t);
|
返回兩個time_t時間差 |
gettimeofday |
int gettimeofday(struct timeval*, struct timezone* );
|
返回當前時間距離1970年的秒數和微妙數以及時區 |
gmtime |
struct tm* gmtime(const time_t*);
|
將time_t轉換成UTC時間並以tm結構返回 |
localtime |
struct tm* localtime(const time_t* );
|
將time_t轉換成UTC時間並以tm結構返回(本地時區值) |
mktime |
time_t mktime(struct tm* );
|
將tm時間(本地時區值)轉換為time_t |
time |
time_t time(time_t* );
|
獲得time_t型別的UTC時間 |
strftime |
size_t strftime(char *strDest, size_t maxsize, const char *format, const struct tm *timeptr);
|
時間格式化(類似於printif) |
strftime的格式化命令
%a 星期幾的簡寫
%A 星期幾的全稱
%b 月分的簡寫
%B 月份的全稱
%c 標準的日期的時間串
%C 年份的後兩位數字
%d 十進位制表示的每月的第幾天
%D 月/天/年
%e 在兩字元域中,十進位制表示的每月的第幾天
%F 年-月-日
%g 年份的後兩位數字,使用基於周的年
%G 年分,使用基於周的年
%h 簡寫的月份名
%H 24小時制的小時
%I 12小時制的小時
%j 十進位制表示的每年的第幾天
%m 十進位制表示的月份
%M 十時製表示的分鐘數
%n 新行符
%p 本地的AM或PM的等價顯示
%r 12小時的時間
%R 顯示小時和分鐘:hh:mm
%S 十進位制的秒數
%t 水平製表符
%T 顯示時分秒:hh:mm:ss
%u 每週的第幾天,星期一為第一天 (值從0到6,星期一為0)
%U 第年的第幾周,把星期日做為第一天(值從0到53)
%V 每年的第幾周,使用基於周的年
%w 十進位制表示的星期幾(值從0到6,星期天為0)
%W 每年的第幾周,把星期一做為第一天(值從0到53)
%x 標準的日期串
%X 標準的時間串
%y 不帶世紀的十進位制年份(值從0到99)
%Y 帶世紀部分的十制年份
%z,%Z 時區名稱,如果不能得到時區名稱則返回空字元。
%% 百分號
具體內容詳解見cppreference 。