Linux获取时间

Linux获取时间

一、获取时间

1.1 获取秒、微秒

Linux中获取微秒级时间的系统调用gettimeofday(),但是返回值的准确性依赖于系统的架构。

text
1
2
3
#include <sys/time.h>
/* 在tz指向的缓冲区中返回日历时间;Linux不支持tz参数,设置为NULL */
int gettimeofday(struct timeval *tv, struct timezone *tz);

其中timeval结构体定义如下

text
1
2
3
4
struct timeval {
   time_t tv_sec;  /* 从1970年1月1日00:00:00以来的秒数(long) */
   suseconds_t tv_usec; /* 附加的微秒(long int) */
}

time()系统调用返回自Epoch( 1970年1月1日00:00:00 )以来的秒数,如果p_time参数不为空,则会将返回值置于p_time指向的位置。

text
1
2
#include <time.h>
time_t time(time_t *p_time);

二、时间转换

2.1 time_t和可打印的格式

ctime()提供了一种简单的将时间转成字符串格式的转换方式。

text
1
2
3
4
#include <time.h>
char *ctime(const time_t *p_time); // 返回的字符串包括终止空字符和换行符
// output eg : Wed Jun 8 14:22:34 2012
// 返回的字符串是静态分配的,下次调用会覆盖

注:在SUSv3规定,调用ctime()gmtime()localTime()asctime()中的任一个函数,都可能覆盖其它函数的返回

2.2 time_t和分解的格式

gmtime()可以把日历时间转换成一个对应UTC的分解的时间;localTime()考虑时区和夏令时的设置,返回对应系统本地时间的分解时间

text
1
2
3
4
5
6
7
#include <time.h>
struct tm *gmtime(const time_t *p_time);
struct tm *localTime(const time_t *p_time);

// 可重入版本
struct tm *gmtime_r(const time_t *p_time);
struct tm *localTime_r(const time_t *p_time);
text
1
2
3
4
5
6
7
8
9
10
11
12
// 分解时间结构体
struct tm {
   int    tm_sec;   /* seconds [0,61] */
   int    tm_min;   /* minutes [0,59] */
   int    tm_hour;  /* hour [0,23] */
   int    tm_mday;  /* day of month [1,31] */
   int    tm_mon;   /* month of year [0,11] */
   int    tm_year;  /* years since 1900 */
   int    tm_wday;  /* day of week [0,6] (Sunday = 0) */
   int    tm_yday;  /* day of year [0,365] */
   int    tm_isdst; /* daylight savings flag */
};

2.3 分解的格式与可打印格式

asctime()将分解的格式转换成可打印的格式,指向由静态分配的字符串

text
1
2
3
4
5
#include <time.h>
char *asctime(const struct tm *timeptr);

// 可重入版本
char *asctime_r(const struct tm *timeptr);

strftime()在将分解的时间转换成可打印的格式时提供更为精确的控制。

text
1
2
3
4
5
#include <time.h>
size_t strftime(char *out_str, size_t max_size, const char *format, const struct tm *timeptr);

// strftime不会自动添加换行符
// out_str会按照format做格式化

format参数定义:

说明符 描述 实例
%a 星期几的缩写 Tue
%A 星期几的全称 Tuesday
%b 月份名称的缩写 Feb
%B 月份全称 February
%c 日期和时间 Tue Feb 1 21:39:46 2011
%d 一月中的一天(两位数字,01-31) 01
%D 美国日期的格式(同%m%d%y) 02/01/2011
%e 一月中的一天(两个字符) 1
%F ISO格式的日期(%Y-%m-%d) 2011-02-01
%H 24 小时格式的小时(两位数,00-23) 21
%I 12 小时格式的小时(两位数,01-12) 09
%j 一年中的第几天(三位数,001-366) 032
%m 十进制数表示的月份(两位,01-12) 08
%M 分(两位,00-59) 55
%p AM 或 PM 名称 PM
%P 上午/下午(GNU扩展) pm
%R 24小时制的时间(%H:%M) 21:39
%S 秒(00-61) 46
%T 时间(%H:%M:%S) 21:39:46
%u 星期几编号(1-7) 2
%U 一年中的第几周,以第一个星期日作为第一周的第一天(00-53) 05
%w 十进制数表示的星期几,星期日表示为 0(0-6) 2
%W 一年中的第几周,以第一个星期一作为第一周的第一天(00-53) 05
%x 日期表示法(本地化) 02/01/2011
%X 时间表示法(本地化) 21:39:46
%y 两位数字年份,最后两个数字(00-99) 11
%Y 四位数字年份 2011
%Z 时区的名称或缩写 CET
%% 一个 % 符号 %

strptime()strftime()的逆向函数,将包含日期的字符串转换成分解的时间

text
1
2
3
4
#define _XOPNE_SOURCE
#include <time.h>

char *strptime(const char *str, const char *format, struct tm *time_ptr);

转换图

下图来自Linux/Unix系统编程手册

时间转换