国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Linux上系統(tǒng)時間函數(shù)、DST等相關有關問題總結
http://www.reader8.cn/jiaocheng/20120910/1995886.html
2012
Linux下系統(tǒng)時間函數(shù)、DST等相關問題總結1. 內(nèi)核中時間的基本類型:在Linux內(nèi)核中,常見的時間類型有以下兩種

Linux下系統(tǒng)時間函數(shù)、DST等相關問題總結

1. 內(nèi)核中時間的基本類型:

           在Linux內(nèi)核中,常見的時間類型有以下兩種:系統(tǒng)時間(system time)和實時時間(real time),其實,方便理解,可以將二者分別認為是相對時間和絕對時間,同時它們分別對應于內(nèi)核中的兩個全局變量值:jiffies和xtime。

           xtime: xtime值是從cmos電路中取得的時間,一般是從某個歷史時刻(1970年1月1日0時0分)開始到現(xiàn)在的時間,其實也就是我們操作系統(tǒng)上面所顯示的時間,它的精度是微秒。

           jiffies:jiffies是記錄從電腦開機到現(xiàn)在總共的時鐘中斷次數(shù)(拍數(shù)),它的值取決于系統(tǒng)的頻率,單位是HZ,其倒數(shù)即表示一秒鐘中斷所產(chǎn)生的次數(shù),在Linux 2.5內(nèi)核版本之后將HZ從100提高到1000MHZ,它的精度也就是10毫秒。

           根據(jù)對上面兩個全局變量值的介紹,大提升應該了解到Linux系統(tǒng)中系統(tǒng)時間與實時時間之間的區(qū)別,前者表示的是從電腦開機到現(xiàn)在的時間,可以通過全局變量jiffies值換算而來;而實時時間則是指我們?nèi)粘I钪械娜掌跁r間,它跟UTC有著密切關系,這些將在后面章節(jié)做介紹。

 

2. Linux time API中常見的時間結構:

(1)time_t:它是一個長整型數(shù)據(jù),用來表示從1970年之后到現(xiàn)在的秒數(shù)。一般通過time函數(shù)獲取。

(2)timeval結構:通過gettimeofday函數(shù)獲取。

            struct timeval

            {

              long tv_sec; /* seconds */

               long tv_usec; /* microseconds */

             };

(3)timezone結構:通過gettimeofday函數(shù)獲取。

            struct timezone

            {

                      int tz_minuteswest; /* 和Greewich時間差了多少分鐘*/

                      int tz_dsttime; /*DST types*/

            };

           【引申】常見的DST類型如下:

            #define   DST_NONE      0    /* not on dst */

            #define   DST_USA        1    /* USA style dst */

            #define   DST_AUST       2   /* Australian style dst */

            #define   DST_WET        3    /* Western European dst */

            #define   DST_MET        4    /* Middle European dst */

            #define   DST_EET         5    /* Eastern European dst */

            #define   DST_CAN        6    /* Canada */

(4)timespec結構:通過clock_gettime函數(shù)獲取。

            struct timespec {

            time_t tv_sec;         /* seconds */

             long   tv_nsec;        /* nanoseconds */

            };

(5)tm結構:通常由gmtime, localtime, mktime等函數(shù)返回。

           struct tm {

                  /*

               * the number of seconds after the minute,normally in the range

               * 0 to 59, but can be up to 60 to allow forleap seconds

               */

                int tm_sec;

                /* the number of minutes after the hour, in the range 0 to 59*/

                int tm_min;

                 /* the number of hours past midnight, in the range 0 to 23 */

                 int tm_hour;

                 /* the day of the month, in the range 1 to 31*/

                 int tm_mday;

                 /* the number of months since January, in the range 0 to 11 */

                 int tm_mon;

                 /* thenumber of years since 1900 */

                long tm_year;

                /* the number of days since Sunday, in the range 0 to 6 */

               int tm_wday;

               /* the number of days since January 1, in the range 0 to 365 */

              int tm_yday;

           };

 

3. 常見的時間系統(tǒng)函數(shù):

(1) time:   #include <time.h>

      time_t time(time_t *t)

      若函數(shù)的參數(shù)為NULL,則返回從1970年1月1日0時0分0秒到現(xiàn)在(系統(tǒng)時間)所經(jīng)過的秒;若參數(shù)非空,則將返回的值存在由指針t所指代的內(nèi)存中。

(2) gettimeofday: #include <sys/time.h>

      int gettimeofday(structtimeval *tv ,struct timezone *tz )

      此函數(shù)可以獲取兩方面的時間信息,一個是可以獲取到從1970年1月1日0時0分0秒到現(xiàn)在(系統(tǒng)時間)所經(jīng)過的微秒,精度相比time函數(shù)精度有所提升;另外還可以獲取到系統(tǒng)的時區(qū)信息。

【說明】

◆     gettimeofday函數(shù)成功返回0;否則返回-1,錯誤存儲在errno中。

◆     tz_minuteswest值的確定問題:它表示的是與GTM之間相差的分鐘數(shù),其值應該為GMT(GMT +0)減去本地

         時區(qū)對應的時間所得到的值,以EDT(GMT -4)為例,其值為240分鐘。

◆     在實際開發(fā)中,gettimeofday中的tz參數(shù)實際很少使用,因為各種原因,一直未能實現(xiàn)(所獲取出來的值恒為

         0),因此,通常將此處直接寫成NULL。

◆     對于gettimeofday函數(shù)的效率以及內(nèi)部實現(xiàn)(系統(tǒng)調(diào)用實現(xiàn)),可參考

           http://blog.csdn.net/russell_tao/article/details/7185588中的闡述。

◆     與gettimeofday函數(shù)相對應的是settimeofday,它可以設置實時時間RTC。但之前必須要具有root權限。

(3) gmtime,localtime and mktime:

           struct tm*gmtime(const time_t *timep)

           struct tm *localtime(const time_t *timep)

           time_tmktime(struct tm*tm)

           以上三個函數(shù)實現(xiàn)了time_t與tm結構的互換。前兩者將time_t結構轉(zhuǎn)換成tm結構,mktime則正好相反。

【說明】gmtime與localtime之間的區(qū)別:

           二者均可以將time_t結構的時間值轉(zhuǎn)化成真實世界所使用的日期時間表示方法(tm結構),但是,前者返回的時間值未作時區(qū)的轉(zhuǎn)換,即返回的是UTC時間;而localtime函數(shù)則返回的經(jīng)過了時區(qū)轉(zhuǎn)換的時間值,所獲取到的值才是本地的真實時間。例如,在Linux系統(tǒng)中運行date命令,它顯示的是經(jīng)過時區(qū)轉(zhuǎn)換之后的時間值(通過localtime獲?。?,而若運行“date-u”則能顯示未經(jīng)過時區(qū)轉(zhuǎn)換的UTC時間(通過gmtime獲?。?。

 

(3) strftime:  #include <time.h>

     size_tstrftime (char *s,sizetsize, const char *format,const struct tm *brokentime)

     此函數(shù)的功能是將由brokentime指針所指的時間按照format指針所指的格式輸出到由s指針所指向的存儲空間中,其中size是指存儲空間的最大值。若返回0,則表明出現(xiàn)錯誤,所寫進存儲空間的結果是未定義的,若為真,則返回的是寫進存儲空間的字符數(shù)。

 

(4) clock_gettime: #include <time.h>

      intclock_gettime(clockid_tclk_id,struct timespec *tp);

      此函數(shù)的功能是用來獲取不同類型計時時鐘的時間,其類型由clockid_t指定,常見的有:

       CLOCK_REALTIME(與實時時間對應)

       CLOCK_MONOTONIC(與系統(tǒng)時間對應)

【說明】

◆     clock_gettime函數(shù)能將所獲得的時間值精確到納秒級別;

◆     函數(shù)運行成功則返回0,否則返回-1,并將錯誤存在errno中;

◆     除上面的兩個時鐘類型之外,還有以下兩種類型:

        CLOCK_PROCESS_CPUTIME_ID和CLOCK_THREAD_CPUTIME_ID

        但是這兩種時鐘類型一般出現(xiàn)在多處理機系統(tǒng)(SMP)中,值得注意的是,在老版本的Linux系統(tǒng)中可能會出現(xiàn)CPU時間之間不一致的現(xiàn)象,這是因為不同的CPU之間沒有保證時間一致性措施,導致CPU時間之間出現(xiàn)偏移量,在2.6.18版本之后解決了這方面的問題,使得系統(tǒng)啟動后不同的CPU之間具有相同的時間基準點。

◆CLOCK_REALTIME時間可以通過settime或者settimeofday函數(shù)進行修改,或者通過NTP周期性 地糾正,此時需要用到adjtimex函數(shù);CLOCK_MONOTONIC時間則不能通過settime或者settimeofday函數(shù)進行修改,但是同樣可以通過NTP進行調(diào)整,此時同樣需要用到adjtimex函數(shù)。

對比兩種時鐘類型,若要在實際開發(fā)中要統(tǒng)計某個事件的時間,則最好是使用CLOCK_MONOTONIC,因為CLOCK_REALTIME被影響的因素太多,如手動修改,時區(qū)變化等等。

 

4. DST以及相關的系統(tǒng)函數(shù):

(1)UTC、GMT與DST

           目前世界上常見的計時方式主要有:太陽時(MT)和原子時。GMT(格林尼治時間)的正午是指當太陽橫穿格林尼治子午線時的時間,由于地球的自轉(zhuǎn)呈現(xiàn)不規(guī)則性,并且正在緩慢減速,因此格林威治時間目前已經(jīng)不再作為標準時間使用,取而代之的是協(xié)調(diào)時間時(UTC),它是由原子鐘提供,它是基于標準的GMT提供的準確時間,若在不需要精確到秒的前提下,通常也將GMT與UTC視作等同

           DST(daylight saving time)也稱為夏令時,它是以節(jié)約能源為目的而人為規(guī)定的一種制度,它規(guī)定某段時間作為夏令時間,并在標準時間的基礎上提前多長時間(通常是一個小時),同時DST還規(guī)定了規(guī)定生效的起始時間和末尾時間,詳細規(guī)則會在tzset函數(shù)中介紹,值得注意的是目前只是部分國家實施了夏令時制度。

           標準時間是相對于UTC/GMT時間而言的,它在UTC/GMT之上增加了時區(qū)信息,比如中國標準時間是GMT+8,即在UTC時間上增加8個小時。   

(2) 系統(tǒng)時間、標準時間以及UTC時間之間的關系:

           這節(jié)主要探討在具體項目實現(xiàn)過程中,如何處理系統(tǒng)時間、標準時間以及UTC時間之間的關系,其中系統(tǒng)時間可以通過前面的系統(tǒng)函數(shù)獲取到,它可能正處于夏令時間區(qū)域,下面這個圖可以清晰地闡述三者之間的關系:

             我們以localtime函數(shù)獲取到本地系統(tǒng)時間為例,演示如何將其轉(zhuǎn)換成UTC時間,前面已經(jīng)說過,localtime所獲取到的時間已經(jīng)包含了時區(qū)信息,但是之前我們必須要確認目前的這個時間是否處于夏令時區(qū)域之內(nèi),若是,則還需要經(jīng)過A階段(去掉DST偏移量,通常是一個小時),若不是,只需要經(jīng)歷第二個階段B,即去時區(qū),最后轉(zhuǎn)化成UTC,當然這兩個階段并沒有嚴格的先后順序。反過來,在具體實現(xiàn)中,還經(jīng)常出現(xiàn)將UTC時間轉(zhuǎn)化成本地時間的情況,比如NTP就是基于這樣的原理,它從NTP server端獲取統(tǒng)一的UTC時間,然后需要經(jīng)過C(加時區(qū))和D(加DST,如果存在或正好處于夏令時區(qū)域范圍之內(nèi)的話)兩個階段將其轉(zhuǎn)化成本地系統(tǒng)時間。

           下面主要闡述第一種情況(本地系統(tǒng)時間——>UTC)是如何具體實現(xiàn)的。當然前提是我們要知道目前所在的時區(qū),這是一切的根本。在此之前,值得說明的是,一般來講,時區(qū)是一個固定的信息,難以想象一個國家或地區(qū)去改變時區(qū)所帶來的后果,但是DST因為是人為規(guī)定的,因此可能存在著修改的情況,基于這個事實,在具體實現(xiàn)中,時區(qū)信息可以存儲在本地,而DST信息既可以靜態(tài)存儲在本地,也可以通過相關的server動態(tài)獲取到。我們以靜態(tài)存儲的方式為例來講解具體是如何實現(xiàn)去時區(qū),去DST。

           下面這個結構體存儲了跟時區(qū)相關的位移量(offset)以及是否存在DST等信息,根據(jù)所在的時區(qū)信息,很容易找到系統(tǒng)時間與UTC時間之間的時區(qū)偏移,另外根據(jù)rule是否為-1來確定此時區(qū)是否實施了夏令時,若為-1,表明這個時區(qū)地已經(jīng)實現(xiàn)了夏令時,則還需要經(jīng)過去DST階段,否則只需要經(jīng)過去時區(qū)就可以得到UTC時間。

        struct zone zones[N_ZONES] = {

        /* offset rules */

        { -43200, -1 }, /* (GMT-12:00)International Date Line West */

        { -39600, -1 }, /* (GMT-11:00) Midway Island,Samoa */

        { -36000, -1 }, /* (GMT-10:00) Hawaii */

        { -32400,  0 }, /* (GMT-09:00) Alaska */

        { -28800,  0 }, /* (GMT-08:00) Pacific Time, Tijuana */

        { -25200, -1 }, /* (GMT-07:00) Arizona, Mazatlan*/

        { -25200, 13 }, /* (GMT-07:00) Chihuahua, La Paz*/

        { -25200,  0 }, /* (GMT-07:00) Mountain Time */

        { -21600,  0 }, /* (GMT-06:00) Central America */

        { -21600,  0 }, /* (GMT-06:00) Central Time */

        { -21600, 13 }, /* (GMT-06:00) Guadalajara, MexicoCity, Monterrey*/

        { -21600, -1 }, /* (GMT-06:00) Saskatchewan */

        { -18000, -1 }, /* (GMT-05:00) Bogota, Lima, Quito */

        { -18000,  0 }, /* (GMT-05:00) Eastern Time */

        { -18000, -1 }, /* (GMT-05:00) Indiana */

        { -14400,  0 }, /* (GMT-04:00) Atlantic Time */

        {-14400, -1 }, /* (GMT-04:00) Caracas, La Paz */

        { -14400,  2 }, /* (GMT-04:00) Santiago */

        { -12600,  0 }, /* (GMT-03:30) Newfoundland */

        { -10800, 14 }, /* (GMT-03:00) Brasilia */

        { -10800, -1 }, /* (GMT-03:00) Buenos Aires, Georgetown*/

        { -10800, -1 }, /* (GMT-03:00) Greenland */

        { -7200, -1 }, /* (GMT-02:00) Mid-Atlantic */

        { -3600,  1 }, /* (GMT-01:00) Azores */

        { -3600, -1 }, /* (GMT-01:00) Cape Verde Is. */

        {     0, -1 }, /* (GMT) Casablanca, Monrovia */

        {     0,  1 }, /* (GMT) Greenwich MeanTime: Dublin, Edinburgh,Lisbon, London*/

        {  3600,  1 }, /* (GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna

        {  3600,  1 }, /* (GMT+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague */

        {  3600,  1 }, /* (GMT+01:00) Brussels, Copenhagen, Madrid, Paris*/

        {  3600,  1 }, /* (GMT+01:00) Sarajevo, Skopje, Warsaw, Zagreb*/

        {  3600, -1 }, /* (GMT+01:00) West Central Africa*/

        {  7200,  1 }, /* (GMT+02:00) Athens, Istanbul, Minsk */

        {  7200,  1 }, /* (GMT+02:00) Bucharest */

        {  7200,  4 }, /* (GMT+02:00) Cairo */

        {  7200, -1 }, /* (GMT+02:00) Harare, Pretoria */

        {  7200,  1 }, /* (GMT+02:00) Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius */

        {  7200,  5 }, /* (GMT+02:00) Jerusalem */

        { 10800,  6 }, /* (GMT+03:00) Baghdad */

        { 10800, -1 }, /* (GMT+03:00) Kuwait,Riyadh */

        { 10800,  7 }, /* (GMT+03:00) Moscow, St. Petersburg, Volgograd */

        { 10800, -1 }, /* (GMT+03:00) Nairobi*/

        { 12600,  8 }, /* (GMT+03:30) Tehran */

        { 14400, -1 }, /* (GMT+04:00) Abu Dhabi, Muscat */

        { 14400,  9 }, /* (GMT+04:00) Baku, Tbilisi, Yerevan */

        { 16200, -1 }, /* (GMT+04:30) Kabul*/

        { 18000,  7 }, /* (GMT+05:00)Ekaterinburg */

        { 18000, -1 }, /* (GMT+05:00) Islamabad, Karachi, Tashkent*/

        { 19800, -1 }, /* (GMT+05:30) Chennai, Kolkata, Mumbai, New Delhi */

        { 20700, -1 }, /* (GMT+05:45) Kathmandu*/

        { 21600, 12 }, /* (GMT+06:00) Almaty, Novosibirsk */

        { 21600, -1 }, /* (GMT+06:00) Astana, Dhaka*/

        { 21600, -1 }, /* (GMT+06:00) Sri Jayawardenepura */

        {  23400, -1 }, /* (GMT+06:30) Rangoon */

        { 25200, -1 }, /* (GMT+07:00) Bangkok, Hanoi, Jakarta*/

        { 25200,  7 }, /* (GMT+07:00) Krasnoyarsk */

        { 28800, -1 }, /* (GMT+08:00) Beijing,Chongquing, Hong Kong, Urumqi*/

        { 28800, -1 }, /* (GMT+08:00) Irkutsk,Ulaan Bataar */

        { 28800, -1 }, /* (GMT+08:00) Kuala Lumpur, Singapore*/

        { 28800, -1 }, /* (GMT+08:00) Perth*/

        { 28800, -1 }, /* (GMT+08:00) Taipei*/

        { 32400, -1 }, /* (GMT+09:00) Osaka, Sapporo, Tokyo*/

        { 32400, -1 }, /* (GMT+09:00) Seoul*/

        { 32400,  7 }, /* (GMT+09:00) Yakutsk */

        { 34200,  3 }, /* (GMT+09:30) Adelaide */

        { 34200, -1 }, /* (GMT+09:30) Darwin*/

        { 36000, -1 }, /* (GMT+10:00) Brisbane*/

        { 36000,  3 }, /* (GMT+10:00) Canberra, Melbourne, Sydney*/

        { 36000, -1 }, /* (GMT+10:00) Guam, Port Moresby */

        { 36000, 10 }, /* (GMT+10:00) Hobart*/

        { 36000,  7 }, /* (GMT+10:00) Vladivostok */

        { 39600, -1 }, /* (GMT+11:00) Magadan */

        { 39600,  7 }, /* (GMT+11:00)Solomon Is., New Caledonia*/

        { 43200, 11 }, /* (GMT+12:00) Auckland, Wellington */

        { 43200, -1 }, /* (GMT+12:00) Fiji,Kamchatka, Marshall Is. */

        { 43200, -1 }, /* (GMT+12:00) NZ */

};        

           那么又如何去掉DST,即找到系統(tǒng)時間與標準時間之間的DST偏移量呢?在此之前需要了解到DST的規(guī)則問題,如規(guī)則格式、規(guī)則數(shù)據(jù)等等。

           DST規(guī)則規(guī)定了實施夏令時的起始時間以及結束時間,如澳大利亞的是:從4月的第一個星期天的凌晨3點到10月的第一個星期天的凌晨2點,全世界DST可參考www.worldtimezone.com/daylight.html。下面主要闡述如何判斷目前的時間是否包含有夏令時。

rpytime(rule1,year) < (gm_time + zone->z_gmtoff))< rpytime(rule2,year)

      上面的式子中gm_time是本地系統(tǒng)時間(注意是通過localtime獲取,沒有加入時區(qū),單位為秒),z_gmtoff是指制定時區(qū)的偏移量,這樣式子中間代表就是標準時間;式子中rule1,rule2分別對應于DST規(guī)則中的兩個界點,并利用rpytime函數(shù)計算出從1970年以來的時間總長(以秒為單位),若上面的式子成立,表明存在DST,那是因為DST使得在標準時間之上提前了1小時。



本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
UTC和GMT時間
世界時鐘 :: 洛杉磯 (Los Angeles), 美國 (United States)
不同時區(qū)之間,時間的轉(zhuǎn)換?
徹底弄懂GMT、UTC、時區(qū)和夏令時
安卓國際化開發(fā)中的時區(qū)問題之
卡西歐電子手表怎么調(diào)日期及時間?卡西歐說明書詳解調(diào)校
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服