(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)
参考:https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/mktime-mktime32-mktime64?view=msvc-170
参考:https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/localtime-localtime32-localtime64?view=msvc-170
参考:https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/gmtime-gmtime32-gmtime64?view=msvc-170
参考:https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/ctime-ctime32-ctime64-wctime-wctime32-wctime64?view=msvc-170
参考:https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/time-time32-time64?view=msvc-170

经常用time函数的时候,获取了从一个1970年1月1日0时0分0秒开始的秒数计数,但是这个计数是基于当地时区时间计数,还是格林威治时间计数,自己心里还是有问号在的。

验证测试

确认也不难,查文档,自己测试试试看,就有了下面这些记录了:

// 时间0值,代表的时间是什么时间呢?是1970.1.1,格林威治0:0:0,东8区是8:00:00
// 参考输出 time0=0 Thu Jan  1 08:00:00 1970
time_t n0 = 0;
printf("time0=%d %s\n", n0, ctime(&n0));// 获取当前时间: 格林威治时间
// 参考 now=time(NULL)=1648340045 %86400=845 Sun Mar 27 08:14:05 2022
// 参考中可以看出,845是0:14:05时刻,这个时间值是格林威治的时刻,东8区需要+8小时
time_t now = time(NULL);
printf("now=time(NULL)=%d %86400=%d %s", n, n%86400, ctime(&n));// gm为格林威治时间,直接使用time_t转换即可得到tm结构
// 参考 使用now转换格力威支时刻,显示的是 gm.hour=0, min=14, sec=5
struct tm* gm = gmtime(&now);
printf("gm.hour=%d, min=%d, sec=%d\n", gm->tm_hour, gm->tm_min, gm->tm_sec);// local为当地时间,使用time_t格林威治时间+时区偏差,生成tm结构
// 参考 使用now转换当地时刻,显示的是 local.hour=8, min=14, sec=5
struct tm* local = localtime(&now);
printf("local.hour=%d, min=%d, sec=%d\n", local->tm_hour, local->tm_min, local->tm_sec);// mktime输入的是localtime-tm结构,得到格林威治时间time_t
// ctime展示的当地时间localtime串信息
// 参考 使用local转换,显示的是 mktime=1648340045, %86400=845, Sun Mar 27 08:14:05 2022
time_t l = mktime(local);
printf("mktime=%d, %86400=%d, %s", l, l%86400, ctime(&l));// localtime与gmtime两者关系:
例如 localtime北京时间 = gmtime格林威治时间 +8小时

如果想做时区自动转换也是可以的:
例如当前计算机采用的东八区时间,想使用timezone-0作为程序的时区设置
通过:linux版本使用tzset、windows版本使用_tzset设置时区

// 设置程序使用时区0
_putenv_s("TZ", "GMT-0");
_tzset();// gmtime与localtime就会一致了, ctime展示出的也是设定timezone=0的时间了
struct tm* gm = gmtime(&now);
struct tm* local = localtime(&now);
printf("current: %s", ctime(&now));

叙述理解

研究时间这块,跟我之前理解偏差最大的一个点是:

  • time(NULL)总是返回的是当前格林威治时间,不论系统/程序采用的哪个时区;
  • 正常使用的情况下:time_t上的存储值总是描述格林威治时间;
  • tm结构存储值有时用来描述格林威治时间gmtime,有时用来描述当地时间localtime-当前时区时间;
  • ctime考虑了时区,输入值要求time_t是格林威治时间,输出来的值总是用来描述当地时间-当前时区时间;
  • mktime考虑了时区,输入的值总是要求localtime-tm结构-当前时区时间,输出值格林威治时间;

注意:

  • ctime返回的是静态变量地址;更要注意gmtime与localtime返回的静态变量地址是同一个,后调用的会覆盖上次调用的值;
  • tm结构上tm_year不同于time_t-从1970年1月1日开始,tm_year而是从1900年开始计数,输出时要+1900;
  • tm结构上tm_month从0开始,输出时需要+1; tm_mday是从1开始; tm_hour, tm_min, tm_sec的范围皆是[0, 59].
  • mktime时,不需要输入tm_wday and tm_yday。
  • Windows下:_mktime64/time handles dates from midnight, January 1, 1970 to 23:59:59, December 31, 3000. if the calendar time can’t be represented, returns -1.
  • Windows下:localtime/gmtime/ctime return NULL if the date passed to the function is Before midnight, January 1, 1970.

测试程序与输出

测试程序

#include <stdio.h>
#include <time.h>int main(){time_t n0 = 0;printf("time0=%d %s\n", n0, ctime(&n0));time_t n = time(NULL);printf("now=time(NULL)=%d %86400=%d %s", n, n%86400, ctime(&n));struct tm* gm = gmtime(&n);printf("gm.hour=%d, min=%d, sec=%d\n", gm->tm_hour, gm->tm_min, gm->tm_sec);struct tm* local = localtime(&n);printf("local.hour=%d, min=%d, sec=%d\n", local->tm_hour, local->tm_min, local->tm_sec);time_t l = mktime(local);printf("mktime=%d, %86400=%d, %s\n", l, l%86400, ctime(&l));struct tm t;t.tm_year = 70;t.tm_mon = 1;t.tm_mday = 1; // 注: windows下mktime不支持东8区取1970.1.1号8点前时间;linux是可以的;windows下可以取往后延一天的0点时间值。t.tm_hour = 0;t.tm_min = 0;t.tm_sec = 0;time_t curr = mktime(&t);printf("local-1970.1.1=%d %86400=%d %s\n", curr, curr % 86400, ctime(&curr));printf("(now-local@1970.1.1)%86400 = %d\n", (n - curr) % 86400);return 0;
}

输出

time0=0 Thu Jan  1 08:00:00 1970now=time(NULL)=1648340045 %86400=845 Sun Mar 27 08:14:05 2022
gm.hour=0, min=14, sec=5
local.hour=8, min=14, sec=5
mktime=1648340045, %86400=845, Sun Mar 27 08:14:05 2022local-1970.1.1=-28800 %86400=-28800 Thu Jan  1 00:00:00 1970(now-local@1970.1.1)%86400 = 29645

(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)

时区与time/gmtime/localtime/mktime/ctime函数联系相关推荐

  1. time gmtime localtime strftime 时间函数

    C语言中time()函数 函数简介 函数名: time 头文件:time.h 函数原型:time_t time(time_t * timer) 功能: 获取当前的系统时间,返回的结果是一个time_t ...

  2. ctime()函数以及time()使用

    C 库函数 char *ctime(const time_t *timer) 返回一个表示当地时间的字符串,当地时间是基于参数 timer. 返回的字符串格式如下:Www Mmm dd hh:mm:s ...

  3. C语言ctime函数

    ctime函数原型: #include <time.h> char *ctime(const time_t *timeval); ctime以原始时间值为参数,并将其转换为一个更易读的本地 ...

  4. Linux下gmtime、gmtime_r、localtime、localtime_r函数详解

    函数功能介绍 使用man gmtime或man localtime都可以的得到这几个函数的介绍.原型如下: struct tm *gmtime(const time_t *timep); struct ...

  5. python ctime函数_Python time 模块

    Python time 模块 在本文中,我们将详细讨论time模块.我们将通过实例学习使用time模块中定义的不同的与时间相关的函数. Python有一个命名time为处理与时间有关的任务的模块.要使 ...

  6. Perl中state()和localtime()函数

    stat函数 perl下的stat函数和shell下的stat命令的功能基本一致,也是取得文件的各类具体信息: stat()函数返回一个数组,下面是数组各个元素的含义: 0     dev      ...

  7. gmtime与mktime的重新编写

    这几日发现Linux的mktime与gmtime所处理的数据类型是32位的,即代表时间设置只能设置到2038年,在公司的产品要实现这个时间的突破还是得自己写一个新的处理时间的函数. 作为一个刚毕业的程 ...

  8. mktime时间函数

    1.函数说明 1.1描述 ​ time_t mktime(struct tm *timeptr) 把 timeptr 所指向的结构转换为自 1970 年 1 月 1 日以来持续时间的秒数,发生错误时返 ...

  9. python ctime函数_Python中的ctime()方法使用教程

    ctime()方法转换,因为历元到表示本地时间的字符串表示以秒为单位的时间.如果不设置秒时或None,所返回的时间的当前time()被使用.使用asctime(localtime(secs)).不使用 ...

最新文章

  1. iOS数据持久化--归档
  2. Matlab学习笔记:画图多重设置
  3. 3409: [Usaco2009 Oct]Barn Echoes 牛棚回声
  4. unity3d 各个目录的意思
  5. “约见”面试官系列之常见面试题第三十五篇之轮循机制(建议收藏)
  6. 关于C#监视剪贴板信息
  7. 今天工作中碰到一个clone的问题
  8. c++ inline 以及构造函数
  9. 编译安装ccache
  10. 社交媒体爬虫------调用微博API获取微博内容
  11. JSON.Stringify
  12. 计算机2级vb查询,计算机2级VB
  13. cad2019菜单栏怎么调出来_AutoCAD2019怎么把工具栏放左右两边 两侧工具栏调出来...
  14. 2018主流台式计算机跑分,pu天梯图2018最新版2018电脑cpu处理器性能排行榜
  15. C#panel渐变绘制
  16. 信息收集--OSINT
  17. 【前辈经验】——前端职位描述
  18. python thinker canvas详解_python thinker canvas create_arc 使用详解
  19. STM32 GPIO的配置寄存器(CRL、CRH)输入输出模式配置
  20. 迈出你的第一步——天助自助者

热门文章

  1. Flash图片的内存计算公式
  2. 【题解】小码哥杯(原甲骨文杯)A组初赛编程题.2016
  3. 2023最新SSM计算机毕业设计选题大全(附源码+LW)之java学生社团管理系统jcjyw
  4. 哪种ARM Cortex内核更适合我的应用:A系列、R系列、还是M系列?
  5. Rock Pi开发笔记(二):入手Rock Pi 4B plus(基于瑞星微RK3399)板子并制作系统运行
  6. 在Word指定位置插入富文本域值(html文本)
  7. 思考:从索爱X10的升级看智能手机的市场现状和发展趋势
  8. STC-B学习板蜂鸣器播放音乐
  9. matlab中文乱码解决方案
  10. Oppo_A53m救砖刷机过程