最近搞ONVIF,在时间接口中有一个时区的字段,需要使用POSIX格式的时区,ONVIF手册要求符合IEEE100.3.1的第8章节,但要注册才能看IEEE标准,我印象中以前下载过,但找不到了。幸好,找到一篇讲POSIX格式时区的文章,终于有点认知了。

一、理解POSIX格式时区

(本节主要根据上述地址的文章进行理解进行描述,不是直接翻译,建议直接看原文。)

Linux系统的环境变量TZ存储了时区信息,包括DST(Daylight Saving Time,日光节约时,又叫夏令时)的开、关,以及UTC(Coordinated Universal Time,世界协调时间)的时间差。系统内部均使用UTC时间,平常我们看到的时间(本地时间),都是基于时区和DST(夏令时)规则来计算得来的。TZ的格式为:

TZ = local_timezone,date/time,date/time

local_timezone是时区名称,其后两个date/time分别表示DST变更时间点(即何时开始,何时结束),date格式为Mm.n.d(注:“M”是字符),其中m范围为1~12,表示1~12月份,如M3表示3月份;n范围为1~5,1表示一个月中第一周,5表示最后一周;d范围为0~6,0表示星期日,6表示星期六。time为hh:mm:ss的格式。

比如:

TZ=CST6CDT,M3.2.0/2:00:00,M11.1.0/2:00:00

这个格式的时区表示:每一年的3月份第二个星期日凌晨2点开始变更为夏令时,11月份第1个星期日凌晨2点结束夏令时,CST6CDT为时区名称,CST表示Central Standard Time,CDT表示 Central Daylight Time,即夏令时,6表示与GMT相差6小时(实际为GMT -06:00,下文将看到)。关于时区名称,第二节再结合实例说讲讲。

夏令时格式可以自定义,但这不属于本文范围了。

查看tzset函数说明(使用命令man tzset),原文如下:

The value of TZ can be one of three formats.  The first format is used when there is  no  day‐
       light saving time in the local timezone:

std offset

The std string specifies the name of the timezone and must be three or more alphabetic charac‐
       ters.  The offset string immediately follows std and specifies the time value to be  added  to
       the  local  time to get Coordinated Universal Time (UTC).  The offset is positive if the local
       timezone is west of the Prime Meridian and negative if it is east.  The hour must be between 0
       and 24, and the minutes and seconds 0 and 59.

这部分说的是没有夏令时的时区格式,即一个名称加上与UTC的时间差值,就是说,当地时间加上时间差就得到UTC时间。如果时间差为正数,则时区位于本初子午线(Prime Meridian)之西(西几区),如果是负数,则时区位于本初子午线之东(东几区),见加粗部分字体。所以CST6CDT是西六区的时区名称。——因为西六区加上6小时,正是UTC时间。而CST-8是东八区,因为东八区减去8小时刚好是UTC时间。

二、实例

时区文件不一定全部是可读的ascii字符,大部分是乱码,但还是可以用cat命令查看得到有用信息,在一台PC上看看CST6CDT的实际情况:
root@latelee:~/test# cat /usr/share/zoneinfo/CST6CDT 
CST6CDT,M3.2.0,M11.1.0

注意,实际结果和上面举例不同之处是time,这表示是0点就进行。再看看用date命令得到的“时区名称”和时区偏移:

root@latelee:~/test# date +%Z
CST

root@latelee:~/test#date +%z
-0600

可以看到,名称是“CST”,而不是“CST6CDT”,,时间比GMT晚6小时,即西六区,个人认为,第1节提到的名称,是很多有意义的字段组合而成。

再看一个太平洋时区的值:
root@latelee:~/test# cat /usr/share/zoneinfo/PST8PDT
PST8PDT,M3.2.0,M11.1.0
除了时区名称不同,夏令时与CST6CDT相同。
类似的还有EST5EDT,实际,这几个名称上都是“X-ST-时区-X-DT”这个形式的。

回头看看北京时间(一般有北京、重庆、上海等地名,随便一个即可)的东八区:
root@latelee:~/test# cat /usr/share/zoneinfo/Asia/Shanghai
CST-8
root@latelee:~/test# date +%z
+0800
可以看到,我们国家现在没有实行夏令时(历史上有短暂执行过)。我们再看看GMT-8的时区文件:
root@latelee:~/test# cat /usr/share/zoneinfo/Etc/GMT-8
TZif2pMT-8TZif2pMT-8
<GMT-8>-8
注意,设置东八区的时区,要使用GMT-8,而不是GMT+8,对于正负数,第一节是比较权威的解释,我们大概还可以这样认为:负数表示比GMT(注:本文不区别GMT和UTC)时间提前多少,正数表示比GMT时间落后多少。比如GMT-8,就是这个时区比GMT早了8个小时,GMT+8,就是这个时区比GMT晚了8个小时。比如现在写这篇文章时,我准备吃今天最后一餐饭了(没人请吃夜宵),伦敦那边才准备吃今天的午饭。
细心的读者会注意到,第1节出现了CST,而东八区时间里也有CST,我查了一下资料,CST表示下面4个时区:
Central Standard Time (USA) GMT-6:00
Central Standard Time (Australia) GMT+9:30
China Standard Time GMT+8:00
Cuba Standard Time GMT-5:00

注:CST还是李迟个人主页“迟思堂工作室”的拼音首字母,也是李迟所学专业“计算机科学与技术”英文缩写。

三、其它

下面是使用zdump命令查看Shanghai时区文件的信息:

root@latelee:~/test# zdump -v Asia/Shanghai
Asia/Shanghai  Fri Dec 13 20:45:52 1901 UT = Sat Dec 14 04:51:49 1901 LMT isdst=0 gmtoff=29157
Asia/Shanghai  Sat Dec 14 20:45:52 1901 UT = Sun Dec 15 04:51:49 1901 LMT isdst=0 gmtoff=29157
Asia/Shanghai  Sat Dec 31 15:54:02 1927 UT = Sat Dec 31 23:59:59 1927 LMT isdst=0 gmtoff=29157
........

暂时未研究这个。

当天的PS:

本来想再写一下RTC方面的东西,但我印象中有写过,我搜索了一下,果然有,但是,那是2年多以前的事了:

嵌入式设备ntp同步时间的一些笔记--迟思堂工作室

四、参考资料

POSIX格式的时区介绍:http://www.ibm.com/developerworks/aix/library/au-aix-posix/index.html

GNU关于TZ变量的介绍:http://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html

世界时区介绍、简写等:http://www.timeanddate.com/time/zones/

五、posix 1003.1 section8.3定义的Timezone

2016.2.25晚:

上文使用GMT**的形式,一来是因为很多嵌入式设备的存储空间十分有限,对根文件系统会做比较大的裁减,对于时区这一方面,一般我只保持Etc/GMT**文件;二来poisix标准只约定了TZ环境变量的形式“stdoffset”,标准只提及std是不少于3字节,不多于TZNAME_MAX字节的指定的时区名称。但并没有规定一定能用“GMT”或一定不能用“GMT”,只是人们认知中的“GMT+8”为GMT时区加上8小时,即东八区。但是,“offset”偏移的“+”、“-”一定是posix规定的,“-”表示本初子午线之东,“+”表示本初子午线之西。在onvif测试工具中,如果设备返回的时区名称为“CST+8”会比实际时间少16个小时,只有返回“CST-8”才能真正反映实际时间。——把“CST”改为任意其它值,也能得到同样的结果。

从一般理解层面考虑,还是不建议使用“GMT-8”来表示东八区时间。

下面是我注册opengroup网站后,查看posix标准文档8.3章节TZ环境变量的描述文字:

TZ

This variable shall represent timezone information. The contents of the environment variable namedTZ shall be used by the ctime(), localtime(), strftime(), mktime(), [TSF]ctime_r(), and localtime_r() functions, and by various utilities, to override the default timezone. The value ofTZ has one of the two forms (spaces inserted for clarity):

:characters

or:

std offset dst offset, rule

If TZ is of the first format (that is, if the first character is a colon), the characters following the colon are handled in an implementation-defined manner.

The expanded format (for all TZ s whose value does not have a colon as the first character) is as follows:

stdoffset[dst[offset][,start[/time],end[/time]]]

Where:

std and dst
Indicate no less than three, nor more than {TZNAME_MAX}, bytes that are the designation for the standard (std) or the alternative ( dst -such as Daylight Savings Time) timezone. Onlystd is required; if dst is missing, then the alternative time does not apply in this locale.

Each of these fields may occur in either of two formats quoted or unquoted:

  • In the quoted form, the first character shall be the less-than ( '<' ) character and the last character shall be the greater-than ('>' ) character. All characters between these quoting characters shall be alphanumeric characters from the portable character set in the current locale, the plus-sign ('+' ) character, or the minus-sign ( '-' ) character. The std anddst fields in this case shall not include the quoting characters.

  • In the unquoted form, all characters in these fields shall be alphabetic characters from the portable character set in the current locale.

The interpretation of these fields is unspecified if either field is less than three bytes (except for the case whendst is missing), more than {TZNAME_MAX} bytes, or if they contain characters other than those specified.

offset
Indicates the value added to the local time to arrive at Coordinated Universal Time. Theoffset has the form:

hh[:mm[:ss]]

The minutes ( mm) and seconds ( ss) are optional. The hour (hh) shall be required and may be a single digit. The offset followingstd shall be required. If no offset follows dst, the alternative time is assumed to be one hour ahead of standard time. One or more digits may be used; the value is always interpreted as a decimal number. The hour shall be between zero and 24, and the minutes (and seconds)-if present-between zero and 59. The result of using values outside of this range is unspecified. If preceded by a'-', the timezone shall be east of the Prime Meridian; otherwise, it shall be west (which may be indicated by an optional preceding'+' ).

rule
Indicates when to change to and back from the alternative time. The rule has the form:

date[/time],date[/time]

where the first date describes when the change from standard to alternative time occurs and the seconddate describes when the change back happens. Each time field describes when, in current local time, the change to the other time is made.

The format of date is one of the following:

Jn
The Julian day n (1 <= n <= 365). Leap days shall not be counted. That is, in all years-including leap years-February 28 is day 59 and March 1 is day 60. It is impossible to refer explicitly to the occasional February 29.
n
The zero-based Julian day (0 <= n <= 365). Leap days shall be counted, and it is possible to refer to February 29.
Mm.n.d
The d'th day (0 <= d <= 6) of week n of month m of the year (1 <= n <= 5, 1 <= m <= 12, where week 5 means "the lastd day in month m" which may occur in either the fourth or the fifth week). Week 1 is the first week in which thed'th day occurs. Day zero is Sunday.

The time has the same format as offset except that no leading sign ('-' or '+' ) is allowed. The default, if time is not given, shall be 02:00:00.

李迟 2016.1.18 周一 晚饭前

linux下时区的一些认识相关推荐

  1. linux下时区设置和时间同步

    一.时区设置: [root@master ~]# tzselect Please identify a location so that time zone rules can be set corr ...

  2. linux 时区文件的规则,linux下时区的一些认识

    最近搞ONVIF,在时间接口中有一个时区的字段,需要使用POSIX格式的时区,ONVIF手册要求符合IEEE100.3.1的第8章节,但要注册才能看IEEE标准,我印象中以前下载过,但找不到了.幸好, ...

  3. linux new date差8个小时,new date() 在Linux下引起的时间差问题

    java工程部署到Linux时,使用new date()获取的时间出现时间差,通过查阅资料,发现有可能是服务器时间设置问题,JVM问题,jdk问题: 1.服务器时间设置问题: 正确的时间显示 有 CS ...

  4. Linux下修改时间时区

    Linux下修改时间时区 Linux时钟分为系统时钟(System Clock)和硬件(Real Time Clock,简称RTC)时钟.系统时钟是指当前Linux Kernel中的时钟,而硬件时钟则 ...

  5. linux时间8个小时差,Linux下Chrome浏览器时间不对,时区不对

    deepin linux下,在chrome谷歌浏览器中,时区差8小时. 经过测试,把操作系统时区设置为上海(GMT)就可以了,操作系统默认可能是本地的时间和地点,虽然也是北京时间,但是可能导致chro ...

  6. Linux下查看/修改系统时区、时间

    一.查看和修改Linux的时区 1. 查看当前时区 命令 : "date -R" 2. 修改设置Linux服务器时区 方法 A 命令 : "tzselect" ...

  7. 转载:Linux下查看/修改系统时区、时间

    一.查看和修改Linux的时区 1. 查看当前时区 命令 : "date -R" 2. 修改设置Linux服务器时区 方法 A 命令 : "tzselect" ...

  8. Linux下程序时间消耗监控与统计

    良好的计时器可帮助程序开发人员确定程序的性能瓶颈,或对不同算法进行性能比较.但要精确测量程序的运行时间并不容易,因为进程切换.中断.共享的多用户.网络流量.高速缓存访问及转移预测等因素都会对程序计时产 ...

  9. linux系统编程需要什么,若想成为一名Linux下编程高手,必须能对各种系统调用有透彻的了解...

    原标题:若想成为一名Linux下编程高手,必须能对各种系统调用有透彻的了解 什么是系统调用? Linux内核中设置了一组用于实现各种系统功能的子程序,称为系统调用.用户可以通过系统调用命令在自己的应用 ...

最新文章

  1. 2022-2028年中国自主可控行业深度调研及投资前景预测报告(全卷)
  2. IPV6的设置问题!
  3. mysql添加自团_Mysql入门基础 数据库创建篇
  4. Vue(五)Vue规范
  5. 【基础操作】线性基详解
  6. Redux有何优点?
  7. 位图索引,数据库索引浅浅的学习
  8. vue导入swiper_vue项目中导入swiper插件的方法
  9. php上传图片管理系统,php 登录操作的文件上传管理系统
  10. Bootstrap 排版引用
  11. Dubbo实现分布式架构原理
  12. MATLAB(1)MATLAB工作环境
  13. 华为云服务器建站教程
  14. Java学习笔记(24)——正则表达式
  15. 关于sigmoid函数几点介绍
  16. 23.本地服务Services
  17. 物流快递系统程序设计
  18. FPGA秋招面试手撕代码20+
  19. 小杜机器人线下店_小度机器人怎么领养?小度机器人功能最新一览
  20. 各种计算机语言的经典书籍(C/C++/Java/C#/VC/VB等)

热门文章

  1. 苹果明年有望推出15英寸版MacBook Air
  2. 华为nova9 SE官网上架:华为首款1亿像素手机
  3. 当初怼刘海屏最狠的三星,为什么又用了回来?
  4. Meta:绝对没有威胁要离开欧洲市场
  5. 京东物流:将连续第10年春节也送货 为坚守岗位一线员工补贴近4亿元
  6. 荣耀X20 SE评测:6400万高清美拍 2000元以下真香现场
  7. 华为nova 8i渲染图曝光:背部设计神似Mate30
  8. 维信诺通过9.5亿元应收款保理业务提案
  9. 特斯拉接连出闹剧?一次比一次渗人...
  10. 苹果iPhone 12系列智能手机支持北斗卫星导航定位