zoukankan      html  css  js  c++  java
  • 关于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 ", daylight ); 
       printf( "timezone = %ld ", timezone ); 
       printf( "tzname[0] = %s ", 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内容。

  • 相关阅读:
    POJ 2018 二分
    873. Length of Longest Fibonacci Subsequence
    847. Shortest Path Visiting All Nodes
    838. Push Dominoes
    813. Largest Sum of Averages
    801. Minimum Swaps To Make Sequences Increasing
    790. Domino and Tromino Tiling
    764. Largest Plus Sign
    Weekly Contest 128
    746. Min Cost Climbing Stairs
  • 原文地址:https://www.cnblogs.com/bibaodi/p/4869007.html
Copyright © 2011-2022 走看看