Linux 时间系统调用

UNIX及LinuxQ的时间系统是由「新纪元时间」Epoch开始计算起。Epoch是指定为1970
年1月1日凌晨零点零分零秒,格林威治时间。目前大部份的UNX系统都是用32位来记录时间,正值
表示为1970以后,负值则表示1970年以前。

对于当前时间到Epoch 我们用两种类型来描述 time_ttimeval


time_t  // 实际上就是uint32_t
struct timeval
{
  __time_t tv_sec;		/* Seconds.  */
  __suseconds_t tv_usec;	/* Microseconds.  */
};

这两个数据结构唯一的区别 就是timeval 的精度更高,精度达到了微妙

接下来我们要了解如何得到这两个类型:

time()

#include<time.h>
time_t time(time_t *tloc);

参数:

  • tloc: 当这个参数不为空的时候 ,距离Epoch 的秒数 会存在tloc所指向的内存中

返回值:
返回的是 距离Epoch 的秒数

从上面的我们发现:

  time_t t1;
  time(&t1);

  time_t t2;
  t2 = time(nullptr);

t1 和 t2 得到的结果是一样的

gettimeofday

#include<sys/time.h>
int gettimeofday(struct timeval *tv, struct timezone *tz);

参数:

  • *tv: 输入输出型参数,返回现在到Epoch 有多少秒+多少微妙
  • tz:已经被废弃,直接NULL完事

返回值:
0 代表成功,-1 代表错误,errno 会被设置


现在我们已经知道了如何获取时间,但是现在又有一个问题,存储的秒数 虽然精确但是不是很易读,如何让这些时间变得易读就要用到接下来的系统调用。

在linux 中我们使用下面的数据结构来表示 一个易读的时间

struct tm
{
  int tm_sec;			/* Seconds.	[0-60] (1 leap second) */
  int tm_min;			/* Minutes.	[0-59] */
  int tm_hour;			/* Hours.	[0-23] */
  int tm_mday;			/* Day.		[1-31] */
  int tm_mon;			/* Month.	[0-11] */
  int tm_year;			/* Year	- 1900.  */
  int tm_wday;			/* Day of week.	[0-6] */
  int tm_yday;			/* Days in year.[0-365]	*/
  int tm_isdst;			/* DST.		[-1/0/1]*/

# ifdef	__USE_MISC
  long int tm_gmtoff;		/* Seconds east of UTC.  */
  const char *tm_zone;		/* Timezone abbreviation.  */
# else
  long int __tm_gmtoff;		/* Seconds east of UTC.  */
  const char *__tm_zone;	/* Timezone abbreviation.  */
# endif
};

gmtime

struct tm *gmtime(const time_t *timep);   // 线程不安全
struct tm *gmtime_r(const time_t *timep, struct tm *result);  // 线程安全的版本

参数:

  • timep:距离Epoch 的秒数
  • result:输入输出型参数

gmtime_r 输出的结构从输入参数中得到,而不是函数的返回值中得到!gmtime 不是线程安全的原因是把结果存在了静态变量中,导致多线程的时候不可重入!

注意这里的 gmt 和 UTC (世界协调时) 是一样的

localtime

struct tm *localtime(const time_t *timep);
struct tm *localtime_r(const time_t *timep, struct tm *result);

参数:

  • timep:距离Epoch 的秒数
  • result:输入输出型参数

localtime_r输出的结构从输入参数中得到,而不是函数的返回值中得到!localtime 不是线程安全的原因是把结果存在了静态变量中,导致多线程的时候不可重入!

下面来介绍一下 gmt 时间 和 本地时间 的区别:
众所周知不同国家都是有时差的,那么比方说北京时间是如何计算出来的呢? 首先UTC(世界协调时) 是一个基准,在这个基准上我们根据经纬度 划分出不同的时区,如果我们想得到本地时间 只要用标准时间加上该地区所在时区的偏移量。
举一个简单的例子: 北京时间在东八区时区,意味着北京时间比基准时间快8个小时(偏移量),而这个标准时间就是gmtime 函数得到的时间 而 本地时间(北京时间) 就是localtime得到的时间

我们可以做一个小实验

 struct timeval t3;
  gettimeofday(&t3, NULL);

  struct tm tm1;
  struct tm tm2;
  gmtime_r(&t1, &tm1);

  localtime_r(&t1, &tm2);
  cout << tm1.tm_year << " " << tm1.tm_mon << " " << tm1.tm_mday << " "
       << tm1.tm_hour << endl;
  cout << tm2.tm_year << " " << tm2.tm_mon << " " << tm2.tm_mday << " "
       << tm2.tm_hour << endl;

我们在执行之前先看一下时间
image.png
执行结果如下:
image.png
我们发现 正如所验证的一样,localtimegmtime快了八个小时

strftime

按照输入的格式,输出时间

 size_t strftime (char *__restrict __s, size_t __maxsize,
			const char *__restrict __format,
			const struct tm *__restrict __tp)

参数:

  • __s:输出字符串的指针
  • __maxsize:输出字符串的大小
  • __format:输出到输出字符串的时间的格式 详情见:man 2 strftime
  • __tp:上面获取的时间结构体

输出:
输出到__s字符串中 的字符的数量

相关推荐

  1. linux系统调用介绍

    2024-03-18 04:16:05       40 阅读
  2. Linux 系统调用

    2024-03-18 04:16:05       12 阅读
  3. Linux系统调用mmap

    2024-03-18 04:16:05       11 阅读
  4. OpenHarmony—Linux系统调用

    2024-03-18 04:16:05       29 阅读
  5. 如何调整服务器系统时间

    2024-03-18 04:16:05       28 阅读
  6. 如何调整服务器系统时间

    2024-03-18 04:16:05       20 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-18 04:16:05       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-18 04:16:05       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-18 04:16:05       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-18 04:16:05       20 阅读

热门阅读

  1. 客户端渲染与服务端渲染

    2024-03-18 04:16:05       23 阅读
  2. 深入了解Android垃圾回收机制

    2024-03-18 04:16:05       27 阅读
  3. 从零开始的LeetCode刷题日记:541. 反转字符串II

    2024-03-18 04:16:05       23 阅读
  4. 如何解决接口幂等的问题?

    2024-03-18 04:16:05       25 阅读
  5. SpringSecurity

    2024-03-18 04:16:05       20 阅读
  6. Docker 新建网络实现容器间通信

    2024-03-18 04:16:05       20 阅读
  7. 音视频实战--自定义输入输出IO

    2024-03-18 04:16:05       19 阅读