Linux c运行库中时间的相关函数(一)

一、几个重要概念

秒是一个时间基本单位。一天24小时,一小时60分,一分钟60秒,这来自于秒的定义——1秒的时间间隔为平均太阳日的1⁄86400。到了20世纪中叶,人们发现地球自转的时间并不是恒定的,于是在1956年改以地球绕太阳轨道公转一周的时间来定义秒。1967年,改用原子共振频率来定义秒,并在此基础上制作出了原子钟。目前,原子钟是世界上已知最准确的时间测量和频率标准。

GMT时间

格林尼治平均时(Greenwich Mean Time, GMT),又称为格林尼治标准时间。格林尼治平均时的正午是指当平太阳横穿格林尼治子午线时(也就是在格林尼治上空最高点时)的时间。自1924年2月5日开始,格林尼治天文台负责每隔一小时向全世界发放调时信息。由于地球每天的自转是有些不规则的,而且正在缓慢减速,因此格林尼治平均时基于天文观测本身的缺陷,已经被原子钟报时的协调世界时(UTC)所取代。

UT时间

世界时(Universal Time, UT),是一种以格林尼治子夜起算的平太阳时。

由于1925年以前人们在天文观测中,常常把每天的起始(0时)定为正午,而不是通常民用的午夜,给格林尼治平时的意义造成含糊,人们使用世界时一词来明确表示每天从午夜开始的格林尼治平时。

UTC时间

协调世界时(Coordinated Universal Time)。是主要的世界时间标准,以原子钟所定义的秒长为基础,在时刻上尽量接近GMT时间。UTC时间认为一个太阳日总是86400秒。在大多数情况下,UTC时间能与GMT时间互换。

闰秒

闰秒是在协调世界时(UTC)中增加或减少一秒,使得UTC时与原子时之间的差不超过0.9秒。需要闰秒的部分原因是因为一个太阳日并不总是86400秒。当要增加正闰秒时,这一秒是增加在第二天的00:00:00之前,效果是延缓UTC第二天的开始。当天23:59:59的下一秒被记为23:59:60,然后才是第二天的00:00:00。如果是负闰秒的话,23:59:58的下一秒就是第二天的00:00:00了,但目前还没有负闰秒调整的需求。最近的一次添加闰秒是在2016年12月31日23:59:60。

UNIX时间

UNIX时间,或称POSIX时间是UNIX或类UNIX系统使用的时间表示方式。一般定义为从协调世界时(UTC时间)1970年1月1日0时0分0秒起至现在的总秒数(不考虑闰秒)。

时区

时区是指地球上的某一个区域使用同一个时间定义。GMT时间或者UT时间,都是表示地球自转速率的一种形式。从太阳升起到太阳落下,时刻从0到24变化。这样,不同经度的地方时间自然会不相同。为了解决这个问题,人们把地球按经度划分为不同的区域,每个区域内使用同一个时间定义,相邻的区域时间差为1个小时。时区又分为理论时区和法定时区:1)理论时区按经度,每15°为一个时区,将地球划分为24个时区,以本初子午线为中心,向东西两侧各延伸7.5°的区域为0时区;2)法定时区是在理论时区的基础上,根据某些地区的国界线做了调整之后的时区,为实际使用的时区。例如中国横跨东五区到东九区五个时区,但统一使用东八区时间(北京时间)。

时区划分可查看:https://www.timeanddate.com/time/zones/

夏令时

夏时制,夏时令(Daylight Saving Time, DST),又称“日光节约时制”和“夏令时间”,是一种为节约能源而人为规定地方时间的制度,在这一制度实行期间所采用的统一时间称为“夏令时间”。一般在天亮早的夏季人为将时间调快一小时,可以使人早起早睡,减少照明量,以充分利用光照资源,从而节约照明用电。各个采纳夏时制的国家具体规定不同。目前全世界有近110个国家每年要实行夏令时。我国曾采用了6年(1986-1991)夏时制,但是由于我国将多个理论时区统一为东八区,因此新疆等天亮的较晚的地区并不能起到节约能源的作用,加上我国民众科学素养普遍不高,导致了更多的混乱,因此从1992年起暂停实行夏令时。

本地时间

所在时区的时间(LocalTime, LT)。UTC与LT的换算关系如下:

本地时间=UTC标准时间 + 时区偏移(时区差 + [夏令时(1小时)])

注:

1)时区差东为正,西为负

2)夏令时需根据当地政策是否实行和当前时间是否处于夏令时共同决定

例如:UTC时间2020-01-03 07:30:00 UTC; UTC+0800(北京)2020-01-03 15:30:00 +8000; UTC-0500(纽约)2020-01-03 02:30:00 -0500; UTC+0530(印度)2020-01-03 13:00:00 +0530, UTC+1000(堪培拉)2020-01-03 18:30:00 +1000(处于夏令时)

CST时间

CST(时区缩写)时间可视为四个时区的标准时间,分别是:1) Central Standard Time (USA) UT-6:00(美国中部时间); 2) Central Standard Time (Australia) UT+9:30(澳大利亚中部时间); 3) China Standard Time UT+8:00(中国标准时间); 4) Cuba Standard Time UT-4:00(古巴标准时间)。

以上内容参考

1)https://www.cnblogs.com/xieyong-p/p/9062358.html

2)https://www.cnblogs.com/pipci/p/8377680.html

二、几个重要结构体

1. struct tm

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

};

2. time_t

typedef long int time_t;      /* time_t为长整型的别名*/

3. struct timeval

struct timeval

{

  time_t tv_sec; /* Seconds.  */

  long tv_usec; /* Microseconds.  */

};

4. struct timezone

struct timezone

{

    int tz_minuteswest; /* Minutes west of GMT.  */

    int tz_dsttime; /* Nonzero if DST is ever in effect.  */

};

5. struct timespec

struct timespec

{

  time_t tv_sec; /* Seconds.  */

  long tv_nsec; /* Nanoseconds.  */

};

三、几个常见函数

1. time_t time(time_t *timer)

头文件:#include <time.h>

说明:该函数返回自纪元 Epoch(1970-01-01 00:00:00 UTC)起经过的时间(当前日历时间,Calendar Time),以秒为单位。如果timer不为空,则返回值也存储在timer指向的内存中。

返回值:成功返回正确秒数,失败返回-1

示例:

#include <time.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
	time_t now;
	// 方法一
	now = time(NULL);
	printf("now time: %s\n", ctime(&now));
	// 方法二
	time(&now);
	printf("now time: %s\n", ctime(&now));
	return 0;
}

运行结果:

2. char *asctime(const struct tm *tp)

头文件:#include <time.h>

说明:该函数可以把tp指向的tm结构体中储存的时间转换为字符串(25个字符)。返回的字符串格式为:Www Mmm dd hh:mm:ss yyyy,其中Www为星期,Mmm是以字母表示的月份,dd为日,hh为时,mm为分,ss为秒,yyyy为年份。

返回值:返回一个C字符串,该字符串包含了可读格式的日期和时间信息

示例:

#include <time.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
	struct tm timeinfo;

	timeinfo.tm_sec    = 0;
	timeinfo.tm_min    = 0;
	timeinfo.tm_hour   = 0;
	timeinfo.tm_mday   = 0;
	timeinfo.tm_mon    = 0;
	timeinfo.tm_year   = 2020-1900;
	timeinfo.tm_wday   = 0;
	printf("The date and time is: %s\n", asctime(&timeinfo));
	return 0;
}

运行结果:

3. char *asctime_r(const struct tm *tp, char *buf)

说明:功能和asctime相同,只是增加了将结果存储在buf指向的缓冲区中(至少包含26个字节)

4. char *ctime(const time_t *t)

头文件:#include <time.h>

说明:该函数以原始时间值为参数,并将其转换为一个更易读的本地时间字符串。原始时间是指以格林尼治时间(GMT)1970年1月1日午夜(0点)为纪元,到现在为止的秒数;返回的字符串格式如下: Www Mmm dd hh:mm:ss yyyy,其中Www 为星期,Mmm是以字母表示的月份,dd 为日,hh为时,mm为分,ss为秒,yyyy为年份。

返回值:返回一个C字符串,该字符串包含了可读格式的日期和时间信息

示例:

#include <time.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
	time_t timer = 0;
	setenv("TZ", "GMT0", 1); // 该函数设置的环境变量只在本进程有效
	printf("The time is: %s\n", ctime(&timer));
	setenv("TZ", "GMT-8", 1);
	printf("The time is: %s\n", ctime(&timer));
	return 0;
}

运行结果:

注:转换为本地时间字符串后,增加了8个小时(北京时间)。

5. char *ctime_r(const time_t *timer, char *buf)

说明:功能和ctime相同,只是增加了将结果存储在buf指向的缓冲区中(至少包含26个字节)

6. time_t mktime(struct tm *tp)

头文件:#include <time.h>

说明:该函数的作用是将本地时间(struct tm)转换为自1970年1月1日0时0分0 秒算起至今所经过的秒数(time_t)。该转换与struct tm中的tm_wday、tm_yday无关,仅用tm_mday决定日期,若struct tm中的成员是非法的,该函数会自动校正,如2019-12-32 00:00:00,矫正后为2020-01-01 00:00:00。转换后的时间会扣除时区和夏令时偏移,转换成功的同时会改变tp所指向的值

返回值:成功返回经过的秒数,失败返回-1

示例:

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
	time_t t;
	struct tm timeinfo;

	setenv("TZ", "GMT-8", 1);
	timeinfo.tm_sec    = 0;
	timeinfo.tm_min    = 0;
	timeinfo.tm_hour   = 0;
	timeinfo.tm_mday   = 1;
	timeinfo.tm_mon    = 0;
	timeinfo.tm_year   = 2020-1900;
	timeinfo.tm_wday   = 0;
	t = mktime(&timeinfo);
	printf("The time is %s\n", asctime(gmtime(&t)));

	setenv("TZ", "GMT+0", 1);
	timeinfo.tm_sec    = 0;
	timeinfo.tm_min    = 0;
	timeinfo.tm_hour   = 0;
	timeinfo.tm_mday   = 1;
	timeinfo.tm_mon    = 0;
	timeinfo.tm_year   = 2020-1900;
	timeinfo.tm_wday   = 0;
	t = mktime(&timeinfo);
	printf("The time is %s\n", asctime(gmtime(&t)));
}

运行结果:

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值