寫國際化的程序比較難處理的兩個問題可能是:時間問題 、 編碼問題 。
本篇文章來聊一聊時間問題。
最近設(shè)備到了國外,時間不不準(zhǔn)了~
雜燴君一直在東八區(qū)寫代碼,處理時間問題時,習(xí)慣性的把時區(qū)寫死為東八區(qū),即設(shè)備的小時數(shù)總是基于GMT的小時數(shù)加上8個小時作為設(shè)備的小時數(shù)。
如果設(shè)備到了國外,設(shè)備的時間就不準(zhǔn)了,設(shè)備的小時數(shù)對不上當(dāng)?shù)氐男r數(shù)。我們的設(shè)備時間,是使用設(shè)備上GPS的授時時間給設(shè)備進(jìn)行時間校準(zhǔn)的。
設(shè)備從GPS拿到的時間數(shù)據(jù)只是UTC時間。所以,不同地區(qū)的時間,需要基于UTC時間+/-時區(qū),向西減小,向東增加。當(dāng)?shù)氐臅r區(qū),可以根據(jù)當(dāng)?shù)氐慕?jīng)度進(jìn)行計(jì)算,這個后面再說。
下面我們先來了解一些概念:
GMT與UTC時間
GMT時間(Greenwich Mean Time,格林威治時間),之前作為全球時間的基準(zhǔn)參考時間。
UTC時間(Universal Time Coordinated, 世界標(biāo)準(zhǔn)時間或世界協(xié)調(diào)時間),以原子時秒長為基礎(chǔ),在時刻上盡量接近于世界時的一種時間計(jì)量系統(tǒng)。UTC是基于標(biāo)準(zhǔn)的GMT提供的準(zhǔn)確時間。
UTC時間和GMT時間其實(shí)是同一個時間,只不過UTC時間用秒來表示。
1、獲取UTC時間
獲取UTC時間的接口:
#include?time_t?time(time_t?*tloc);
該接口返回1970-01-01 0000 +0000至今的秒數(shù)(UTC)。
使用例子:
#include?#include? time_t?get_utc_time(void) { ????return?time(NULL); } int?main(int?argc,?char?**argv) { ????time_t?utc_time?=?get_utc_time(); ????printf("utc_time?=?%ld?s ",?utc_time); ????return?0; }
運(yùn)行結(jié)果:
2、獲取GMT時間
獲取GMT時間的接口:
#include?struct?tm?*gmtime(const?time_t?*timep);
該接口返回tm結(jié)構(gòu)的GMT時間(UTC時間)。
tm結(jié)構(gòu):
struct?tm? { ????int?tm_sec;????/*?Seconds?(0-60)?*/ ????int?tm_min;????/*?Minutes?(0-59)?*/ ????int?tm_hour;???/*?Hours?(0-23)?*/ ????int?tm_mday;???/*?Day?of?the?month?(1-31)?*/ ????int?tm_mon;????/*?Month?(0-11)?*/ ????int?tm_year;???/*?Year?-?1900?*/ ????int?tm_wday;???/*?Day?of?the?week?(0-6,?Sunday?=?0)?*/ ????int?tm_yday;???/*?Day?in?the?year?(0-365,?1?Jan?=?0)?*/ ????int?tm_isdst;??/*?Daylight?saving?time?*/ };
使用例子:
#include?#include? time_t?get_utc_time(void) { ????return?time(NULL); } int?main(int?argc,?char?**argv) { ????time_t?utc_time?=?get_utc_time(); ????printf("utc_time?=?%ld?s ",?utc_time); ????struct?tm?*gmt_tm?=?gmtime(&utc_time);? ????printf("gmt?time?=?%.4d-%.2d-%.2d?%.2d:%.2d:%.2d ",?gmt_tm->tm_year?+?1900, ?????????????????????????????????????????????????????????gmt_tm->tm_mon?+?1, ?????????????????????????????????????????????????????????gmt_tm->tm_mday, ?????????????????????????????????????????????????????????gmt_tm->tm_hour, ?????????????????????????????????????????????????????????gmt_tm->tm_min, ?????????????????????????????????????????????????????????gmt_tm->tm_sec); ????return?0; }
運(yùn)行結(jié)果:
時區(qū)
由于世界各國家與地區(qū)經(jīng)度不同,地方時區(qū)也有所不同,因此會劃分為不同的時區(qū)。
正式的時區(qū)劃分包括24個時區(qū),每一時區(qū)由一個英文字母表示。每隔經(jīng)度15°劃分一個時區(qū),有一個例外,每個時區(qū)有一條中央子午線。
1、時區(qū)劃分方法:
現(xiàn)今全球共分為24個時區(qū)。英國(格林尼治天文臺舊址)為中時區(qū)(零時區(qū))、東1—12區(qū),西1—12區(qū)。每個時區(qū)橫跨經(jīng)度15度,時間正好是1小時。最后的東、西第12區(qū)各跨經(jīng)度7.5度,以東、西經(jīng)180度為界。每個時區(qū)的中央經(jīng)線上的時間就是這個時區(qū)內(nèi)統(tǒng)一采用的時間,稱為區(qū)時,相鄰兩個時區(qū)的時間相差1小時。
2、經(jīng)度范圍:
3、當(dāng)?shù)貢r區(qū)計(jì)算
需要用到的接口:
#include?struct?tm?*localtime(const?time_t?*timep);
計(jì)算當(dāng)?shù)貢r區(qū):
#include?#include? time_t?get_utc_time(void) { ????return?time(NULL); } int?main(int?argc,?char?**argv) { ????time_t?utc_time?=?get_utc_time(); ????printf("utc_time?=?%ld?s ",?utc_time); ????struct?tm?*gmt_tm?=?gmtime(&utc_time);? ????printf("gmt?time?=?%.4d-%.2d-%.2d?%.2d:%.2d:%.2d ",?gmt_tm->tm_year?+?1900, ?????????????????????????????????????????????????????????gmt_tm->tm_mon?+?1, ?????????????????????????????????????????????????????????gmt_tm->tm_mday, ?????????????????????????????????????????????????????????gmt_tm->tm_hour, ?????????????????????????????????????????????????????????gmt_tm->tm_min, ?????????????????????????????????????????????????????????gmt_tm->tm_sec); ????int?gmt_hour?=?gmt_tm->tm_hour; ????struct?tm?*local_tm?=?localtime(&utc_time);? ????printf("local?time?=?%.4d-%.2d-%.2d?%.2d:%.2d:%.2d ",?local_tm->tm_year?+?1900, ???????????????????????????????????????????????????????????local_tm->tm_mon?+?1, ???????????????????????????????????????????????????????????local_tm->tm_mday, ???????????????????????????????????????????????????????????local_tm->tm_hour, ???????????????????????????????????????????????????????????local_tm->tm_min, ???????????????????????????????????????????????????????????local_tm->tm_sec); ????int?local_hour?=?local_tm->tm_hour; ????int?local_time_zone?=?local_hour?-?gmt_hour; ????if?(local_time_zone?-12)? ????{ ????????local_time_zone?+=?24;? ????}? ????else?if?(local_time_zone?>?12)? ????{ ????????local_time_zone?-=?24; ????}else{} ????printf("local_time_zone?=?%d ",?local_time_zone); ????return?0; }
我們當(dāng)前為北京時間:
我們把Ubuntu時間日期里的地點(diǎn)改到其它國家:
?
CST 時間
CST (China Standard Time,中國標(biāo)準(zhǔn)時間)。
中國標(biāo)準(zhǔn)時間一般指北京時間。北京時間是中國采用國際時區(qū)東八時區(qū)的區(qū)時作為標(biāo)準(zhǔn)時間。而中國幅員遼闊,東西相跨5個時區(qū)(即東五區(qū)、東六區(qū)、東七區(qū)、東八區(qū)、東九區(qū)5個時區(qū))
“北京時間”適用于中國(大陸、港澳、臺灣)境內(nèi),但在大陸的新疆、西藏等地,政府機(jī)關(guān)、企事業(yè)單位作息時間和郵政通訊費(fèi)用優(yōu)惠分界點(diǎn)雖然用北京時間來表示,但也比其他各省延晚2小時,使用UTC+6的情況更為普遍。
根據(jù)經(jīng)度計(jì)算時區(qū)
時區(qū)范圍是中央經(jīng)線的度數(shù)向左右分別減、加7.5度。用該地的經(jīng)度除以15度,當(dāng)余數(shù)小于7.5度時,商數(shù)即為該地所在的時區(qū)數(shù),當(dāng)余數(shù)大于7.5度時,商數(shù)加1即為該地所在的時區(qū)數(shù)。
#include?#include? int?calc_timezone(double?longitude) { ????int?timezone?=?0; ????int?quotient?=?(int)(longitude?/?15); ????double?remainder?=?(longitude?-?quotient?*?15); ????printf("quotient?=?%d,?remainder?=?%lf ",?quotient,?remainder); ????if?(remainder?<=?7.5) ????{ ????????timezone?=?quotient; ????} ????else ????{ ????????timezone?=?quotient?+?(quotient?>=?0???+?1?:?-1); ????} ????return?timezone; } int?main(int?argc,?char?**argv) { ????while?(1) ????{ ????????double?longitude?=?0.0; ????????printf("please?input?longitude:"); ????????scanf("%lf",?&longitude); ????????printf("longitude?=?%lf ",?longitude); ????????int?timezone?=?calc_timezone(longitude); ????????printf("timezone?=?%d ",?timezone); ????} ????return?0; }
這其實(shí)也是百度百科上提供的思路:
這種方式至少可以計(jì)算得到時區(qū)中心線的時區(qū)數(shù),但是一些臨界情況可能會差1小時。在網(wǎng)絡(luò)上也沒有找到其它更好的解決方案。
設(shè)備的時間,如果只是作為一個顯示功能,影響可能不是很大,但是如果設(shè)備的時間來做其它事情,比如定時功能,定時多少點(diǎn)多少分做什么事情,影響就很大了。
對于我們的設(shè)備,定時功能使用手機(jī)APP來操作的,這時候能想到的比較好的方法就是每當(dāng)使用手機(jī)APP的時候,把手機(jī)APP的時間給設(shè)備時間進(jìn)行一次校準(zhǔn)。
編輯:黃飛
?
評論
查看更多