寫國際化的程序比較難處理的兩個問題可能是:時間問題
、 編碼問題
。
本篇文章來聊一聊時間問題。
最近設備到了國外,時間不不準了~
雜燴君一直在東八區寫代碼,處理時間問題時,習慣性的把時區寫死為東八區,即設備的小時數總是基于GMT的小時數加上8個小時作為設備的小時數。
如果設備到了國外,設備的時間就不準了,設備的小時數對不上當地的小時數。我們的設備時間,是使用設備上GPS的授時時間給設備進行時間校準的。
設備從GPS拿到的時間數據只是UTC時間。所以,不同地區的時間,需要基于UTC時間+/-時區,向西減小,向東增加。當地的時區,可以根據當地的經度進行計算,這個后面再說。
下面我們先來了解一些概念:
GMT與UTC時間
GMT時間(Greenwich Mean Time,格林威治時間),之前作為全球時間的基準參考時間。
UTC時間(Universal Time Coordinated, 世界標準時間或世界協調時間),以原子時秒長為基礎,在時刻上盡量接近于世界時的一種時間計量系統。UTC是基于標準的GMT提供的準確時間。
UTC時間和GMT時間其實是同一個時間,只不過UTC時間用秒來表示。
1、獲取UTC時間
獲取UTC時間的接口:
#include
time_ttime(time_t*tloc);
該接口返回1970-01-01 0000 +0000至今的秒數(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;
}
運行結果:
![ed8195b0-632a-11ed-8abf-dac502259ad0.png](https://file1.elecfans.com//web2/M00/97/E7/wKgaomTnO4CAS9-gAACAUCoGmO4145.png)
2、獲取GMT時間
獲取GMT時間的接口:
#include
structtm*gmtime(consttime_t*timep);
該接口返回tm結構的GMT時間(UTC時間)。
tm結構:
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;
}
運行結果:
![ed95b108-632a-11ed-8abf-dac502259ad0.png](https://file1.elecfans.com//web2/M00/97/E7/wKgaomTnO4CABOo4AACXsuhnJdQ721.png)
時區
由于世界各國家與地區經度不同,地方時區也有所不同,因此會劃分為不同的時區。
正式的時區劃分包括24個時區,每一時區由一個英文字母表示。每隔經度15°劃分一個時區,有一個例外,每個時區有一條中央子午線。
1、時區劃分方法:
現今全球共分為24個時區。英國(格林尼治天文臺舊址)為中時區(零時區)、東1—12區,西1—12區。每個時區橫跨經度15度,時間正好是1小時。最后的東、西第12區各跨經度7.5度,以東、西經180度為界。每個時區的中央經線上的時間就是這個時區內統一采用的時間,稱為區時,相鄰兩個時區的時間相差1小時。
2、經度范圍:
![eda9a8ac-632a-11ed-8abf-dac502259ad0.png](https://file1.elecfans.com//web2/M00/97/E7/wKgaomTnO4CANyU-AABDNVkJrRA289.png)
3、當地時區計算
需要用到的接口:
#include
structtm*localtime(consttime_t*timep);
計算當地時區:
#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;
}
elseif(local_time_zone>12)
{
local_time_zone-=24;
}else{}
printf("local_time_zone=%d
",local_time_zone);
return0;
}
我們當前為北京時間:
![edbdd0f2-632a-11ed-8abf-dac502259ad0.png](https://file1.elecfans.com//web2/M00/97/E7/wKgaomTnO4CAY5SUAAI85OTcZqk950.png)
我們把Ubuntu時間日期里的地點改到其它國家:
![edee3fe4-632a-11ed-8abf-dac502259ad0.png](https://file1.elecfans.com//web2/M00/97/E7/wKgaomTnO4CAThK8AAIt2kzTUS8989.png)
![eeab8a36-632a-11ed-8abf-dac502259ad0.png](https://file1.elecfans.com//web2/M00/97/E7/wKgaomTnO4CAR-BQAAIrJSbv0lo443.png)
CST 時間
CST (China Standard Time,中國標準時間)。
中國標準時間一般指北京時間。北京時間是中國采用國際時區東八時區的區時作為標準時間。而中國幅員遼闊,東西相跨5個時區(即東五區、東六區、東七區、東八區、東九區5個時區)
“北京時間”適用于中國(大陸、港澳、臺灣)境內,但在大陸的新疆、西藏等地,政府機關、企事業單位作息時間和郵政通訊費用優惠分界點雖然用北京時間來表示,但也比其他各省延晚2小時,使用UTC+6的情況更為普遍。
根據經度計算時區
時區范圍是中央經線的度數向左右分別減、加7.5度。用該地的經度除以15度,當余數小于7.5度時,商數即為該地所在的時區數,當余數大于7.5度時,商數加1即為該地所在的時區數。
#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;
}
這其實也是百度百科上提供的思路:
![eecbebfa-632a-11ed-8abf-dac502259ad0.png](https://file1.elecfans.com//web2/M00/97/E7/wKgaomTnO4GAcB8VAADHz7RS1PU622.png)
這種方式至少可以計算得到時區中心線的時區數,但是一些臨界情況可能會差1小時。在網絡上也沒有找到其它更好的解決方案。
設備的時間,如果只是作為一個顯示功能,影響可能不是很大,但是如果設備的時間來做其它事情,比如定時功能,定時多少點多少分做什么事情,影響就很大了。
對于我們的設備,定時功能使用手機APP來操作的,這時候能想到的比較好的方法就是每當使用手機APP的時候,把手機APP的時間給設備時間進行一次校準。
大家是否有其它更好的解決方案,歡迎留言討論
如果覺得文章有幫助,麻煩幫忙轉發,謝謝!
審核編輯 :李倩-
嵌入式
+關注
關注
5096文章
19189瀏覽量
308033 -
代碼
+關注
關注
30文章
4837瀏覽量
69130 -
UTC
+關注
關注
1文章
24瀏覽量
14500
發布評論請先 登錄
相關推薦
如何提高嵌入式代碼質量?
新手怎么學嵌入式?
嵌入式主板是什么意思?嵌入式主板全面解析
嵌入式系統的未來趨勢有哪些?
現場直擊 | 飛凌嵌入式亮相2024上海國際嵌入式展
![現場直擊 | 飛凌<b class='flag-5'>嵌入式</b>亮相2024上海<b class='flag-5'>國際</b><b class='flag-5'>嵌入式</b>展](https://file1.elecfans.com/web2/M00/ED/47/wKgZomZqjgOAWck6AAD04Ftdak4182.png)
embedded world China 2024上海國際嵌入式展 智慧賦能,科技全球!國際嵌入式產業菁英再聚上海
芯原亮相2024上海國際嵌入式大會
下周見!飛凌嵌入式即將亮相2024上海國際嵌入式展
![下周見!飛凌<b class='flag-5'>嵌入式</b>即將亮相2024上海<b class='flag-5'>國際</b><b class='flag-5'>嵌入式</b>展](https://file1.elecfans.com/web2/M00/EC/63/wKgZomZidZqAC3LAAACunT2iiTs101.png)
評論