TLPI-Chapter 10 时间
2017-10-24 00:10
295 查看
日历时间Calendat Time
UNIX系统内部对时间的表示均是以自1970年1月1日的零点以来的秒数来度量。日历时间存储与类型time_t的变量中,此类型是由SUSv3定义的整数类型。系统调用gettimeofday(),可于tv指向的缓冲区中返回日历时间。
#include <sys/time.h> int gettimeofday(struct timeval *tv, struct timezone *tz); Returns 0 on success, or –1 on error 参数tv是指向如下数据结构的一个指针: struct timeval { __kernel_time_t tv_sec; /* seconds */ __kernel_suseconds_t tv_usec; /* microseconds */ };
在现代X86-32系统上,gettimeofday()可以提供微妙级的准确度。
time函数基于gettimeofday实现,time精度秒级,gettimeofday可以达到微妙。
#include <time.h> time_t time(time_t *timep); Returns number of seconds since the Epoch,or (time_t) –1 on error
时间转换函数
将time_t转换为可打印格式
#include <time.h> char *ctime(const time_t *timep)
ctime返回的字符串经由静态分配,下一次对ctime()的调用会将其覆盖。
函数gmtime()和localtime()可将time_t类型转换为一个所谓的分解时间。分解时间置于一个经由静态分配的结构中,其地址则作为函数结果返回。
函数gmtime()能够把日历时间转换为一个对应于UTC的分解时间。
函数localtime()需要考虑时区和夏令时设置,返回对应于系统本地时间的一个分解时间。
#include<time.h> struct tm *localtime(const time_t * timep); struct tm *gmtime(const time_t *timep);
函数mktime()将一个本地时区的分解时间转换为time_t,并将结果返回。
函数asctime()则从分解时间转换为打印时间。
char *asctime(const struct tm *timeptr);
在参数tm中提取一个指向分解时间结构的指针,asctime()则会返回一指针,指向经由静态分配的字符串,内含时间,格式则与ctime()相同。
/*************************************************************************\ * Copyright (C) Michael Kerrisk, 2015. * * * * This program is free software. You may use, modify, and redistribute it * * under the terms of the GNU General Public License as published by the * * Free Software Foundation, either version 3 or (at your option) any * * later version. This program is distributed without any warranty. See * * the file COPYING.gpl-v3 for details. * \*************************************************************************/ /* Listing 10-1 */ /* calendar_time.c Demonstrate the use of functions for working with calendar time. This program retrieves the current time and displays it in various forms. */ #include <locale.h> #include <time.h> #include <sys/time.h> #include "tlpi_hdr.h" #define SECONDS_IN_TROPICAL_YEAR (365.24219 * 24 * 60 * 60) int main(int argc, char *argv[]) { time_t t; struct tm *gmp, *locp; struct tm gm, loc; struct timeval tv; /* Retrieve time, convert and display it in various forms */ t = time(NULL); printf("Seconds since the Epoch (1 Jan 1970): %ld", (long) t); printf(" (about %6.3f years)\n", t / SECONDS_IN_TROPICAL_YEAR); if (gettimeofday(&tv, NULL) == -1) errExit("gettimeofday"); printf(" gettimeofday() returned %ld secs, %ld microsecs\n", (long) tv.tv_sec, (long) tv.tv_usec); gmp = gmtime(&t); if (gmp == NULL) errExit("gmtime"); gm = *gmp; /* Save local copy, since *gmp may be modified by asctime() or gmtime() */ printf("Broken down by gmtime():\n"); printf(" year=%d mon=%d mday=%d hour=%d min=%d sec=%d ", gm.tm_year, gm.tm_mon, gm.tm_mday, gm.tm_hour, gm.tm_min, gm.tm_sec); printf("wday=%d yday=%d isdst=%d\n", gm.tm_wday, gm.tm_yday, gm.tm_isdst); /* The TZ environment variable will affect localtime(). Try, for example: TZ=Pacific/Auckland calendar_time */ locp = localtime(&t); if (locp == NULL) errExit("localtime"); loc = *locp; /* Save local copy */ printf("Broken down by localtime():\n"); printf(" year=%d mon=%d mday=%d hour=%d min=%d sec=%d ", loc.tm_year, loc.tm_mon, loc.tm_mday, loc.tm_hour, loc.tm_min, loc.tm_sec); printf("wday=%d yday=%d isdst=%d\n\n", loc.tm_wday, loc.tm_yday, loc.tm_isdst); printf("asctime() formats the gmtime() value as: %s", asctime(&gm)); printf("ctime() formats the time() value as: %s", ctime(&t)); printf("mktime() of gmtime() value: %ld secs\n", (long) mktime(&gm)); printf("mktime() of localtime() value: %ld secs\n", (long) mktime(&loc)); exit(EXIT_SUCCESS); }
程序输出结果:
root@ubuntu:~/tlpi-dist/time# ./calendar_time Seconds since the Epoch (1 Jan 1970): 1508659096 (about 47.808 years) gettimeofday() returned 1508659096 secs, 249229 microsecs Broken down by gmtime(): year=117 mon=9 mday=22 hour=7 min=58 sec=16 wday=0 yday=294 isdst=0 Broken down by localtime(): year=117 mon=9 mday=22 hour=15 min=58 sec=16 wday=0 yday=294 isdst=0 asctime() formats the gmtime() value as: Sun Oct 22 07:58:16 2017 ctime() formats the time() value as: Sun Oct 22 15:58:16 2017 mktime() of gmtime() value: 1508630296 secs mktime() of localtime() value: 1508659096 secs root@ubuntu:~/tlpi-dist/time#
程序说明:
函数localtime()需要考虑时区和夏令时设置,因此打印的是本地时间。比gmtime()返回的时间晚整8个小时。
函数gettimeofday确实可以精确到microsecs级别。
1508659096-1508630296=8*3600
函数strftime():
当把一个分解时间转换成打印格式时,函数strftime()可以提供更为精确的控制。
函数currTime()返回当前时间。
/*************************************************************************\ * Copyright (C) Michael Kerrisk, 2015. * * * * This program is free software. You may use, modify, and redistribute it * * under the terms of the GNU Lesser General Public License as published * * by the Free Software Foundation, either version 3 or (at your option) * * any later version. This program is distributed without any warranty. * * See the files COPYING.lgpl-v3 and COPYING.gpl-v3 for details. * \*************************************************************************/ /* Listing 10-2 */ /* curr_time.c Implement our currTime() function. */ #include <time.h> #include "curr_time.h" /* Declares function defined here */ #define BUF_SIZE 1000 /* Return a string containing the current time formatted according to the specification in 'format' (see strftime(3) for specifiers). If 'format' is NULL, we use "%c" as a specifier (which gives the' date and time as for ctime(3), but without the trailing newline). Returns NULL on error. */ char * currTime(const char *format) { static char buf[BUF_SIZE]; /* Nonreentrant */ time_t t; size_t s; struct tm *tm; t = time(NULL); tm = localtime(&t); if (tm == NULL) return NULL; s = strftime(buf, BUF_SIZE, (format != NULL) ? format : "%c", tm); return (s == 0) ? NULL : buf; }
函数strptime()是strftime()的逆向函数,将包含日期和时间的字符串转换成分解时间。
示例代码:
/*************************************************************************\ * Copyright (C) Michael Kerrisk, 2015. * * * * This program is free software. You may use, modify, and redistribute it * * under the terms of the GNU General Public License as published by the * * Free Software Foundation, either version 3 or (at your option) any * * later version. This program is distributed without any warranty. See * * the file COPYING.gpl-v3 for details. * \*************************************************************************/ /* Listing 10-3 */ /* strtime.c Demonstrate the use of strptime() and strftime(). Calls strptime() using the given "format" to process the "input-date+time". The conversion is then reversed by calling strftime() with the given "out-format" (or a default format if this argument is omitted). */ #if ! defined(__sun) #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE #endif #endif #include <time.h> #include <locale.h> #include "tlpi_hdr.h" #define SBUF_SIZE 1000 int main(int argc, char *argv[]) { struct tm tm; char sbuf[SBUF_SIZE]; char *ofmt; if (argc < 3 || strcmp(argv[1], "--help") == 0) usageErr("%s input-date-time in-format [out-format]\n", argv[0]); if (setlocale(LC_ALL, "") == NULL) errExit("setlocale"); /* Use locale settings in conversions */ memset(&tm, 0, sizeof(struct tm)); /* Initialize 'tm' */ if (strptime(argv[1], argv[2], &tm) == NULL) fatal("strptime"); tm.tm_isdst = -1; /* Not set by strptime(); tells mktime() to determine if DST is in effect */ printf("calendar time (seconds since Epoch): %ld\n", (long) mktime(&tm)); ofmt = (argc > 3) ? argv[3] : "%H:%M:%S %A, %d %B %Y %Z"; if (strftime(sbuf, SBUF_SIZE, ofmt, &tm) == 0) fatal("strftime returned 0"); printf("strftime() yields: %s\n", sbuf); exit(EXIT_SUCCESS); }
执行结果:
如果输入两个参数,则函数strftime使用”%H:%M:%S %A, %d %B %Y %Z”形式,如果输入三个参数,函数strftime则使用输入的格式。
时区
在目录/usr/share/zoneinfo中,每个文件包含一个特定国家或地区内时区制度的相关信息,且往往根据其所描述的时区来加以命名,诸如EST 美国东部 CET欧洲中部 等。系统的本地时间由时区文件/etc/localtime定义,通常链接到/usr/share/zoneinfo下的一个文件。
设置时区影响ctime() localtime() mktime() strftime(),为了获取当前的时区设置,上述函数都会调用tzset(3),对如下三个全局变量进行初始化:
char *tzname[2], int daylight; long timezone;
函数tzset会首先检查环境变量TZ,如果尚未设置该变量,则使用/etc/localtime中定义的默认时区来初始化时区.
程序执行结果:
root@ubuntu:~/tlpi-book/time# ./show_time ctime() of time() value is: Sun Oct 22 23:03:27 2017 asctime() of local time is: Sun Oct 22 23:03:27 2017 strftime() of local time is: Sunday, 22 October 2017, 23:03:27 CST root@ubuntu:~/tlpi-book/time# root@ubuntu:~/tlpi-book/time# root@ubuntu:~/tlpi-book/time# TZ=":Pacific/Auckland" ./show_time ctime() of time() value is: Mon Oct 23 04:03:34 2017 asctime() of local time is: Mon Oct 23 04:03:34 2017 strftime() of local time is: Monday, 23 October 2017, 04:03:34 NZDT root@ubuntu:~/tlpi-book/time#
相关文章推荐
- Python 语言及其应用 Chapter_10 Note 3 时间time
- chapter 10 关联容器(待续)
- 时间子系统10_hpet时钟初始化
- Chapter 4. 聚合函数、字符串函数、类型转换函数、时间日期函数
- 【Data Algorithms_Recipes for Scaling up with Hadoop and Spark】Chapter 10 Content-Based Recommend
- Linux设备驱动程序第三版学习(10)- 时间、延迟及延缓操作
- TensorFlow实战10:ResNet实现及时间测评
- 如何知道 win10 的激活到期时间和期限等
- obj-c编程10:Foundation库中类的使用(5)[时间对象]
- Files and Strings(Chapter 10 of Python 3 Object Oriented Programming)
- 10-2 11 静态不记录 日志切割 静态过期时间
- CHAPTER 10:EX 34
- Chapter 1 Securing Your Server and Network(10):使用扩展保护避免授权中继攻击
- Chapter 10 信号
- 第五周作业_Chapter 10课后练习
- The Linux Programming Interface 10 Time 时间
- 零元学Expression Blend 4 - Chapter 10 用实例了解布局容器系列-「StackPanel」
- js---10时间类
- c# 10位数int时间单位换算为datetime
- Linux设备驱动程式学习(10)-时间、延迟及延缓操作