linux c++ 获取时间,详解Linux下的C++时间类型:time_t

Unix时间戳(Unix timestamp),或称Unix时间(Unix time)、POSIX时间(POSIX

time),是一种时间表示方式,定义为从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。Unix时间戳不仅被使用在Unix

系统、类Unix系统中,也在许多其他操作系统中被广泛采用。

目前相当一部分操作系统使用32位二进制数字表示时间。此类系统的Unix时间戳最多可以使用到格林威治时间2038年01月19日03时14分07秒(二进制:01111111

11111111 11111111 11111111)。其后一秒,二进制数字会变为10000000 00000000 00000000

00000000,发生溢出错误,造成系统将时间误解为1901年12月13日20时45分52秒。这很可能会引起软件故障,甚至是系统瘫痪。使用64位二进制数字表示时间的系统(最多可以使用到格林威治时间292,277,026,596年12月04日15时30分08秒)则基本不会遇到这类溢出问题。

首先课课家视频教程平台带大家了解一下时间的相关概念,以及之间的区别,需要了解的时间概念有:

本地时间(locale time)

格林威治时间(Greenwich Mean Time GMT)

时间协调时间 (Universal Time Coordinated UTC)

本地时间,显而易见不用解释了

先看看时间的标准:

(1)世界时

世界时是最早的时间标准。在1884年,国际上将1s确定为全年内每日平均长度的1/8.64×104。以此标准形成的时间系统,称为世界是,即UT1。1972年国际上开始使用国际原子时标,从那以后,经过格林威治老天文台本初子午线的时间便被称为世界时,即UT2,或称格林威治时间(GMT),是对地球转速周期性差异进行校正后的世界时。

(2)原子时

1967年,人们利用铯原子振荡周期极为规律的特性,研制出了高精度的原子时钟,将铯原子能级跃迁辐射9192631770周所经历的时间定为1s。现在用的时间就是1971年10月定义的国际原子时,是通过世界上大约200多台原子钟进行对比后,再由国际度量衡局时间所进行数据处理,得出的统一的原子时,简称TAI。

(3)世界协调时

世界协调时是以地球自转为基础的时间标准。由于地球自转速度并不均匀,并非每天都是精确的86400原子s,因而导致了自转时间与世界时之间存在18个月有1s的误差。为纠正这种误差,国际地球自转研究所根据地球自转的实际情况对格林威治时间进行增减闰s的调整,与国际度量衡局时间所联合向全世界发布标准时间,这就是所谓的世界协调时(UTC:CoordinatdeUniversalTime)。UTC的表示方式为:年(y)、月(m)、日(d)、时(h)、分(min)、秒(s),均用数字表示。

GPS

系统中有两种时间区分,一为UTC,另一为LT(地方时)两者的区别为时区不同,UTC就是0时区的时间,地方时为本地时间,如北京为早上八点(东八区),UTC时间就为零点,时间比北京时晚八小时,以此计算即可

通过上面的了解,我们可以认为格林威治时间就是时间协调时间(GMT=UTC),格林威治时间和UTC时间均用秒数来计算的。

而在我们平时工作当中看到的计算机日志里面写的时间大多数是用UTC时间来计算的,那么我们该怎么将UTC时间转化为本地时间便于查看日志,那么在作程序开发时又该怎么将本地时间转化为UTC时间呢?

下面就介绍一个简单而使用的工具,就是使用Linux/unix命令date来进行本地时间和local时间的转化。

大家都知道,在计算机中看到的utc时间都是从(1970年01月01日

0:00:00)开始计算秒数的。所看到的UTC时间那就是从1970年这个时间点起到具体时间共有多少秒。

我们在编程中可能会经常用到时间,比如取得系统的时间(获取系统的年、月、日、时、分、秒,星期等),或者是隔一段时间去做某事,那么我们就用到一些时间函数。

linux下存储时间常见的有两种存储方式,一个是从1970年到现在经过了多少秒,一个是用一个结构来分别存储年月日时分秒的。

time_t 这种类型就是用来存储从1970年到现在经过了多少秒,要想更精确一点,可以用结构struct

timeval,它精确到微妙。

struct timeval

{

long tv_sec;

long tv_usec;

};

而直接存储年月日的是一个结构:

struct tm

{

int tm_sec;

int tm_min;

int tm_hour;

int tm_mday;

int tm_mon; 1+p->tm_mon;

int tm_year; 1900+ p->tm_year;

int tm_wday;

int tm_yday;

int tm_isdst;

};

需要特别注意的是,年份是从1900年起至今多少年,而不是直接存储如2011年,月份从0开始的,0表示一月,星期也是从0开始的,

0表示星期日,1表示星期一。

下面介绍一下我们常用的时间函数:

#include

char *asctime(const struct tm* timeptr);

将结构中的信息转换为真实世界的时间,以字符串的形式显示

char *ctime(const time_t *timep);

将timep转换为真是世界的时间,以字符串显示,它和asctime不同就在于传入的参数形式不一样

double difftime(time_t time1, time_t time2);

返回两个时间相差的秒数

int gettimeofday(struct timeval *tv, struct timezone *tz);

返回当前距离1970年的秒数和微妙数,后面的tz是时区,一般不用

struct tm* gmtime(const time_t *timep);

将time_t表示的时间转换为没有经过时区转换的UTC时间,是一个struct tm结构指针

stuct tm* localtime(const time_t *timep);

和gmtime类似,但是它是经过时区转换的时间。

time_t mktime(struct tm* timeptr);

将struct tm 结构的时间转换为从1970年至今的秒数

time_t time(time_t *t);

取得从1970年1月1日至今的秒数。

上面是简单的介绍,下面通过实战来看看这些函数的用法:

#include

int main()

{

time_t timep;

time(&timep);

printf("%s", asctime(gmtime(&timep)));

return 0;

}

编译并运行:

$gcc -o gettime1 gettime1.c

$./gettime1

Fri Jan 11 17:04:08 2008

下面是直接把time_t类型的转换为我们常见的格式:

#include

int main()

{

time_t timep;

time(&timep);

printf("%s", ctime(&timep));

return 0;

}

编译并运行:

$gcc -o gettime2 gettime2.c

$./gettime2

Sat Jan 12 01:25:29 2008

我看了一本书上面说的这两个例子如果先后执行的话,两个的结果除了秒上有差别之外(执行程序需要时间),应该是一样的,可是我这里执行却发现差了很长时间按,一个是周五,一个是周六,后来我用

date 命令执行了一遍

$date

六 1月 12 01:25:19 CST 2008

我发现date和gettime2比较一致, 我估计可能gettime1并没有经过时区的转换,它们是有差别的。

#include

int main()

{

char *wday[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri",

"Sat"};

time_t timep;

struct tm *p;

time(&timep);

p = gmtime(&timep);

printf("%d/%d/%d ", 1900 + p->tm_year, 1 + p->tm_mon,

p->tm_mday);

printf("%s %d:%d:%d\\n", wday[p->tm_wday],

p->tm_hour,

p->tm_min, p->tm_sec);

return 0;

}

编译并运行:

$gcc -o gettime3 gettime3.c

$./gettime3

2008/1/11 Fri 17:42:54

从这个时间结果上来看,它和gettime1保持一致。

#include

int main()

{

char *wday[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri",

"Sat"};

time_t timep;

struct tm *p;

time(&timep);

p = localtime(&timep);

printf("%d/%d/%d ", 1900 + p->tm_year, 1 + p->tm_mon,

p->tm_mday);

printf("%s %d:%d:%d\\n", wday[p->tm_wday], p->tm_hour,

p->tm_min, p->tm_sec);

return 0;

}

编译并运行:

$gcc -o gettime4 gettime4.c

$./gettime4

2008/1/12 Sat 1:49:29

从上面的结果我们可以这样说:

time, gmtime, asctime 所表示的时间都是UTC时间,只是数据类型不一样,

而localtime, ctime

所表示的时间都是经过时区转换后的时间,它和你用系统命令date所表示的CST时间应该保持一致。

#include

int main()

{

time_t timep;

struct tm *p;

time(&timep);

printf("time():%d\\n",timep);

p = localtime(&timep);

timep = mktime(p); //by lizp 错误,没有时区转换, 将struct tm

结构的时间转换为从1970年至p的秒数

printf("time()->localtime()->mktime(): %d\\n",

timep);

return 0;

}

编译并运行:

$gcc -o gettime5 gettime5.c

$./gettime5

time():1200074913

time()->localtime()->mktime(): 1200074913

这里面把UTC时间按转换为本地时间,然后再把本地时间转换为UTC时间,它们转换的结果保持一致。

#include

int main()

{

time_t timep;

struct tm *p;

time(&timep);

printf("time():%d\\n",timep);

p = gmtime(&timep);

timep = mktime(p); //by lizp 错误,没有时区转换, 将struct tm

结构的时间转换为从1970年至p的秒数

printf("time()->gmtime()->mktime(): %d\\n", timep);

return 0;

}

编译并运行:

$gcc -o gettime6 gettime6.c

$./gettime6

time():1200075192

time()->gmtime()->mktime(): 1200046392

从这里面我们可以看出,转换后时间不一致了,计算一下,整整差了8个小时(

(1200075192-1200046392)/3600 =

8),说明mktime会把本地时间转换为UTC时间,这里面本来就是UTC时间,于是再弄个时区转换,结果差了8个小时,用的时候应该注意。

strftime() 函数将时间格式化

我们可以使用strftime()函数将时间格式化为我们想要的格式。它的原型如下:

size_t strftime(

char *strDest,

size_t maxsize,

const char *format,

const struct tm *timeptr

);

我们可以根据format指向字符串中格式命令把timeptr中保存的时间信息放在strDest指向的字符串中,最多向strDest中存放maxsize个字符。该函数返回向strDest指向的字符串中放置的字符数。

函数strftime()的操作有些类似于sprintf():识别以百分号(%)开始的格式命令集合,格式化输出结果放在一个字符串中。格式化命令说明串

strDest中各种日期和时间信息的确切表示方法。格式串中的其他字符原样放进串中。格式命令列在下面,它们是区分大小写的。

%a 星期几的简写

%A 星期几的全称

%b 月分的简写

%B 月份的全称

%c 标准的日期的时间串

%C 年份的后两位数字

%d 十进制表示的每月的第几天

%D 月/天/年

%e 在两字符域中,十进制表示的每月的第几天

%F 年-月-日

%g 年份的后两位数字,使用基于周的年

%G 年分,使用基于周的年

%h 简写的月份名

%H 24小时制的小时

%I 12小时制的小时

%j 十进制表示的每年的第几天

%m 十进制表示的月份

%M 十时制表示的分钟数

%n 新行符

%p 本地的AM或PM的等价显示

%r 12小时的时间

%R 显示小时和分钟:hh:mm

%S 十进制的秒数

%t 水平制表符

%T 显示时分秒:hh:mm:ss

%u 每周的第几天,星期一为第一天 (值从0到6,星期一为0)

%U 第年的第几周,把星期日做为第一天(值从0到53)

%V 每年的第几周,使用基于周的年

%w 十进制表示的星期几(值从0到6,星期天为0)

%W 每年的第几周,把星期一做为第一天(值从0到53)

%x 标准的日期串

%X 标准的时间串

%y 不带世纪的十进制年份(值从0到99)

%Y 带世纪部分的十制年份

%z,%Z 时区名称,如果不能得到时区名称则返回空字符。

%% 百分号

如果想显示现在是几点了,并以12小时制显示,就象下面这段程序:

#include "time.h"

#include "stdio.h"

int main(void)

{

struct tm *ptr;

time_t lt;

char str[80];

lt=time(NULL);

ptr=localtime(

strftime(str,100,"It is now %I %p",ptr);

printf(str);

return 0;

}

其运行结果为:

It is now 4PM

而下面的程序则显示当前的完整日期:

#include

#include

#include

int main( void )

{

struct tm *newtime;

char tmpbuf[128];

time_t lt1;

time( <1 );

newtime=localtime(<1);

strftime( tmpbuf, 128, "Today is %A, day %d of %B in the year

%Y.\\n", newtime);

printf(tmpbuf);

return 0;

}

以上内容由课课家linux视频教程平台提供

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/257398.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

程序员的国庆节如何安排,你想好了吗?

2019独角兽企业重金招聘Python工程师标准>>> 就要国庆放假了&#xff0c;国庆节是旅游的黄金期&#xff0c;同时也是我们买买买的幸福期&#xff0c;作为一名技术开发&#xff0c;除了要安排假期旅游行程外也不要忘记提升自己&#xff0c;准备好学习计划&#xff0c…

Print! Print! Print!

print语句可以实现打印--只是对程序员友好的标准输出流的接口而已。 从技术角度来讲&#xff0c;这是把一个或多个对象转换为其文本表达形式&#xff0c;然后发送给标准输出或另一个类似文件的流。 更详细地说&#xff0c;在Python中&#xff0c;打印与文件和流的概念紧密相连。…

C#让TopMost窗体弹出并置顶层但不获取当前输入焦点的终极办法

为了使程序在弹出窗口时置顶层且不获取系统输入焦点&#xff0c;避免影响用户当前的操作&#xff0c;来电通来电弹屏软件尝试过N多种办法&#xff0c;例如&#xff1a;弹出前保存当前焦点窗口句柄&#xff0c;弹出时因为使用TopMost系统默认将焦点交给了弹出窗口&#xff0c;弹…

微服务实战(一):微服务架构的优势与不足

本文讲的是微服务实战&#xff08;一&#xff09;&#xff1a;微服务架构的优势与不足&#xff0c;【编者的话】本文来自Nginx官方博客&#xff0c;是微服务系列文章的第一篇&#xff0c;主要探讨了传统的单体式应用的不足&#xff0c;以及微服务架构的优势与挑战。正如作者所说…

linux创建zip+函数,linux+shell基础知识

目录&#xff1a;1.路径&#xff1a;2.进程&#xff1a;3.清屏和退出当前命令操作&#xff1a;4.ls 参数&#xff1a;5.创建目录\文件\复制文件&#xff1a;6.查看文件内容&#xff1a;7.linux通配符&#xff1a;8.grep:9.终止命令&#xff1a;10.搜索文件&#xff1a;11.查看网…

关于浮动float属性和position:absolute属性的区别

最近返回头看了很多书籍&#xff0c;一直在纠结float属性和absolute绝对定位的区别和使用的情况&#xff0c;给大家分享一下自己的心得和体会吧。 1&#xff0c;float属性 float属性意义是让元素拜托独占一行的霸道总裁&#xff0c;成为一个普普通通的人。比如下面这个例子 如图…

Climbing Stairs

You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? 分析&#xff1a;考虑走第n步时的情况&#xff0c;可以从第n-1个台阶走一步&#xff0c;也可以从…

3dmax linux版本,如何安装Linux版FLOW-3D及注意事项

如何安装Linux版FLOW-3D及注意事项安装Linux版的flow3d流程&#xff1a;1、复制flow3d安装CD盘中unix文件夹到Linux系统桌面&#xff1b;(或从CD中直接安装也可以)2、从terminal进入unix文件夹&#xff1b;3、./install或./install_flow3d4、提示是否接受license协议&#xff0…

高级组合技打造“完美” 捆绑后门

0x00 简介 之前写过一篇关于客户端钓鱼的文章&#xff1a;《使用powershell Client进行有效钓鱼》中&#xff0c;在使用各个Client进行测试的过程中&#xff0c;个人发现CHM文件是最好用的一个&#xff0c;但是其缺点就是会弹黑框&#xff0c;这样就会让被攻击者察觉。那么怎么…

使用友盟分享心得(SSO登陆,不能获取accesstoken,不能跳转APPSSO登陆的问题)

在xcode5中plist 文件是默认有 Bundle DisplayName的 而如果工程是在xcode6环境下开发的话。 这时候就会出现友盟无法跳转微博跟QQSSO的问题。 solution&#xff1a;在plist中加入bundle DisplayName 转载于:https://www.cnblogs.com/ZippoatiOS/p/4443933.html

linux单线程处理多个请求,redis是单线程的,如何处理并发请求?

疑问&#xff1a;redis是单线程的&#xff0c;如何并发处理多个请求&#xff1f;下面是我个人的理解。答案是&#xff1a;使用操作系统的多进程机制。也就是我们常说的&#xff0c;多路复用API&#xff0c;多路复用API本质上是对操作系统多路复用功能的封装。什么是操作系统的多…

Cloudera Manager内部结构、功能包括配置文件、目录位置等

2019独角兽企业重金招聘Python工程师标准>>> 问题导读 1.CM的安装目录在什么位置&#xff1f; 2.hadoop配置文件在什么位置&#xff1f; 3.Cloudera manager运行所需要的信息存在什么位置&#xff1f; 4.CM结构和功能是什么&#xff1f; 1. 相关目录 /var/log/cloud…

python 学习笔记(一)

在Windows上安装Python 首先&#xff0c;从Python的官方网站www.python.org下载最新的2.7.9版本&#xff0c;地址是这个&#xff1a; http://www.python.org/ftp/python/2.7.9/python-2.7.9.msi 然后&#xff0c;运行下载的MSI安装包&#xff0c;在选择安装组件的一步时&#x…

An ffmpeg and SDL Tutorial

http://dranger.com/ffmpeg/转载于:https://www.cnblogs.com/qwertWZ/p/4447141.html

linux模式匹配,sed的模式匹配用法探讨

[rootsunsky Desktop]# cat sunskyabcdef[rootsunsky Desktop]# cat sunsky|sed 1,2d|sed 1,2def[rootsunsky Desktop]# cat sunsky|sed -e 1,2d -e 1,2ddef问题&#xff1a;sed中-e的意思是直接在指令列模式上进行sed的动作编辑按照&#xff0c;那么按照-e的含义&#xff0c;上…

Qualcomm QXDM工具简介和log抓取

高通工具简介QXDM 简介QXDM 安装QXDM 激活QXDM 使用AT打开Diagnostic口 QXDM 配置1 Message View ConfigurationMessage PacketsLog PacketsLog PacketsOTAEvent ReportsStrings2 Log View Config3 QXDM-保存配置文件4 QXDM-导入配置文件QPST 端口配置QXDM 抓取log QXDM LOG保存…

layout_gravity

layout_gravity——当前View&#xff0c;本身&#xff0c;在父一级的控件所分配的显示范围内的&#xff0c;对齐方式常用在&#xff1a; 当前控件&#xff08;在父一级LineLayout所分配给其的显示范围内&#xff09;的对齐方式需要注意的是&#xff0c;如果TableRow的gravity确…

Linux_arm_启动_c语言部分详解,[原创]Linux arm 启动 c语言部分详解第四讲

Linux arm启动c语言部分详解第四讲(from setup_per_cpu_areas();)Written by leeming上面的setup_arch花了我们大量的篇幅&#xff0c;现在我们要继续往前推进了。注&#xff1a;黑色为主线&#xff0c;蓝色为函数的一级展开&#xff0c;红色是注意重要的地方。//因为我们没有定…

Kudu1.1.0 、 Kudu1.2.0 Kudu1.3.0的版本信息异同比较

不多说&#xff0c;直接上干货&#xff01; Kudu1.1.0 新特性 python API升级&#xff0c;具备JAVA Cclient一样的功能&#xff08;从0.3版本直接升级到1.1&#xff09;&#xff0c;主要的点如下&#xff1a; 1.1. 改进了Parial Row的语义 1.2. 增加了range partition支持 1.3.…

ASP.NET Web API 中 特性路由(Attribute Routing) 的重名问题

刚才忘了说了&#xff0c;在控制器名重名的情况下&#xff0c;特性路由是不生效的。不然的话就可以利用特性路由解决同名的问题了。 而且这种不生效是真的不生效&#xff0c;不会提示任何错误&#xff0c;重名或者什么的&#xff0c;直接会报告404&#xff0c;所以也是个坑。转…