这两天学习了Linux环境下的时区方面的东西。做一些小笔记,也包括代码方面。

一、时区名称

从查阅到的资料看,如果没有使用夏令时的话,时区名称形式为“stdoffset”,即时区名加上时间偏移,时间偏移为正数表示西几区,负数表示东几区。如我们国家使用“CST-8”,即东八区。Linux目录/usr/share/zoneinfo/存储着不同的国家/地区的时区信息文件。一般嵌入式设备如果空间有限,可以精简掉部分信息,比如统一使用目录/usr/share/zoneinfo/Etc/下的文件。注意,这个目录的文件都是GMT**形式。东八区为GMT-8,而不是常识中认为的GMT+8,因为GMT+8一般理解为GMT时间加上8小时。但如果设置时区为GMT+8,系统时间与实际时间就会相差16个小时。

二、代码片段

1、获取时区:

一种实现方法是使用date +%z获取时区偏移值,单位为小时,有正负数之分。这个值是正常认知,即正数表示实际时间比GMT多多少个小时。使用date +%Z可获取时区名称。

代码如下:

// 获取时区
int get_timezone(int* timezone)
{const char* date_cmd = "date +%z";FILE *fp = NULL;char timezone_info[16] = {0};int tmp_time_zone = 0;fp = popen(date_cmd, "r");if (fp == NULL){return -1;}fread(timezone_info, sizeof(timezone_info), 1, fp);pclose(fp);timezone_info[strlen(timezone_info) - 1] = '\0';if (isdigit(timezone_info[1]) && isdigit(timezone_info[2])){tmp_time_zone = (timezone_info[1] - '0') * 10 + (timezone_info[2] - '0');if (timezone_info[0] == '-'){tmp_time_zone = - tmp_time_zone;}*timezone = tmp_time_zone;return 0;}else{*timezone = 0;return -1;}return 0;
}

另一种方式是使用timezone这个全局变量,这个变量存储的时间单位为秒,正负数同上第一节分析时区名称含义相同。负数表示东几区。

实现代码如下:

int get_timezone(int* timezone)
{extern long timezone; // 时区,单位为秒,如GMT-8,为-28800秒tzset(); // 必须执行*tz = -(int)(timezone / 3600);  // 注意这里的负号return 0;
}

函数get_timezone返回的值的正负数经过转换后,方便程序计算。比如ONVIF设置的时间只有UTC而不是当地时间,所以将UTC时间加上这个函数返回的时区值即可算出当地时间。除了timezone外,还有tzname和daylight这两个全局变量。它们的使用示例代码如下:

/**
* @brief 获取时区名称、时间偏移值
*
* @param tz1[OUT]   时间名称0
* @param tz2[OUT]   时间名称1
* @param tz_seconds[OUT]   时间偏移值,单位为秒,如东八区,与GMT时间相差-28800秒
* @param daylight_saving[OUT] 夏令时 为0不使用,非0则使用
*
* @return 0: 成功 -1:失败
* @note  使用东八区测试,daylight_saving为1,不知是否正常测试:
PST8PDT时区
rm /etc/localtime
ln -s /usr/share/zoneinfo/PST8PDT /etc/localtimetzname[0]:PST
tzname[1]: PDT
timezone: 28800 (正数表示西几区)
*/
void get_tz_name(char* tz1, char* tz2, long* tz_seconds, int* daylight_saving)
{extern char *tzname[2];extern long timezone; // 时区,单位为秒,如-8区,为-28800秒extern int daylight;tzset(); // 必须执行strcpy(tz1, tzname[0]);strcpy(tz2, tzname[1]);*tz_seconds = timezone;*daylight_saving   = daylight;
}

2、时区名称和时区值转换

ONVIF使用的时区名称是posix标准,但要从中知道是哪一个时区,以便对应于GMT**的形式。转换代码如下:

/**
* @brief 时区名称转换为时区数值
*
* @param tzname[IN]   时区名称,posix标准,如东八区时区为GMT-8,西八区为GMT+8,西八区也可以用PST8PDT表示
*
* @return -12~12: 成功 1024:失败
* @note  这里返回的时区数值是为了程序方便计算,比如返回8表示是东八区时间(与上述的时区名称不同),
*        这样在GMT时间加上8小时就是当地时间,其它同理
*/
int convert_tzname2tz(const char* tzname)
{
#define IS_TZ(foo) (!strncmp(tzname, foo, strlen(foo)))// "GMTxxx" first: GMT0/GMT+0/GMT-0 GMT-8 GMT-08// CSTif (IS_TZ("GMT") || IS_TZ("CST")){char *endptr;long val = strtol(&tzname[3], &endptr, 10);if (val >= -12 && val <= 12) return -val;else return 1024;}else if (IS_TZ("IDLW")){return -12;}else if (IS_TZ("NT")||IS_TZ("NUT")||IS_TZ("SST")){return -11;}else if (IS_TZ("AHST") || IS_TZ("CAT")||IS_TZ("HST")||IS_TZ("HDT")||IS_TZ("TAHT")){return -10;}else if (IS_TZ("YST")||IS_TZ("YDT")||IS_TZ("GAMT")){return -9;}else if (IS_TZ("PST")||IS_TZ("PDT")){return -8;}else if (IS_TZ("MST")||IS_TZ("MDT")){return -7;}else if (IS_TZ("CDT")){return -6;}else if (IS_TZ("EST")||IS_TZ("EDT")||IS_TZ("EAST")){return -5;}else if (IS_TZ("AST")||IS_TZ("ADT")||IS_TZ("GYT")||IS_TZ("WART")){return -4;}else if (IS_TZ("CLT")||IS_TZ("BRT")||IS_TZ("PMST")||IS_TZ("WGT")){return -3;}else if (IS_TZ("AT")||IS_TZ("GST")){return -2;}else if (IS_TZ("WAT")){return -1;}else if (IS_TZ("Zulu")||IS_TZ("UT")||IS_TZ("UTC")||IS_TZ("UCT")|| IS_TZ("Greenwich")||IS_TZ("BST")){return 0;}else if (IS_TZ("CET")||IS_TZ("FWT")||IS_TZ("MET")||IS_TZ("MEWT")||IS_TZ("SWT")||IS_TZ("MEST")||IS_TZ("MESZ")||IS_TZ("SST")||IS_TZ("FST")){return 1;}else if (IS_TZ("EET")||IS_TZ("IST")){return 2;}else if (IS_TZ("BT")||IS_TZ("MSK")){return 3;}else if (IS_TZ("ZP4")){return 4;}else if (IS_TZ("ZP5")){return 5;}else if (IS_TZ("ZP6")){return 6;}else if (IS_TZ("ZP7")){return 7;}else if (IS_TZ("WAST")||IS_TZ("HKT")||IS_TZ("SGT")){return 8;}else if (IS_TZ("JST")){return 9;}else if (IS_TZ("ACT")){return 10;}else if (IS_TZ("EAST")){return 11;}else if (IS_TZ("IDLE")){return 12;}else{return 1024;}return 1024;
}

从时区数值转换为时区名称代码示例:

/*
g_tz_name是时区名称,请到 /usr/share/zoneinfo/Etc/目录查看文件。
数值前面正数表示时区位于本初子午线之西,负数表示时区位于本初子午线之东。
如不明白,请在linux环境执行命令“man tzset”阅读文档。
*/
const char* g_tz_name[25] = {"GMT+12","GMT+11","GMT+10","GMT+9","GMT+8","GMT+7","GMT+6","GMT+5","GMT+4","GMT+3","GMT+2","GMT+1","GMT","GMT-1","GMT-2","GMT-3","GMT-4","GMT-5","GMT-6","GMT-7","GMT-8","GMT-9","GMT-10","GMT-11","GMT-12",
};/**
* @brief 返回时区名称
*
* @param timezone[IN]   时区数值,如东八区为+8,西八区为-8
*
* @return 时区名称
*/
const char* get_timezone_info(int timezone)
{return g_tz_name[timezone + 12];
}

李迟 2016.01.23 周六 今天特冷

linux时区的几个代码片段相关推荐

  1. linux的时间是msk,linux时区的几个代码片段

    这两天学习了Linux环境下的时区方面的东西.做一些小笔记,也包括代码方面. 一.时区名称 从查阅到的资料看,如果没有使用夏令时的话,时区名称形式为"stdoffset",即时区名 ...

  2. php编程神器,PHP代码神器 十个PHP代码片段超极好用

    PHP开发中敲代码是最能磨练人意志的,面对枯燥的代码有些人感兴趣,然而有些人不耐烦,面对如此多的代码总想着可以复制粘贴,以提高效率.PHP代码有这种功能,今天小编给大家推荐一些PHP代码神器,十个超极 ...

  3. 一些日常工具集合(C++代码片段)

    一些日常工具集合(C++代码片段) --工欲善其事,必先利其器 尽管不会松松松,但是至少维持一个比较小的常数还是比较好的 在此之前依然要保证算法的正确性以及代码的可写性 本文依然会持久更新,因为一次写 ...

  4. php常用的十个代码片段,转载

    为什么80%的码农都做不了架构师?>>>            PHP是一种HTML内嵌式的语言,是一种在服务器端执行的嵌入HTML文档的脚本语言.PHP拥有数以百计的基本功能,支持 ...

  5. JavaScript代码片段

    简介:本文收集了我常用的JavaScript代码片段,欢迎提意见! 大灰狼边敲门边说:"小兔子乖乖,把门儿开开!" 小兔子听到后,连忙去开门:"来喽!" 兔妈妈 ...

  6. 第一百一十八期:运行 JavaScript 代码片段的 20 种工具

    运行 JavaScript 代码片段的 20 种工具 前端日常开发中,我们使用喜爱的 IDE 调试 JavaScript 代码,比如我喜欢的代码编辑器有两个,Sublime Text 3 和 VS C ...

  7. 直接拿来用,10个PHP代码片段

    PHP是一种HTML内嵌式的语言,是一种在服务器端执行的嵌入HTML文档的脚本语言.PHP拥有数以百计的基本功能,支持上千种扩展.这些功能都被很好的加载在PHP站点上,但内置的库有各种各样的命名.在P ...

  8. python实现微信自动加群_为Python开发人员提供实时代码片段,Kite获1700万美元A轮融资...

    [猎云网(微信号:)]1月29日报道(编译:孙家乐) Kite是一款为Python开发人员提供实时代码片段的工具,它在由Trinity Ventures领投的A轮融资中获得了1700万美元.最新版本的 ...

  9. 积水成渊:用github gist收藏你的代码片段

    Github Gis服务 出生名门github 用于记录代码片段 匿名张贴 能像wiki一样记录历史如果您修改了已经发布了的Gist的话,之前的所有版本都将被保存. 支持markdown ... 更多 ...

最新文章

  1. Windows 服务器操作系统安全设置加固方法
  2. C++知识点60——非类型模板参数
  3. 如何布局文章标题才更吸引搜索引擎注意?
  4. textarea怎样隐藏滚动条
  5. java assert可以检查exception吗_检查胃病一定要做胃镜吗?这五种检查也可以筛查胃病疾病...
  6. JAVA中构造器和方法的区别点
  7. 世界上迄今为止最安全的加密算法
  8. asp.net文件上传进度条控件(破解版~没时间限制)多项自定义 .
  9. 改造create-react-app 通过npm命令动态打包文件
  10. matlab改变示波器颜色,[转载]matlab/simulink 示波器颜色设置
  11. order( )函数--R语言
  12. mysql 减函数_mysql时间加减函数
  13. tengine2.2.3报错502的The proxy server received an invalid response from an upstream server问题处理...
  14. 电机驱动芯片——DRV8833、TB6612、A4950、L298N的详解与比较
  15. weblogic部署静态资源文件html,Tomcat和Weblogic部署纯html文件过程解析
  16. Oracle体系结构图(思维导图及详解)
  17. RPM软件包管理命令简介
  18. atcod D - Staircase Sequences
  19. 软件工程 学习笔记 知识梳理
  20. Python免安装环境(Windows)

热门文章

  1. 苹果年底推出搭载M2芯片MacBook Air和MacBook Pro
  2. “全国住房公积金”微信小程序正式上线 快速办理“异地转移”
  3. 讯飞输入法新升级:支持离线输入方式 加强用户数据安全
  4. 马斯克称特斯拉可能恢复比特币交易后 比特币价格突破4万美元
  5. 近期新机发布一览:最便宜的只需699元!
  6. 何小鹏:创业初期每月都去借钱 网易丁磊借了80万
  7. 拼多多“官宣”iPhone 12:来得刚刚好 下周见!
  8. 华为Mate 40 Pro屏幕贴膜曝光:双孔曲面屏实锤?
  9. 外媒:美国政府官员建议阻止英飞凌收购赛普拉斯
  10. 强迫症告辞!三星Galaxy S11这“凌乱”的后置5摄,感受下