原址:http://blog.donews.com/quickmouse/archive/2008/05/08/1287733.aspx

by quickmouse <> 2008年5月8日

一直以来应用Linux也就是随便的写点程序,构建一下服务器,很少关注一个基本的设置——时区。我相信大部分的爱好者们都是如此的,我们生活在一个地

方,一个国家,一个地区,至少不会频繁改变。so…我们的机器时间设置是很少变化的,再加上现在很多情况下都有UTP——时间网络同步协议了,更不要说去

改变时区。

然而对于一个应用Linux作为平台的产品而言,它却是可能会被改变时区的,即便机会不多,但对于设计人员、工程师、项目经理而言,这一部分不容忽视。于

是,在第二次遇到这个问题的时候,我选择将它彻底弄清楚,所以有了这样一篇记录。问题的描述是这样的:我们可以使用time调用获取当前的时间,注意,这

是以UTC表示的机器时间——自1970年1月1日0点以来的秒数,接着我们用localtime调用可以将time获取的时间转换为本地时间,从UTC

转换到本地时间会依靠时区信息进行调整。对于一个daemon进程而言,如果每隔一段时间用time和localtime调用就可以定期获取当前时间的数

值,但是如果在这个期间发生了时区设置转换会怎样呢?

或许你会觉得,那一定会出大问题——时区变了,localtime也会出现很大的调整。嗯,接下来的结论就是后续的程序需要小心处理这种变化……

很不幸,我们的感觉是错的,如果时区的设置变化了,localtime转换的时间依然与之前没有什么不同,除非程序再次启动。Linux的时区设置通过几

个不同的途径完成。一方面可以通过设置环境变量TZ来指定时区,例如TZ=Asia/Shanghai,可以将时区指定为上海所在的时区,时区的配置出现

在/usr/share/zoneinfo/Asia/Shanghai文件当中(Redhat环境);如果没有指定TZ环境变量,那么缺省的时区配置文

件可以用/etc/localtime来获得,这个文件可能是一个符号链接指向真实的文件,也有可能就是将/usr/share/zoneinfo下的文

件复制过来达到所要的结果。由于环境变量由各个进程组单独继承,那么在设置时区之后很难改变其他进程组的环境变量,所以一般的系统很少直接设置TZ环境变

量,而是由/etc/localtime文件来指示时区位置。

既然如此,为什么设置了时区以后,已经运行的daemon程序在使用localtime函数调用时没有使用新时区呢?这个可以通过glibc的源码来回

答。localtime等涉及到本地所在时区的函数在调用的时候会先调用tzset这个函数,这一点可以通过tzset函数的manpage看出来。

tzset完成的工作是把当前时区信息(通过TZ环境变量或者/etc/localtime)读入并缓冲。事实上tzset在实现的时候是通过内部的

tzset_internal函数来完成的,显式的调用tzset会以显式的方式告知tzset_internal,而单独调用localtime的时候

是以隐式的方式告知tzset_internal,前者将强制tzset不管何种情况一律重新加载TZ信息或者/etc/localtime,而后者则是

只有在TZ发生变化,或者加载文件名发生变化的时候才会再次加载时区信息。因此,如果只是/etc/localtime的内容发生了变化,而文件名"

/etc/localtime"没有变化,则不会再次加载时区信息,导致localtime函数调用仍然以老时区转换UTC时间到本地时间。

结论:对localtime的反复调用,如果要考虑时区变化的因素,最好显式的调用一次tzset。或许今后的glibc库会修正这个bug?至少我在glibc-2.3.5和2.4的版本上还看到这个问题。

(豆芽) :

大家有没有碰到这种情况

程序A.pl运行中定时用localtime获取本地时间

比如此时取到的时间串是

2008-03-07-11-20-53

然后重新设置系统时区

[root@xx34 ~]# date

五  3月  7 11:20:58 CST 2008

[root@xx34 ~]# cp /usr/share/zoneinfo/America/New_York  /etc/localtime

cp:是否覆盖‘/etc/localtime’? y

[root@xx34 ~]# date

四  3月  6 22:21:20 EST 2008

但还在运行的A.pl用localtime获取的时间却是

2008-03-07-11-21-53

而不是

2008-03-06-22-21-53

但重新启动A.pl再取到的时间却是正确的

有没什么办法解决, 不想去重启程序

先谢过了^_^

(豆芽):隔了这么久,今天才找到解决方法, 呵呵

由于程序是作为daemon运行的

在运行过程中会调用到localtime函数

如果在程序运行中时区发生变化

但localtime得到的本地时间还是以最初得到的时区为标准转换的

所以得到的本地时间是错误的

这个是因为perl的localtime是基于C的,

简单地说,

如果TZ环境变量没有变化或者时区配置文件/etc/localtime没有改变文件名

则不会重新加载时区信息

在调用localtime之前调用tzset,则可强制刷新时区信息

例:

use POSIX qw/tzset/;

tzset();

my ($sec,$min,$hour,$mday,$mon,$year,@temp) = localtime();

这样得到的本地时间就是正确的

参考:http://blog.donews.com/quickmouse/archive/2008/05/08/1287733.aspx

linux localtime 时区,localtime与时区zonetime的问题相关推荐

  1. linux设置默认时区,关于linux:如何修改-Linux-默认时区

    在上一篇笔记中,咱们晓得了如何在Linux 中查看零碎默认时区,这篇笔记来学习以下如何批改默认时区. 在Linux 服务器或零碎上放弃正确的工夫始终是一个好习惯,它可能具备以下长处: 因为Linux ...

  2. oracle服务器的操作系统,Oracle Linux 操作系统及数据库的时区机制分析

    Oracle Linux 操作系统及数据库的时区机制分析 1. /etc/localtime 这个文件记录的是系统的时区,缺省的数据库由此获得时区信息 这个文件是二进制文件,修改该文件的方法是拷贝/u ...

  3. linux连接建立的时间,用timedatectl在Linux中检查当前时区及更改时区(创建符号链接来更改时区)...

    本文介绍如何在Linux操作系统中设置或更改时区的方法,可以使用timedatectl,包括通过创建符号链接来更改时区. 前言 时区是具有相同标准时间的地理区域,通常,时区是在操作系统的安装过程中设置 ...

  4. linux OS与SQL修改时区,系统时间

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

  5. Linux修改系统时间、时区

    Linux修改系统时间.时区 查看现在时区 查看时区命令:date -R root@ids:~# date -R Wed, 08 Jul 2020 01:58:11 +0000 可以看到现在时区为+0 ...

  6. linux 查看tomcat时区,项目系统时区问题

    Spring时区转换问题 spring转json的默认实现jackson中会根据时区去转换时间,而jackson的默认时区跟国内是相差8小时的. 解决方法: 重新设置当前项目地所在时区.使用注解的方法 ...

  7. Linux:查看时区和修改时区

    目录 查看系统时区 获取时区TZ值 更改用户时区 更改系统时区 查看系统时区 # +8表示东八区 $ date -R Sun, 15 Jan 2023 10:15:24 +0800 获取时区TZ值 如 ...

  8. linux设置gmt时间,CentOS时区GMT修改为CST

    GMT:格林尼标准时间 北京时间=GMT时间+8小时 [root@sa~]# date -R 查看目前服务器的时间标准 [root@sa~]# vi /etc/sysconfig/clock 将ZON ...

  9. Linux服务器修改时间和时区和北京时间同步

    有时可能服务器的时区和时间和本地不一致导致一些关于使用了时间时区的代码运行出问题,下面来说说关于修改Linux服务器的时间和时区 修改服务器时间和时区#备份原文件sudo mv /etc/localt ...

最新文章

  1. android专题-数据库Room
  2. 工业互联网 — 5G 边缘计算与 IIoT
  3. 选项卡 都是显示在页面底部
  4. HashTable 解决碰撞(冲突)的方法 —— 分离链接法(separate chaining)
  5. linux java程序启动脚本
  6. php 表格分页代码,[Php]分页及表格样式
  7. c3p0 服务启动获取连接超时_c3p0获取连接Connection后的Close()---释疑
  8. 微信小程序API之audio
  9. 微软Office Online服务安装部署(二)
  10. Let’s Encrypt 免费ssl加密
  11. AI连围棋都可以大胜,何况游戏
  12. 试图速成的RPG Maker MV 学习笔记(三)
  13. 复试21天Day 20
  14. 利用函数求三个数的最大值
  15. 什么是哥德尔不完备定理?
  16. 3V, 256Mb MX25L25673GM2I-08G FLASH - NOR 存储器PDF
  17. 【Unity】Avatar与AvatarMask系统介绍(TPS.番外篇)
  18. Spring之AOP系列--指示器
  19. nslookup type值_nslookup命令详解
  20. 华为交换机:基础命令入门学习

热门文章

  1. iOS开发手机震动效果
  2. 好用的截图工具Snipaste使用教程
  3. python基础--列表知识和常见操作
  4. 求购X-Argus,X-Gorgon,X-Khronos,X-Ladon python版 xa、xg、xk、xl
  5. 产品防护:5种常见的短信验证码防刷策略
  6. Android studio 多渠道版本打包方法 flavor dimension
  7. 前端开发:CSS的“*”“#”“.”符号的对比使用
  8. java throwable_Java Throwable、Error与Exception
  9. 自定义的表单提交后 提示感谢您的参与( 停留时间)
  10. 搜狗输入法PC版去除弹窗广告