1 前言
在嵌入式系統中(包括大部分電子設備:手機、平板、手環、手表等等),時間的概念非常重要。如打印log時的時間戳、定時關機、心跳上報、日歷功能、鬧鐘等等。上述這些功能都需要一個相對精確的時間系統。
經常涉及的與時間相關的術語包括:硬件時鐘、系統時鐘、網絡時鐘、時區修改和同步。日常生活和工作中可能接觸到的時區概念包括:UTC
、GMT
、CST
、DST
。在網絡時間中可能接觸到的概念又有:NTP
、SNTP
、NITZ
。本文將會對上述涉及到的概念進行系統的整理和探討。
2 了解概念
下面對幾個概念進行集中陳述。
2.1 時區
時區[1] 是指地球上的不同區域使用同一個時間定義。以前,人們通過觀察太陽的位置(時角)決定時間,這就使得不同經度的地方的時間有所不同(地方時)。1863年,首次使用時區的概念。通過設立一個區域的標準時間部分地解決了這個問題。
時區劃分規則:將全球按經線從東到西劃分為24個時區,其中東、西各12個時區,每個時區跨越經度15°,0區和12區跨越東西各7.5°。規定相鄰區域的時間相差1小時,這樣24個時區剛好是24小時,地球自轉一圈。如下圖是全球時區的劃分明細。常見的時區概念包括:GMT
、UTC
、CST
、DST
。
-
GMT(Greenwich Mean Time)指格林尼治標準時間,它是第一個世界時。
GMT 12:00
就是指格林尼治天文臺當地的正午12:00,而GMT+8 12:00,則是指東八區的北京當地時間的12:00。格林尼治標準時間的正午是指當太陽橫穿格林尼治子午線時(也就是在格林尼治時)的時間。由于地球在它的橢圓軌道里的運動速度不均勻,這個時刻可能和實際的太陽時相差16分鐘。 - UTC(Coordinated Universal Time)是指協調世界時,又稱世界標準時間。它是以原子時為基礎,由于現在世界上最精確的原子鐘50億年才會誤差1秒,所以UTC時間標準非常精確。每隔幾年協調世界時組織都會給世界時+1秒,讓基于原子鐘的世界時和基于天文學(人類感知)的格林尼治標準時間(GMT)相差不至于太大。UTC是現在世界使用的標準時間,UTC與GMT時間基本相同。
-
CST(China Standard Time)指中國標準時間。
GMT + 8 = UTC + 8 = CST
。 - DST(Daylight Saving Time)夏令時,又稱:“日光節約時制”。是一種為節約能源而人為規定地方時間的制度,在這一制度實行期間所采用的統一時間稱為“夏令時間”。一般在天亮早的夏季人為將時間調快一小時,可以使人早起早睡,減少照明量,以充分利用光照資源,從而節約照明用電。各個采納夏時制的國家具體規定不同。全世界有近110個國家每年要實行夏令時。中國現在已經不再使用夏令時。
2.2 時鐘
常見的幾個時鐘概念包括:硬件時鐘、系統時鐘、網絡時鐘。
- 硬件時鐘。在嵌入式領域也就是RTC時鐘(Real Time Clock)。大多采用精度較高的晶振作為時鐘源。在主電源掉電時,還可以工作,需要外加電池供電。通常把集成于芯片內部的 RTC 稱為片內 RTC,在芯片外擴展的 RTC 稱為外部 RTC。
-
系統時鐘。指軟件系統的時鐘。在
linux
和一些rtos
中,啟動時會去讀取硬件時鐘(RTC),之后則獨立運行。獨立運行的好處對于普通用戶意義不大,但對于linux
網絡管理員卻有很大的用處。例如,要將一個很大的網絡中(跨越若干時區)的服務器同步,假如位于美國紐約的linux
服務器和北京的Linux服務器,其中一臺服務器無須改變硬件時鐘而只需臨時設置一個系統時間,如要將北京服務器上的系統時間設置為紐約時間,兩臺服務器完成文件的同步后,再與原來的硬件時鐘同步一下即可。這樣系統時鐘和硬件時鐘就提供了更為靈活的操作。 -
網絡時鐘。網絡時鐘的時間源來自于專業授時的服務器(SNTP、NTP)。實現方案是在網絡上指定若干時鐘源服務器,為用戶提供授時服務,并且這些服務器之間能夠相互比較校正,以提高準確度。在移動蜂窩網絡中,基站也可以通過無線網絡向移動設備提供本地日期和時間、時區、夏時制偏移。網絡時鐘的精度一般都很高,可以達到毫秒級,可以用來對嵌入式設備進行時間同步。
2.3 時間同步
時間同步對嵌入式設備很重要,一些功能業務甚至依賴于時間信息來完成。如自注冊DM業務,需要周期性的向運營商服務器上報信息,這些信息上報都是以天或者是月為周期,不可能靠軟件timer
來實現。和此類似的功能都需要以標準時間為基準,以此完成條件的觸發。下面來探討時間同步的話題。
2.3.1 SNTP
SNTP是簡單網絡時間協議(Simple Network Time protocol)的簡稱,它是目前Internet
網上實現時間同步的一種重要工程化方法。SNTP
由NTP
改編而來,SNTP
其實是NTP
的子集,只是NTP
可以 分發和授時,而SNTP
只有授時沒有分發,也就是說你只能從SNTP
獲取時間,其他的什么都做不了,SNTP
簡化了NTP
的全部流程,這樣節約成本,但只能同步一個時間源。SNTP
協議采用客戶端/服務器的工作方式。SNTP
服務器通過接收GPS
信號或自帶的原子鐘作為系統的時間基準。SNTP
客戶端(嵌入式設備)能夠通過定期訪問SNTP
服務器獲得準確的時間信息,用于調整客戶端自身所在系統的時間,達到同步時間的目的。在linux
系統中一般有現成的SNTP客戶端可以安裝使用,在其他的嵌入式平臺上需要移植或自主開發。一些可用的SNTP服務器匯總如下(親測可以ping通):
- 國家授時中心 NTP 服務器:ntp.ntsc.ac.cn
- 阿里云公共 NTP 服務器:time.pool.aliyun.com
- 騰訊云公共 NTP 服務器:time1.cloud.tencent.com
- 教育網(高校自建)服務器:ntp.sjtu.edu.cn
2.3.2 NITZ
NITZ(Network Identity and Time Zone)是一種通過無線網絡向移動設備提供本地日期和時間、時區、夏時制偏移,以及網絡提供商身份信息的機制,這通常用于無線蜂窩網絡設備(手機、通信模組)的自動更新系統時間。對于其他網絡時間協議,NITZ的質量和執行力度都相對較弱。有些運營商根本就不支持,例如在國內,本地測試(廣東)發現,中國移動和中國電信是支持NITZ
的,中國聯通就根本不支持。再者,與SNTP
相比,SNTP
授時能使時間分辨率達到毫秒級,NITZ
則“對于時間只能精確到數分鐘”。但NITZ
不用連上互聯網,能駐上無線蜂窩網絡就行,而SNTP
必須連接互聯網。
3 應用
3.1 linux中時間命令
linux命令中的date
命令是用來設置和查詢系統時間的,而hwclock
命令是用來設置和讀寫RTC
時間(硬件時間)。有一點需要注意,linux
的時間系統是由「新紀元時間」Epoch開始計算起,單位為秒,Epoch則是指定為1970年1月1日0點0分0秒,格林威治時間(GMT)。date +%s
命令可以讀取從1970年1月1日0點0分0秒開始到當前的秒數。
- 讀取當前秒數(以1970年1月1日0點0分0秒為計算起點);
book@zhang.c:~$?date?+%s
1653752545
-
讀系統時間:
date
;
book@zhang.c:~$?date
Sat?May?28?2226?CST?2022
-
設置系統時間:
date -s "20220501 1200"
,date -s
命令設置時間只會影響系統時間,不會設置RTC時間,如果需要把當前系統時間同步設置到RTC中,需要額外調用hwclock
命令;
book@zhang.c:~$?date?-s?"20220501?1200"
Sun?May??1?1200?CST?2022
-
有關
rtc
時間的操作,主要是hwclock
命令使用;
#讀取并打印當前的rtc時間
hwclock?-r
#讀取RTC時間并設置到系統時間中去
hwclock?-s?
#把當前的系統時間設置到RTC中
hwclock?-w?????
#完整的設置RTC的時間可執行如下命令
date?-s?"20220501?1200"
hwclock?-w
-
date
命令格式化的顯示時間,可以看如下的Command
這一列。
????????Format/result???????????|???????Command??????????????|??????????Output
--------------------------------+----------------------------+------------------------------
YYYY-MM-DD??????????????????????|?date?-I????????????????????|?$(date?-I)
YYYY-MM-DD_hhss?????????????|?date?+%F_%T????????????????|?$(date?+%F_%T)
YYYYMMDD_hhmmss?????????????????|?date?+%Y%m%d_%H%M%S????????|?$(date?+%Y%m%d_%H%M%S)
YYYYMMDD_hhmmss?(UTC?version)???|?date?--utc?+%Y%m%d_%H%M%SZ?|?$(date?--utc?+%Y%m%d_%H%M%SZ)
YYYYMMDD_hhmmss?(with?local?TZ)?|?date?+%Y%m%d_%H%M%S%Z??????|?$(date?+%Y%m%d_%H%M%S%Z)
YYYYMMSShhmmss??????????????????|?date?+%Y%m%d%H%M%S?????????|?$(date?+%Y%m%d%H%M%S)
YYYYMMSShhmmssnnnnnnnnn?????????|?date?+%Y%m%d%H%M%S%N???????|?$(date?+%Y%m%d%H%M%S%N)
YYMMDD_hhmmss???????????????????|?date?+%y%m%d_%H%M%S????????|?$(date?+%y%m%d_%H%M%S)
Seconds?since?UNIX?epoch:???????|?date?+%s???????????????????|?$(date?+%s)
Nanoseconds?only:???????????????|?date?+%N???????????????????|?$(date?+%N)
Nanoseconds?since?UNIX?epoch:???|?date?+%s%N?????????????????|?$(date?+%s%N)
ISO8601?UTC?timestamp???????????|?date?--utc?+%FT%TZ?????????|?$(date?--utc?+%FT%TZ)
ISO8601?UTC?timestamp?+?ms??????|?date?--utc?+%FT%T.%3NZ?????|?$(date?--utc?+%FT%T.%3NZ)
ISO8601?Local?TZ?timestamp??????|?date?+%FT%T%Z??????????????|?$(date?+%FT%T%Z)
YYYY-MM-DD?(Short?day)??????????|?date?+%F(%a)?????????????|?$(date?+%F(%a))
YYYY-MM-DD?(Long?day)???????????|?date?+%F(%A)?????????????|?$(date?+%F(%A))
3.2 SNTP和NITZ
在手機(包括Android和功能機)和模組產品中,SNTP
和NITZ
兩種同步系統時間的策略一般都會用到。默認使用的是NITZ來獲取網絡時間,但是需要有運營商的支持才能使用(中國聯通就不支持),而有些設備產品只支持WIFI等無線網絡,而不支持移動網絡,此時就需要采用SNTP
方式來獲取網絡時間進行同步了。SNTP
協議時間戳是以1900年1月1日0點0分0秒為起點,而linux
時間戳從1970年1月1日0點0分0秒開始記秒數,即記錄到SNTP
結構體中的時間包含了JAN_1970(從1900到1970共70年的秒數)。在拿到SNTP
時間后,往linux同步時間時,需要減掉JAN_1970。
4 總結
-
UTC
與GMT
時間基本相同; - 硬件時鐘和系統時鐘同步后,會分開獨立運行;
-
網絡時鐘的精度都比較高,可以用
SNTP
或NITZ
來進行同步,尤其SNTP
時間同步精度可以達到毫秒級。 -
linux
系統的計時起點為1970年1月1日0點0分0秒,其他嵌入式系統在做網絡時間同步時,也一定要確認好計時起點。
?
評論
查看更多