😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
🤣本文内容🤣:🍭介绍Linux 系统编程的时间获取、设置、转换 🍭
😎金句分享😎:🍭你不能选择最好的,但最好的会来选择你——泰戈尔🍭
本文未经允许,不得转发!!!
目录
🎄一、概述
在Linux系统编程中,经常需要用到一些与时间相关的函数,本文总结了Linux系统编程与时间相关的函数与使用例子。
本文注意内容如下:
- 结构体timeval、timespec、tm
- 时间获取、设置 | time、gettimeofday、settimeofday
- 时间转换函数 | gmtime、localtime、mktime、ctime、asctime
- 格式化日期和时间 | strftime
🎄二、结构体timeval、timespec、tm
本文先介绍Linux时间函数会用到的一些结构体和类型。主要有:time_t、suseconds_t、struct timeval、struct timespec、struct tm、struct timezone
,其中 struct timezone
已经不使用了。这些类型定义如下:
1秒=1000毫秒=1000000微秒=1000000000纳秒
typedef long time_t;
typedef long suseconds_t;
struct timeval {
time_t tv_sec; // seconds
suseconds_t tv_usec; // microseconds-微秒
};
typedef struct timespec {
time_t tv_sec; // seconds
long tv_nsec; // nanoseconds-纳秒
}
struct timezone {
int tz_minuteswest; // minutes west of Greenwich
int tz_dsttime; // type of DST correction
};
struct tm {
int tm_sec; // seconds
int tm_min; // minutes
int tm_hour; // hours
int tm_mday; // day of the month
int tm_mon; // month
int tm_year; // year
int tm_wday; // day of the week
int tm_yday; // day in the year
int tm_isdst; // daylight saving time
};
🎄三、时间获取、设置 | time、gettimeofday、settimeofday
✨3.1 time 函数
函数原型:
#include <time.h>
time_t time(time_t *tloc);
函数功能:time 函数返回自纪元时间(1970-01-01 00:00:00+0000(UTC))以来的秒数,如果参数tloc
不是NULL
,则返回值也存储在tloc
指向的内存中。
返回值:成功返回UTC时间,精确到秒;失败返回(time_t)-1
。
/*
* time函数:time返回自纪元时间(1970-01-01 00:00:00+0000(UTC))以来的秒数。如果t不是NULL,则返回值也存储在t指向的内存中。
* 返回值:typedef long time_t; 成功返回UTC时间,精确到秒;失败返回(time_t)-1
*/
#include <stdio.h>
#include <time.h>
int main()
{
time_t seconds = time((time_t*)NULL);
printf("%ld\n", seconds);
return 0;
}
✨3.2 gettimeofday 函数
函数原型:
#include <sys/time.h>
int gettimeofday(struct timeval *tv, struct timezone *tz);
函数功能:gettimeofday 函数通过第一个参数(struct timeval)返回自纪元时间(1970-01-01 00:00:00+0000(UTC
))以来的秒数、微秒数。第二个参数是时区结构体(struct timezone),已经过时了,tz
参数通常应指定为NULL
。
返回值:成功返回0;失败返回-1,并设置errno。
例子:
/*
* gettimeofday:
通过第一个参数(struct timeval)返回自纪元时间(1970-01-01 00:00:00+0000(UTC))以来的秒数微秒数。
第二个参数是时区结构体(struct timezone),已经过时了,tz参数通常应指定为NULL。
* 返回值:成功返回0;失败返回-1,并设置errno
typedef long time_t;
typedef long suseconds_t;
struct timeval {
time_t tv_sec; // seconds
suseconds_t tv_usec; // microseconds
};
struct timezone {
int tz_minuteswest; // minutes west of Greenwich
int tz_dsttime; // type of DST correction
};
*/
#include<sys/time.h>
#include<stdio.h>
int main()
{
struct timeval tv;
//struct timezone tz;
//gettimeofday (&tv , &tz);
gettimeofday (&tv , NULL);
printf("tv.sec = %ld, tv.usec = %ld\n",tv.tv_sec, tv.tv_usec);
// printf("tz.minuteswest = %d, tz.tz_dsttime = %d\n",tz.tz_minuteswest, tz.tz_dsttime);
return 0;
}
✨3.3 settimeofday 函数
函数原型:
#include <sys/time.h>
int settimeofday(const struct timeval *tv, const struct timezone *tz);
函数功能:settimeofday 函数设置自纪元时间(1970-01-01 00:00:00+0000(UTC
))以来的秒数、微秒数。
返回值:成功返回0;失败返回-1,并设置errno。
🎄四、时间转换函数 | gmtime、localtime、mktime、ctime、asctime
✨4.1 gmtime、localtime 函数
函数原型:
#include <time.h>
struct tm *gmtime(const time_t *timep);
struct tm *localtime(const time_t *timep);
函数功能:这两个函数都是将time_t *
表示的秒数,转换为struct tm *
类型的时间。唯一的区别是:localtime
将日历时间转换成本地时间(考虑到本地时区和夏时制标志),而gmtime
则将日历时间转换成国际标准时间的年、月、日、时、分、秒、周日。
返回值:成功返回指向struct tm
的指针。返回值指向一个静态分配的结构,该结构可能会被任何日期和时间函数的后续调用所覆盖。
✨4.2 mktime 函数
函数原型:
#include <time.h>
time_t mktime(struct tm *tm);
函数功能:mktime
函数将分解的时间结构(表示为本地时间)转换为日历时间表示。该函数将忽略调用方在tm_wday
和tm_yday
字段中提供的值。tm_isdst
字段中指定的值通知mktime()
夏令时(DST)对于tm
结构中提供的时间是否有效:正值表示夏令时有效;零表示夏令时无效;负值意味着mktime()
应该(使用时区信息和系统数据库)尝试确定DST在指定时间是否有效。
返回值:返回自纪元时间(1970-01-01 00:00:00+0000(UTC))以来的秒数;失败返回(time_t)-1
。
✨4.3 ctime、asctime 函数
函数原型:
#include <time.h>
char *ctime(const time_t *timep);
char *asctime(const struct tm *tm);
函数功能:ctime
函数timep
指向的秒数转换为以null
结尾的字符串。asctime
函数将分解的时间值tm
转换为以null
结尾的字符串,其格式与ctime
相同。返回值指向一个静态分配的字符串,该字符串可能会被任何日期和时间函数的后续调用所覆盖。
返回值:成功返回指向char *
的字符串,返回的字符串末尾带有换行符。
综合上面几个函数的例子:
/*
struct tm {
int tm_sec; // seconds
int tm_min; // minutes
int tm_hour; // hours
int tm_mday; // day of the month
int tm_mon; // month
int tm_year; // year
int tm_wday; // day of the week
int tm_yday; // day in the year
int tm_isdst; // daylight saving time
};
*/
#include <stdio.h>
#include <time.h>
int main()
{
char *wday[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
time_t timep = time((time_t*)NULL);
printf("%ld\n", timep);
// gmtime
struct tm* gmTime = gmtime(&timep);
printf("gmtime : %04d-%02d-%02d %02d:%02d:%02d %s\n",1900+gmTime->tm_year, 1+gmTime->tm_mon, gmTime->tm_mday,
gmTime->tm_hour ,gmTime->tm_min ,gmTime->tm_sec, wday[gmTime->tm_wday]);
// localtime
struct tm* localTime = localtime(&timep);
printf("localTime: %04d-%02d-%02d %02d:%02d:%02d %s\n",1900+localTime->tm_year, 1+localTime->tm_mon, localTime->tm_mday,
localTime->tm_hour ,localTime->tm_min ,localTime->tm_sec, wday[localTime->tm_wday]);
// mktime
printf("gmtimeSec=%ld, localtimeSec=%ld\n",mktime(gmTime), mktime(localTime));
// ctime
printf("ctime=%s\n", ctime(&timep));
// asctime
printf("asctimeGm=%s asctimeLocal=%s\n", asctime(gmTime), asctime(localTime));
return 0;
}
注意:如果是多线程编程可以使用下面线程安全的函数代替上面几个函数:
#include <time.h>
char *asctime_r(const struct tm *tm, char *buf);
char *ctime_r(const time_t *timep, char *buf);
struct tm *gmtime_r(const time_t *timep, struct tm *result);
struct tm *localtime_r(const time_t *timep, struct tm *result);
🎄五、格式化日期和时间 | strftime
函数原型:
#include <time.h>
size_t strftime(char *s, size_t max, const char *format,
const struct tm *tm);
函数功能:strftime 函数根据格式规范格式对分解时间tm进行格式化,并将结果放入大小最大的字符数组s中。
返回值:如果结果字符串(包括终止的空字节)不超过最大字节数,strftime()将返回数组s中的字节数(不包括终止的零字节)。请注意,返回值0并不一定表示错误。例如,在许多区域设置中,%p会产生一个空字符串。一个空的格式字符串同样会产生一个空字符串。
格式 | 说明 | 实例 |
---|---|---|
%a | 缩写的周日名 | Tue |
%A | 全周日名 | Tuesday |
%b | 缩写的月名 | Feb |
%B | 全月名 | February |
%c | 日期和时间 | Tue Feb 10 18:27:38 2004 |
%C | 年/100:[00~99] | 20 |
%d | 月日:[01 ~31] | 10 |
%D | 日期[MM/DD/YY] | 02/10/04 |
%e | 月日(一位数前加空格):[1~31] | 10 |
%F | ISO 8601日期格式[YYYY-MM-DD] | 2004-02-10 |
%g | ISO 8601基于周的年的最后2位数[00~99] | 04 |
%G | ISO 8601基于周的年 | 2004 |
%h | 与%b相同 | Feb |
%H | 小时〔24时制):[00~23] | 18 |
%I | 小时((12时制):[01~12] | 06 |
%j | 年日:[001 ~366] | 041 |
%m | 月:[01~12] | 02 |
%M | 分:[00~59] | 27 |
%n | 换行符 | |
%p | AM/PM | PM |
%r | 本地时间:(12时制) | 06:27 :38 PM |
%R | 与“%H:%M”相同 | 18:27 |
%s | 秒:[O0~60] | 38 |
%t | 水平制表符 | |
%T | 与“%H:%M:%S”相同 | 18:27:38 |
%u | ISO 8601周日[Monday=1,1~7] | 2 |
%U | 星期日周数:[00~53] | 06 |
%V | ISO 8601周数:[01~53] | 07 |
%w | 周日:[O=Sunday, 06] | 2 |
%W | 星期一周数:[00~53] | 06 |
%x | 日期 | 02/10/04 |
%X | 时间 | 18: 27 : 38 |
%y | 年的最后两位数:[00~99] | 04 |
%Y | 年 | 2004 |
%z | ISO 8601格式的UTC偏移量 | -0500 |
%Z | 时区名 | EST |
%% | 转换为1个% | % |
例子:
#include <stdio.h>
#include <time.h>
int main(void)
{
char buff[128];
time_t timep = time(NULL);
struct tm *localTime = localtime(&timep);
if (strftime(buff, sizeof buff, "%A %c", localTime)) {
printf("strftime: %s\n",buff);
} else {
printf("strftime failed\n");
}
return 0;
}
🎄六、总结
本文主要介绍Linux系统时间编程相关的几个函数及其使用例子:时间获取、设置、转换 | time、gettimeofday、gmtime、localtime、mktime、ctime、asctime、strftime。
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁
参考资料:
https://blog.csdn.net/baidu_35692628/article/details/124231648
《unix环境高级编程》第二版