日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

时区与time/gmtime/localtime/mktime/ctime函数联系

發(fā)布時(shí)間:2024/3/26 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 时区与time/gmtime/localtime/mktime/ctime函数联系 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)
參考:https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/mktime-mktime32-mktime64?view=msvc-170
參考:https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/localtime-localtime32-localtime64?view=msvc-170
參考:https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/gmtime-gmtime32-gmtime64?view=msvc-170
參考:https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/ctime-ctime32-ctime64-wctime-wctime32-wctime64?view=msvc-170
參考:https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/time-time32-time64?view=msvc-170

經(jīng)常用time函數(shù)的時(shí)候,獲取了從一個(gè)1970年1月1日0時(shí)0分0秒開始的秒數(shù)計(jì)數(shù),但是這個(gè)計(jì)數(shù)是基于當(dāng)?shù)貢r(shí)區(qū)時(shí)間計(jì)數(shù),還是格林威治時(shí)間計(jì)數(shù),自己心里還是有問號(hào)在的。

驗(yàn)證測(cè)試

確認(rèn)也不難,查文檔,自己測(cè)試試試看,就有了下面這些記錄了:

// 時(shí)間0值,代表的時(shí)間是什么時(shí)間呢?是1970.1.1,格林威治0:0:0,東8區(qū)是8:00:00 // 參考輸出 time0=0 Thu Jan 1 08:00:00 1970 time_t n0 = 0; printf("time0=%d %s\n", n0, ctime(&n0));// 獲取當(dāng)前時(shí)間: 格林威治時(shí)間 // 參考 now=time(NULL)=1648340045 %86400=845 Sun Mar 27 08:14:05 2022 // 參考中可以看出,845是0:14:05時(shí)刻,這個(gè)時(shí)間值是格林威治的時(shí)刻,東8區(qū)需要+8小時(shí) time_t now = time(NULL); printf("now=time(NULL)=%d %86400=%d %s", n, n%86400, ctime(&n));// gm為格林威治時(shí)間,直接使用time_t轉(zhuǎn)換即可得到tm結(jié)構(gòu) // 參考 使用now轉(zhuǎn)換格力威支時(shí)刻,顯示的是 gm.hour=0, min=14, sec=5 struct tm* gm = gmtime(&now); printf("gm.hour=%d, min=%d, sec=%d\n", gm->tm_hour, gm->tm_min, gm->tm_sec);// local為當(dāng)?shù)貢r(shí)間,使用time_t格林威治時(shí)間+時(shí)區(qū)偏差,生成tm結(jié)構(gòu) // 參考 使用now轉(zhuǎn)換當(dāng)?shù)貢r(shí)刻,顯示的是 local.hour=8, min=14, sec=5 struct tm* local = localtime(&now); printf("local.hour=%d, min=%d, sec=%d\n", local->tm_hour, local->tm_min, local->tm_sec);// mktime輸入的是localtime-tm結(jié)構(gòu),得到格林威治時(shí)間time_t // ctime展示的當(dāng)?shù)貢r(shí)間localtime串信息 // 參考 使用local轉(zhuǎn)換,顯示的是 mktime=1648340045, %86400=845, Sun Mar 27 08:14:05 2022 time_t l = mktime(local); printf("mktime=%d, %86400=%d, %s", l, l%86400, ctime(&l));// localtime與gmtime兩者關(guān)系: 例如 localtime北京時(shí)間 = gmtime格林威治時(shí)間 +8小時(shí)

如果想做時(shí)區(qū)自動(dòng)轉(zhuǎn)換也是可以的:
例如當(dāng)前計(jì)算機(jī)采用的東八區(qū)時(shí)間,想使用timezone-0作為程序的時(shí)區(qū)設(shè)置
通過:linux版本使用tzset、windows版本使用_tzset設(shè)置時(shí)區(qū)

// 設(shè)置程序使用時(shí)區(qū)0 _putenv_s("TZ", "GMT-0"); _tzset();// gmtime與localtime就會(huì)一致了, ctime展示出的也是設(shè)定timezone=0的時(shí)間了 struct tm* gm = gmtime(&now); struct tm* local = localtime(&now); printf("current: %s", ctime(&now));

敘述理解

研究時(shí)間這塊,跟我之前理解偏差最大的一個(gè)點(diǎn)是:

  • time(NULL)總是返回的是當(dāng)前格林威治時(shí)間,不論系統(tǒng)/程序采用的哪個(gè)時(shí)區(qū);
  • 正常使用的情況下:time_t上的存儲(chǔ)值總是描述格林威治時(shí)間;
  • tm結(jié)構(gòu)存儲(chǔ)值有時(shí)用來描述格林威治時(shí)間gmtime,有時(shí)用來描述當(dāng)?shù)貢r(shí)間localtime-當(dāng)前時(shí)區(qū)時(shí)間;
  • ctime考慮了時(shí)區(qū),輸入值要求time_t是格林威治時(shí)間,輸出來的值總是用來描述當(dāng)?shù)貢r(shí)間-當(dāng)前時(shí)區(qū)時(shí)間;
  • mktime考慮了時(shí)區(qū),輸入的值總是要求localtime-tm結(jié)構(gòu)-當(dāng)前時(shí)區(qū)時(shí)間,輸出值格林威治時(shí)間;

注意:

  • ctime返回的是靜態(tài)變量地址;更要注意gmtime與localtime返回的靜態(tài)變量地址是同一個(gè),后調(diào)用的會(huì)覆蓋上次調(diào)用的值;
  • tm結(jié)構(gòu)上tm_year不同于time_t-從1970年1月1日開始,tm_year而是從1900年開始計(jì)數(shù),輸出時(shí)要+1900;
  • tm結(jié)構(gòu)上tm_month從0開始,輸出時(shí)需要+1; tm_mday是從1開始; tm_hour, tm_min, tm_sec的范圍皆是[0, 59].
  • mktime時(shí),不需要輸入tm_wday and tm_yday。
  • Windows下:_mktime64/time handles dates from midnight, January 1, 1970 to 23:59:59, December 31, 3000. if the calendar time can’t be represented, returns -1.
  • Windows下:localtime/gmtime/ctime return NULL if the date passed to the function is Before midnight, January 1, 1970.

測(cè)試程序與輸出

測(cè)試程序

#include <stdio.h> #include <time.h>int main(){time_t n0 = 0;printf("time0=%d %s\n", n0, ctime(&n0));time_t n = time(NULL);printf("now=time(NULL)=%d %86400=%d %s", n, n%86400, ctime(&n));struct tm* gm = gmtime(&n);printf("gm.hour=%d, min=%d, sec=%d\n", gm->tm_hour, gm->tm_min, gm->tm_sec);struct tm* local = localtime(&n);printf("local.hour=%d, min=%d, sec=%d\n", local->tm_hour, local->tm_min, local->tm_sec);time_t l = mktime(local);printf("mktime=%d, %86400=%d, %s\n", l, l%86400, ctime(&l));struct tm t;t.tm_year = 70;t.tm_mon = 1;t.tm_mday = 1; // 注: windows下mktime不支持東8區(qū)取1970.1.1號(hào)8點(diǎn)前時(shí)間;linux是可以的;windows下可以取往后延一天的0點(diǎn)時(shí)間值。t.tm_hour = 0;t.tm_min = 0;t.tm_sec = 0;time_t curr = mktime(&t);printf("local-1970.1.1=%d %86400=%d %s\n", curr, curr % 86400, ctime(&curr));printf("(now-local@1970.1.1)%86400 = %d\n", (n - curr) % 86400);return 0; }

輸出

time0=0 Thu Jan 1 08:00:00 1970now=time(NULL)=1648340045 %86400=845 Sun Mar 27 08:14:05 2022 gm.hour=0, min=14, sec=5 local.hour=8, min=14, sec=5 mktime=1648340045, %86400=845, Sun Mar 27 08:14:05 2022local-1970.1.1=-28800 %86400=-28800 Thu Jan 1 00:00:00 1970(now-local@1970.1.1)%86400 = 29645

(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)

總結(jié)

以上是生活随笔為你收集整理的时区与time/gmtime/localtime/mktime/ctime函数联系的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。