關於linux中的時間 時區問題


本文部分來源於:  http://hi.baidu.com/peruke/blog/item/b8de06ec6a04583b27979132.html

系統是fedora:

glibc實現了從RTC時間到人可讀時間的一個轉換,一般系統不適用 環境變量TZ進行時區的設置,因為環境變量存在一些缺陷,在fedora中,系統是的時區設置為時區文件/etc/localtime,這個文件是一個/usr/share/zoneinfo/ 路徑下面的時區文件的 軟連接。時區文件的定義實在glibc的源碼中就已經定義好的,因為glibc中有單獨的timezone文件夾。

 

環境變量TZ的格式以及tzset()說明如下:

  

TZ=tzn[+|-]hh[:mm[:ss]][dzn]

eg:TZ="CST-8"

tzn:三字母時區名,例如PST,你必須指出本地時間距UTC的偏移量。
hh:UTC與本地時間的時差,任選帶符號的。
mm:分鍾,由冒號(:)與hh分隔開。
ss:秒鍾,用冒號(:)與mm分隔開。
dzn:三字母夏令時時區例如PDT。如果夏令時沒作用,設置TZ時不設置dzn的值。C運行庫假設在計算夏令時(DST)時執行美國的規則。

其實tzn和dzn可為任意3個字母,只要中間的時差設置正確,localtime()和gmtime()函數調用都會處理正確。要注意一點,比如要將時區TZ設置為中國所在的東八區(即UTC+8:00),不使用夏令時,使用如下語句:

setenv("TZ", "GMT-8", 1);

注意是GMT-8而不是GMT+8,要不就設為了西八區,要比UTC還慢8個小時,這一點比較令人費解。

例如,為了設置TZ環境為德國對應的當前時區,你可以使用如下語句之一:
set TZ=GST-1GDT
set TZ=GST+1GDT
這些字符串使用GST指出德國標准時間,假設德國是超前UTC一個小時,並假設夏令時起作用。
如果TZ值沒設置,tzset試圖使用操作系統指定的時區信息,在Windwos NT和Windows95之下,這個信息指定在控制面版的日期/時間應用中,如果tzset不能獲取這些信息,它缺省使用PST8PDT,它指定為太平洋標准時間。

基於TZ環境變量的值,當調用tzset時把如下值賦給全局變量daylight、timezone和tzname:
全局變量    說明                                                     缺省值
daylight      如果在TZ設置中指定夏令時時區          1則為非0值;否則為0
timezone    UTC和本地時間之間的時差,單位為秒   28800(28800秒等於8小時)
tzname[0] TZ環境變量的時區名稱的字符串值        如果TZ未設置則為空 PST
tzname[1]   夏令時時區的字符串值;                        如果TZ環境變量中忽略夏令時時區則為空PDT在上表中daylight和tzname數組的缺省值對應於"PST8PDT"。

如果從TZ環境變量忽略DST時區,daylight的值為0,ftime,gmtime和localtime函數對於它們的DST標志返回0。
例子

/ *
TZSET.C: This program first sets up the time zone by*
placing the variable named TZ=EST5 in the environment*
table. It then uses tzset to set the global variables* 
named daylight, timezone, and tzname.*/
#include  
#include 
#include  
void main( void ) 
{
if( putenv( "TZ=EST5EDT" ) == -1 )
{
   printf( "Unable to set TZ/n" );exit( 1 );
}
else

   tzset(); printf( "daylight = %d\n", daylight ); 
   printf( "timezone = %ld\n", timezone ); 
   printf( "tzname[0] = %s\n", tzname[0] );
}
exit( 0 );
}

輸出 
daylight = 1 
timezone = 18000 
tzname[0] = EST

參見
asctime,ftime,gmtime,localtime,time,utime

 

1,時間保存在硬件實時鍾(RTC)中,RTC由主板電池供電,即使關斷電源也不會造成時間丟失。

 

2,系統啟動時從RTC獲取時間,這個步驟在rc.sysinit中做:

a,首先從/etc/sysconfig/clock中獲取RTC相關參數UTC/ARC/SRM。UTC為true表示RTC保存的時間是UTC時間,false表示保存的是本地時間。ARC與SRM的含義參考hwclock的manpage,一般false即可;

b,根據上面獲取的內容構造hwclock命令的參數,將時間由RTC讀取到系統時鍾。

*需要說明的一點是hwclock的輸出是本地時間,localtime/utc參數只是用來告訴hwclock命令COMS時區是哪個時區。比如Linux系統的系統時區設置為CST(中國標准時間),COMS時間采用牆上時間,即COMS時區也是CST,這時如果使用--utc參數,會讓hwclock誤以為COMS時區為UTC,所以輸出的時間會自動+8。

 

3,tzset():tzset在程序中用來初始化tzname等全局變量,它首先試圖從環境變量“TZ”中獲取時區,如果TZ環境變量存在,即getenv("TZ")返回值不為NULL,且包含內容有效,則使用TZ值;如果該變量存在但內容無效,比如包含錯誤的時區名字,則使用UTC;如果該變量不存在,即getenv("TZ")返回NULL,則查找系統時區設置文件,一般是/etc/localtime。localtime所指文件的內容格式可參考tzfile(5)。

4,time():返回自00:00:00 UTC, January 1, 1970到現在所經過的秒數,注意,是UTC。

5,ctime()/localtime()/mktime():這類和時區相關的函數內部會調用tzset,但只是第一次調用tzset會做實際初始化,后面的調用都是直接返回。

6,系統關閉時,如執行shutdown/reboot/poweroff/halt等操作后,系統時間會保存到RTC中,這是在halt腳本中完成的,參看/etc/init.d/halt內容。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM