Linux在C语言下的时区设置与修改(三)

前面一直在讲tzset似乎只在初始化的时候才生效,当tzset调用多次时没用。

今天稍微深入的查找了glibc中的tzset的实现,发现其实不是这么回事,其真正的实现是每次都会去解析的。为什么之前会误认为tzset无效,是由于本地进程的环境变量和全局环境变量导致的。

具体的tzset的实现是tzset_internal,在这个函数中,其基本思路是:

1、首先检查环境变量中的TZ环境变量是否存在、有效

2、根据TZ环境变量获取指定的时区文件的路径和文件名

3、保存当前使用的这个环境变量TZ

4、尝试去读取数据文件,这里的数据文件即时区文件tzfile,注意其数据是按固定格式来的。

5、在上述的step4中,会根据tzfile文件,去刷新timezone和daylight的。确定解析tzfile文件成功之后,还会将一个名为__use_tzfile的变量置为1

6、根据上述解析的结果,根据 __use_tzfile是否为1来确定是否需要继续,若没有解析tzfile成功,则判断tz是否有效,无效则刷新tzname的值,认为默认使用UTC时间。

7、若上述操作过程中,发现tzfile解析失效,而tz是有效的,则需要最后去解析tz环境变量,这种情况下tz环境变量是是有时间的,其时间是用来设置夏冬令时的,即daylight saving time的。

上述解析的过程中,可以看到其实也是与man手册的说明是一致的。

手册中,已经明确说明了TZ环境变量的三种格式

(1)在本地时区中没有夏冬令时则可使用如下格式:std offset

std表示的时区的名字,是三个字母 表示的。而offset字符串则表示需要加上(或者减去)多少时间才能恢复成UTC时间,小时是0~24,分钟是0~59

(2)第二种格式是用作夏冬令时的,其格式类型是:std offset  dst [offset].start[/time].end[/time ]

注意在上述的格式中是没有空格的。初始的std和offset指明的是标准时区。dst和offset指明的是相对应的夏冬令时时区的时区名称和偏移。如果offset被忽略掉了他默认是标准时间的前一个小时。

start字段标明了夏冬令时开始有效的时刻,而end字段则表明了何时将这种修改恢复成标准时间。

这些字段可能有如下两种格式:

Jn 标记的是Julian天用n表示1~365。2月29不会计入天数,即使是在闰年

n   标明的是Julian天用n表示0~365。在闰年中2月29会计入天数。

Mm.w.d 指明的是m(1~12)月中的第w(1~5)个星期的第d(0~6)天。0天表示是星期天

time字段表明的是何时本地时间开始生效更改为另一个时间。如果忽略没有了的话,则默认是02:00:00

例如标准的新西兰时间是NZST,是UTC之前的12个小时,而夏冬令时时间是NZDT,UTC时间之前的13个小时,生效间隔是从十月的第一个星期天,到三月的地三个星期天,而这个修改时间发生在默认的02:00:00

(3)第三种格式,用来给定读取的时区文件的文件信息:       :[filespec]

如果上述的文件描述信息filespec被忽略掉的话,读取时区信息的文件将是系统时区目录下的 localtime文件,而这个目录现在一般是/usr/share/zoneinfo

.其文件格式是tzfile格式。filespec不会以/开头的,而且文件描述信息是以系统时区目录为相对路径的,例如,仍然以新西兰举例:

TZ=“:Pacific/Auckland”

现在了解了TZ环境变量的设置,以及tzset文件的实现原理。那么为什么之前利用export来更改TZ环境变量,然后调用tzset刷新时区信息无效呢?

(实际运行glibc中的tzset的测试例子却是有效的!!!!!)

原因在于:

export导出的环境变量,是session即会话的环境变量。

而putenv导出的环境变量,却是以进程为对象的环境变量。

根据上述例子测试,写了shell脚本(export调用导出)和程序(putenv)对比,发现结果果然是两者并不相互干扰,即使两个环境变量名是一样的!!!

结论是:

1、如果要设置时区,根据glibc的实现来看,最好还是用时区文件更改,或者建立链接到localtime的时区文件的方法,否则断电后之前修改肯定会丢失!

2、tzset的调用刷新来获取timezone实际上有效的,而且为了防止其他程序更改时区,如果所运行进程是时区敏感的,则务必要进行不间断的刷新才行。

3、注意环境变量TZ对时区信息的干扰,环境变量可以指定时区,也可以是指定时区文件。

时间: 2024-12-20 19:25:45

Linux在C语言下的时区设置与修改(三)的相关文章

PowerShell 运维菜鸟系列-03-设置-所有用户-OWA-时区-语言-跳过-时区设置)

项目问题: 新用户登录邮箱的OWA的时候,总是要去设置时区,如果是测试,无所谓. 如果是生产,你有几千人的企业,这样肯定是不行的. 解决方法: 以下解决方法是一个学生提供,我一直不在意,因为我不管企业的IT,但这对各学生有用,我收集整理在此系列 中. 1. 查用户 2. 通过Get-MailboxRegionalConfiguration查询 Get-MailboxRegionalConfiguration -Identity SFBDemo01 3. 通过Set-MailboxRegional

下拉选项设置数据的三种方式介绍

度量快速开发平台中,在智能窗体上拖入下拉选择,可以实现很多功能.比如制作查询条件,选择数据等. 方法1:直接在下拉选择右边属性中设置数据. 使用效果: 该方法设置简答,对于那种是固定数据的设置,可以采用这样的效果实现.下拉选项1.Value   与 下拉选项1.SelectedText 获取的值都一样. 方法2:用下拉选项的SetItems方法实现 下拉选项1.SetItems("A,B,C,D",false) 效果与方法一一样,这个方法可以动态的来设置数据,比如根据不同的条件设置不同

linux下的时间及时区设置

一.时间设置及同步 1修改系统时间 #date -s 06/18/14 #date -s 14:20:50 2命令查看.设置硬件时间 #hwclock  --show 或者clock  --show #设置硬件时间 hwclock --set --date="06/18/14 14:55" 或者# clock --set --date="06/18/14 14:55" 3同步系统及硬件时钟 # hwclock --hctosys 或者 # clock --hctos

linux时间时区设置修改及时间同步

linux时间时区设置修改及时间同步一.时区显示时区date --help 获取帮助date -Rdate +%z上面两个命令都可[[email protected] ~]# date -R; date +%zFri, 19 Oct 2012 23:34:27 +0800+0800主要就是后面的+0800,东八区修改时区cp /etc/localtime /etc/localtime.bak #备份系统默认时区cp /usr/share/zoneinfo/Asia/Shanghai /etc/l

Ubuntu 14.04下Gedit编辑器设置为多语言编辑及集成开发环境

Gedit是一个通用的编辑程序,其支持插件及自定义语言设置功能. 以Ubuntu 14.04下的Gedit编辑器为例,介绍其定制方法: 1 安装插件 sudo apt-get install gedit-plugins 2 在gedit中设置插件 略 3 设置语言配置文件 进入语言配置文件夹 cd /usr/share/gtksourceview-3.0/language-specs 查看语言配置文件(*.lang) ls 4 添加语言并根据配置文件设置对应源程序的扩展名 查看当前目录下相近语言

Exchange 2016之用EMS配置全局OWA语言和时区设置

很多人首次登陆owa的时候,都会遇到一个情况,设置owa语言和时区,在Exchange 2013 OWA,北京时间的时区要拉好长才可以找到,今天我们简单的说一下如何在exchange 2016上配置全局OWA语言和时区设置.(该办法适用于Exchange 2013) 我们可以通过在exchange management shell输入get-MailboxRegionalConfiguration mailboxname | fl 查看Language和TimeZone的信息,默认是为空的: 所

QT在linux环境下读取和设置系统时间(通过system来直接调用Linux命令,注意权限问题)

QT在Linux环境下读取和设置系统时间 本文博客链接:http://blog.csdn.NET/jdh99,作者:jdh,转载请注明. 环境: 主机:Fedora12 开发软件:QT 读取系统时间 [cpp] view plain copy void moreidDialog::refresh_time() { QDateTime time; txt_time->setText(time.currentDateTime().toString("yyyy") + ".&

Linux下 环境变量设置方法

etc/profile:在登录时,操作系统定制用户环境时使用的第一个文件,此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行. /etc/environment:在登录时操作系统使用的第二个文件,系统在读取你自己的profile前,设置环境文件的环境变量. ~/.profile:在登录时用到的第三个文件是.profile文件,每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该文件仅仅执行一次!默认情况下,他设置一些环境变量,执行用户的.bashrc文件.

linux系统的语言环境设置之浅见

在linux的系统中经常碰到字符集导致的错误,下面总结了设置修改系统语言环境的方法. 1.环境变量LANG用于设置系统的语言环境. 当启动某些perl.php或其他编程的语言的程序文档时, 其都会主动去分析环境变量LANG的数据, 如果发现无法解析字符编码,可能会出现乱码或错误. 一般中文编码通常是zh_CN.UTF-8(简体中文)或者zh_TW.UTF-8(繁体中文),英文的字符集编 码一般为en_US/en_US.UTF8 目前大多数的linux distributions已经都是支持万国码