- 日历时间 Calendar Time
UTC,格林威治标准时间,GMT这三个名词基本可以认为是等同的
Epoch是指UTC的1970年1月1日零点,这个时间是UNIX系统问世的大致日期
UNIX系统内部对时间的表示方式均是自Epoch以来的秒数来度量的
日历时间存储在类型为time_t的变量中
获取日历时间:
#include <sys/time.h> int gettimeofday(struct timeval *tv, struct timezone *tz);
timeval定义如下:
struct timeval { time_t tv_sec; /* seconds */ suseconds_t tv_usec; /* microseconds */ };
其中,tz是一个历史产物,目前已遭废弃,应始终将其置为NULL
time函数返回自Epoch以来的秒数:
#include <time.h> time_t time(time_t *tloc);
这个函数,除了返回值是秒数,其参数也是秒数、指示指向一个指针缓存区,常设置参数为空、按照以下方式使用:
t = time(NULL)
- 时间转换函数
time_t转换为可打印格式:
#include <time.h> char *ctime(const time_t *timep);
把一个指向time_t的指针作为参数,返回一个26字节的字符串,内涵标准格式的日期和时间,包含换行符和终止字节(\0)各一,此函数会结合本地时区和DST输出结果,返回的字符串静态分配、被下次ctime会覆盖
ctime gmtime localtime asctime这几个函数的返回结果会互相覆盖
time_t和分解时间之间的转换
#include <time.h> struct tm *gmtime(const time_t *timep); struct tm *localtime(const time_t *timep);
gmtime将日历时间转化为对应的UTC的分解时间,localtime则会综合考虑当地时间和DST的影响,返回系统本地时间的一个分解时间。tm结构体定义:
struct tm { int tm_sec; /* Seconds (0-60) */ int tm_min; /* Minutes (0-59) */ int tm_hour; /* Hours (0-23) */ int tm_mday; /* Day of the month (1-31) */ int tm_mon; /* Month (0-11) */ int tm_year; /* Year - 1900 */ int tm_wday; /* Day of the week (0-6, Sunday = 0) */ int tm_yday; /* Day in the year (0-365, 1 Jan = 0) */ int tm_isdst; /* Daylight saving time */ };
mktime()将一个本地区的分解时间翻译为time_t值,并将其作为函数结果返回
#include <time.h> time_t mktime(struct tm *tm);
asctime()提供分解时间到打印格式的转换:
#include <time.h> char *asctime(const struct tm *tm);
本地时区对asctime没有影响,因为其参数分解时间里已经包含了本地时间的处理了
另一个分解时间到打印格式的转换函数:
#include <time.h> size_t strftime(char *s, size_t max, const char *format, const struct tm *tm);
其中,tm只想分解时间,则一个以null结尾的打印格式时间放在 s中(没有换行符),max指定s的最大长度,不包括终止空字节,若结果字符串的总长度(包含终止空字节)超过了maxsize参数指定大小,则strftime()会返回0表示出错。成功时会返回 s所指缓冲区的字节长度。而format是一个字符串,这个参数有许多选项,可用于规定 s中一些时间表示的格式。
打印格式时间转换为分解时间
#define _XOPEN_SOURCE /* See feature_test_macros(7) */ #include <time.h> char *strptime(const char *s, const char *format, struct tm *tm);
这个相当于strftime()的逆向函数,按照 format参数的格式要求,去解析由日期和时间组成的字符串 s,最后放在 tm指向的结构体中
若成功,strptime()返回一指针,指向 str中下一个未经处理的字符(这是当字符串里有一些额外信息时派上用场的),若整个 s字符串都无法正常识别,strptime()返回NULL
- 时区
系统的本地时间由失去文件 /etc/localtime定义,通常链接到 /usr/share/zoneinfo 下的一个文件
设定时区是通过给TZ环境变量设置为由一冒号(:)和时区名称组成的字符串,其中时区名称定义域 /usr/share/zoneinfo中,可以用tzselect指令来逐级查询时间路径
- 地区
每个地区使用的数字、货币、日期和时间之类的信息时,相关的表达书写格式有差异 —— locale的定义为:用户环境中依赖于语言和文化习俗的一个子集
地区信息维护在 /usr/share/local 路径,每个地区目录下的子目录又包括几个文件,其中描述不同类别的一些信息设置,如下表:
为程序设置地区:
#include <locale.h> char *setlocale(int category, const char *locale);
setlocale()可设置也可查询程序的当前地区,category参数选择设置或查询地区的那一部分,使用上面表格列出的类别的常量名称,常用 LC_ALL 来指定我们要设置的地区的所有部分的值
locale参数可能是一个字符串,指定系统上已定义的一个地区(如 de_DE,en_US)
若 locale 为空字符串,则从环境变量取得地区的设置:
setLocale(LC_ALL, "")
除了LC_ALL,LANG也可以指定当前地区的所有部分的值,指示LANG优先级是最低的、LC_ALL优先级最高能够覆盖之前设置的所有内容设置的值,因此,若要指定某一地区某方面内容,可以先用LANG设置使用地区所有方面的内容默认值,然后再用具体的LC_*来定义具体需要使用的某地区的某内容定义
setLocale()返回一个指针指向表示这一类地区设置的字符串,如果我们是为了查看当前的地区设置,则可以指定locale参数为NULL
shell中可以使用 locale 指令查询当前shell内的地区环境相关信息, locale -a列出系统上定义的整套地区
- 更新系统时钟
两个更新系统时钟的接口:settimeofday()和adjtime()。
这俩接口实际很少使用,因为更新系统时间通常是由工具软件维护的
#include <sys/time.h> int settimeofday(const struct timeval *tv, const struct timezone *tz);
参数 tz已被废弃,这个函数会造成系统时间的突然变化,可能会造成有害影响
推荐使用adjtime(),它将系统时钟逐步调整到正确时间
#include <sys/time.h> int adjtime(const struct timeval *delta, struct timeval *olddelta);
delta参数指向一个 结构体,指定需要改变的秒和微秒数,可以是整数或负数,系统时钟会根据此值快一点或慢一点逐渐调节。
adjtime执行的时间里可能无法完成所有的时间调节,所以将它剩余时间放在 olddelta里。
只将 delta设置为NULL则只关注当前未完成的时间校正信息,只将 olddelta设置为NULL则不关心剩余未完成时间校正信息。
- 进程时间
进程时间是进程创建后使用的CPU时间数量,分为两部分:
用户CPU时间:用户模式下执行所花费的时间数量
系统CPU时间:在内核模式中执行所花费的时间数量
调用shell指令或shell中调用程序时,可以使用time 命令来获得相关进程时间:
系统调用 times() ,检索进程时间信息,结果返回到 buf指向的结构体里:
#include <sys/times.h> clock_t times(struct tms *buf);
struct tms { clock_t tms_utime; /* user time */ clock_t tms_stime; /* system time */ clock_t tms_cutime; /* user time of children */ clock_t tms_cstime; /* system time of children */ };
返回值是“相对于某一点流逝的以时钟计时单元为单位的时间”,一般就是两个times结果做差用,不过有可能会有clock_t溢出的情况,所以做差也不一定准确,用gettimeofday()去计算更好些
函数 clock()提供了一个简单的接口用于取得进程时间,它返回一个值描述了调用进程使用的总的CPU时间(用户时间+系统时间):
#include <time.h> clock_t clock(void);
注意这times()和clock()各有一个时间单位,看以下代码是如何将函数返回值换算成秒数的:
static void /* Display 'msg' and process times */ displayProcessTimes(const char *msg) { struct tms t; clock_t clockTime; static long clockTicks = 0; if (msg != NULL) printf("%s", msg); if (clockTicks == 0) { /* Fetch clock ticks on first call */ clockTicks = sysconf(_SC_CLK_TCK); if (clockTicks == -1) errExit("sysconf"); } clockTime = clock(); if (clockTime == -1) errExit("clock"); printf(" clock() returns: %ld clocks-per-sec (%.2f secs)\n", (long) clockTime, (double) clockTime / CLOCKS_PER_SEC); if (times(&t) == -1) errExit("times"); printf(" times() yields: user CPU=%.2f; system CPU: %.2f\n", (double) t.tms_utime / clockTicks, (double) t.tms_stime / clockTicks); }
来源:https://www.cnblogs.com/zsd0101/p/12232114.html