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