APUE学习笔记——6.10 时间与时间例程 time_t

Unix提供的最基本的时间服务室日历时间(纪元时间),也就是计算1970年1月1日0时0分0秒到当前的秒数。该秒数用time_t表示。

  1. typedef long time_t; /* 时间值time_t 为长整型的别名*/

1、获取/设置时间

1.1 time和time_t

函数time()可以用于获取当前日历时间

  1. #include <time.h>
  2. time_t time(time_t *calptr);
  3. Returns: value of time if OK,?1 on error

当前时间值(即1970年1月1日0时0分0秒到现在的秒数)保存给calptr指针指向的地址,也作为返回值。

1.2 指定时钟类型

Unix提供指定时钟类型来获取/设置时间的方法。

  1. #include <time.h>
  2. int clock_getres(clockid_t clk_id, struct timespec *res);
  3. int clock_gettime(clockid_t clk_id, struct timespec *tp);
  4. int clock_settime(clockid_t clk_id, const struct timespec *tp);
  5. Link with -lrt.编译时使用链接库lrt

clock_gettime()和clock_settime();函数提供了纳秒级别的时间,并且会根据clk_id的时间类型进行取值。

clock_getres 用于获取时间的分辨率。  clock_gettime()和clock_settime()使用的时间必须是时间分辨率的整数倍,不是整数倍也要切割成整数倍。

clockid_tclk_id用于指定计时时钟的类型,有以下选项:

  1. CLOCK_REALTIME:系统实时时间,使用此选项时功能相当于time(),如果系统时间被用户修改过,则对应的时间相应改变
  2. CLOCK_MONOTONIC:从系统启动这一刻起开始计时,不受系统时间被用户改变的影响
  3. CLOCK_PROCESS_CPUTIME_ID:本进程运行的CPU时间
  4. CLOCK_THREAD_CPUTIME_ID:本线程运行的CPU时间
  1. struct timespec {
  2. time_t tv_sec; /* seconds */
  3. long tv_nsec; /* nanoseconds */
  4. };

1.3 gettimeofday()与settimeofday()

Unix/Linux提供了微秒级别获取和设置时间的函数gettimeofday()与settimeofday(),但根据man手册的描述,这两个函数已经过时,此处不做介绍。仅列出原型(这两个函数编译需要glibc的支持)

  1. #include <sys/time.h>
  2. int gettimeofday(struct timeval *tv, struct timezone *tz);
  3. int settimeofday(const struct timeval *tv, const struct timezone *tz);

2、时间格式转换

我们使用time()等函数获取的时间是一个time_t获取的从新纪元开始到当前所经过的秒数,是一个整数值。(calender time)

我们很多情况下需要将其转换成我们可读的,向时分秒这样的时间(broken down time)。这就需要进行转化。

时间转换图如 Figure6.9 所示

我们使用struct tm来保存broken-down time

  1. struct tm { /* a broken-down time */
  2.     int tm_sec;     // 秒 【0~60】 60存在的原因是闰秒的存在
  3.     int tm_min;     //分
  4.     int tm_hour;    //时
  5.     int tm_mday;    //日
  6.     int tm_mon;     //月
  7.     int tm_year;    //年 结构中记录的是从1900至今的年数
  8.     int tm_wday; //星期几 【0~6】
  9.     int tm_yday;    // 一年中第几天
  10.     int tm_isdst; // 夏时制标志
  11. };

夏时制,夏时令(Daylight Saving Time:DST),又称“日光节约时制”和“夏令时间”,是一种为节约能源而人为规定地方时间的制度,在这一制度实行期间所采用的统一时间称为“夏令时间”。一般在天亮早的夏季人为将时间提前一小时,可以使人早起早睡,减少照明量,以充分利用光照资源,从而节约照明用电。

    Unix提供了时间格式转换的函数:

2.1 time_t与struct tm相互转化

time_t转化成struct tm

  1. #include <time.h>
  2. struct tm *gmtime(const time_t *calptr);
  3. struct tm *localtime(const time_t *calptr);
  4. Both return: pointer to broken-down time,NULLon error

gmtime 转换成国际标准时间

localtime转换成本地时间(考虑到本地时区和夏时制标志)

struct tm转化成time_t

  1. #include <time.h>
  2. time_t mktime(struct tm *tmptr);
  3. Returns: calendar time if OK,?1 on error

example:

  1. #include<stdio.h>
  2. #include <time.h>
  3. #include<sys/time.h>
  4. int main(void)
  5. {
  6. time_t calptr;
  7. if (time(&calptr) == -1)
  8. {
  9. printf("Error: time() failed!\n");
  10. exit(0);
  11. }
  12. printf("Time(time_t) now is: %d\n",(long) calptr);
  13. /*
  14. * 转换成可读到时间
  15. */
  16. struct tm *gmptr; //国际标准时间
  17. struct tm *localptr; //本地时间
  18. /* 转换成国际标准时间 */
  19. printf("\n\n ----------gm time--------------\n");
  20. if (NULL == (gmptr = gmtime(&calptr)))
  21. {
  22. printf("Error: can‘t convert time_t to struct tm by gmtime()!\n");
  23. exit(0);
  24. }
  25. printf("year:%d,\tMonth:%d,\tDay:%d,\tWeek:%d\n", gmptr->tm_year, gmptr->tm_mon, gmptr->tm_mday, gmptr->tm_wday);
  26. printf("Hour:%d,\tMin:%d,\t,sec:%d\n", gmptr->tm_hour, gmptr->tm_min, gmptr->tm_sec);
  27. /* 转换成本地标准时间 */
  28. printf("\n\n ----------local time--------------\n");
  29. if (NULL == (localptr = localtime(&calptr)))
  30. {
  31. printf("Error: can‘t convert time_t to struct tm by localtime()!\n");
  32. exit(0);
  33. }
  34. printf("year:%d,\tMonth:%d,\tDay:%d,\tWeek:%d\n", localptr->tm_year, localptr->tm_mon, localptr->tm_mday, localptr->tm_wday);
  35. printf("Hour:%d,\tMin:%d,\t,sec:%d\n", localptr->tm_hour, localptr->tm_min, localptr->tm_sec);
  36. return 0;
  37. }

运行结果:

  1. [email protected]:~/Windeal/apue$ ./exe
  2. Time(time_t) now is: 1409207607
  3. ----------gm time--------------
  4. year:114, Month:7, Day:28, Week:4
  5. Hour:6, Min:33, ,sec:27
  6. ----------local time--------------
  7. year:114, Month:7, Day:28, Week:4
  8. Hour:14, Min:33, ,sec:27

东八区,快了8个小时

2.2 转换成格式化字符串

  1. #include <time.h>
  2. size_t strftime(char *restrict buf,size_t maxsize,
  3. const char *restrict format,
  4. const struct tm *restrict tmptr);
  5. size_t strftime_l(char *restrict buf,size_t maxsize,
  6. const char *restrict format,
  7. const struct tm *restrict tmptr,locale_t locale);
  8. ——Both return: number of characters stored in array if room, 0 otherwise

Example:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. int
  5. main(void)
  6. {
  7. time_t t;
  8. struct tm *tmp;
  9. char buf1[16];
  10. char buf2[64];
  11. time(&t);
  12. tmp = localtime(&t);
  13. if (strftime(buf1, 16, "time and date: %r, %a %b %d, %Y", tmp) == 0)
  14. printf("buffer length 16 is too small\n");
  15. else
  16. printf("%s\n", buf1);
  17. if (strftime(buf2, 64, "time and date: %r, %a %b %d, %Y", tmp) == 0)
  18. printf("buffer length 64 is too small\n");
  19. else
  20. printf("%s\n", buf2);
  21. exit(0);
  22. }
  23. ~

运行结果:

  1. [email protected]:~/Windeal/apue$ ./exe
  2. buffer length 16 is too small
  3. time and date: 02:43:55 PM, Thu Aug 28, 2014

字符串转换成struct tm格式

  1. #include <time.h>
  2. char *strptime(const char *restrictbuf,const char *restrictformat,struct tm *restricttmptr);
  3. Returns: pointer to one character past last character parsed,NULLotherwise

关于转换符号:

Unix提供的最基本的时间服务室日历时间(纪元时间),也就是计算1970年1月1日0时0分0秒到当前的秒数。该秒数用time_t表示。

  1. typedef long time_t; /* 时间值time_t 为长整型的别名*/

1、获取/设置时间

1.1 time和time_t

函数time()可以用于获取当前日历时间

  1. #include <time.h>
  2. time_t time(time_t *calptr);
  3. Returns: value of time if OK,?1 on error

当前时间值(即1970年1月1日0时0分0秒到现在的秒数)保存给calptr指针指向的地址,也作为返回值。

1.2 指定时钟类型

Unix提供指定时钟类型来获取/设置时间的方法。

  1. #include <time.h>
  2. int clock_getres(clockid_t clk_id, struct timespec *res);
  3. int clock_gettime(clockid_t clk_id, struct timespec *tp);
  4. int clock_settime(clockid_t clk_id, const struct timespec *tp);
  5. Link with -lrt.编译时使用链接库lrt

clock_gettime()和clock_settime();函数提供了纳秒级别的时间,并且会根据clk_id的时间类型进行取值。

clock_getres 用于获取时间的分辨率。  clock_gettime()和clock_settime()使用的时间必须是时间分辨率的整数倍,不是整数倍也要切割成整数倍。

clockid_tclk_id用于指定计时时钟的类型,有以下选项:

  1. CLOCK_REALTIME:系统实时时间,使用此选项时功能相当于time(),如果系统时间被用户修改过,则对应的时间相应改变
  2. CLOCK_MONOTONIC:从系统启动这一刻起开始计时,不受系统时间被用户改变的影响
  3. CLOCK_PROCESS_CPUTIME_ID:本进程运行的CPU时间
  4. CLOCK_THREAD_CPUTIME_ID:本线程运行的CPU时间
  1. struct timespec {
  2. time_t tv_sec; /* seconds */
  3. long tv_nsec; /* nanoseconds */
  4. };

1.3 gettimeofday()与settimeofday()

Unix/Linux提供了微秒级别获取和设置时间的函数gettimeofday()与settimeofday(),但根据man手册的描述,这两个函数已经过时,此处不做介绍。仅列出原型(这两个函数编译需要glibc的支持)

  1. #include <sys/time.h>
  2. int gettimeofday(struct timeval *tv, struct timezone *tz);
  3. int settimeofday(const struct timeval *tv, const struct timezone *tz);

2、时间格式转换

我们使用time()等函数获取的时间是一个time_t获取的从新纪元开始到当前所经过的秒数,是一个整数值。(calender time)

我们很多情况下需要将其转换成我们可读的,向时分秒这样的时间(broken down time)。这就需要进行转化。

时间转换图如 Figure6.9 所示

我们使用struct tm来保存broken-down time

  1. struct tm { /* a broken-down time */
  2.     int tm_sec;     // 秒 【0~60】 60存在的原因是闰秒的存在
  3.     int tm_min;     //分
  4.     int tm_hour;    //时
  5.     int tm_mday;    //日
  6.     int tm_mon;     //月
  7.     int tm_year;    //年 结构中记录的是从1900至今的年数
  8.     int tm_wday; //星期几 【0~6】
  9.     int tm_yday;    // 一年中第几天
  10.     int tm_isdst; // 夏时制标志
  11. };

夏时制,夏时令(Daylight Saving Time:DST),又称“日光节约时制”和“夏令时间”,是一种为节约能源而人为规定地方时间的制度,在这一制度实行期间所采用的统一时间称为“夏令时间”。一般在天亮早的夏季人为将时间提前一小时,可以使人早起早睡,减少照明量,以充分利用光照资源,从而节约照明用电。

    Unix提供了时间格式转换的函数:

2.1 time_t与struct tm相互转化

time_t转化成struct tm

  1. #include <time.h>
  2. struct tm *gmtime(const time_t *calptr);
  3. struct tm *localtime(const time_t *calptr);
  4. Both return: pointer to broken-down time,NULLon error

gmtime 转换成国际标准时间

localtime转换成本地时间(考虑到本地时区和夏时制标志)

struct tm转化成time_t

  1. #include <time.h>
  2. time_t mktime(struct tm *tmptr);
  3. Returns: calendar time if OK,?1 on error

example:

  1. #include<stdio.h>
  2. #include <time.h>
  3. #include<sys/time.h>
  4. int main(void)
  5. {
  6. time_t calptr;
  7. if (time(&calptr) == -1)
  8. {
  9. printf("Error: time() failed!\n");
  10. exit(0);
  11. }
  12. printf("Time(time_t) now is: %d\n",(long) calptr);
  13. /*
  14. * 转换成可读到时间
  15. */
  16. struct tm *gmptr; //国际标准时间
  17. struct tm *localptr; //本地时间
  18. /* 转换成国际标准时间 */
  19. printf("\n\n ----------gm time--------------\n");
  20. if (NULL == (gmptr = gmtime(&calptr)))
  21. {
  22. printf("Error: can‘t convert time_t to struct tm by gmtime()!\n");
  23. exit(0);
  24. }
  25. printf("year:%d,\tMonth:%d,\tDay:%d,\tWeek:%d\n", gmptr->tm_year, gmptr->tm_mon, gmptr->tm_mday, gmptr->tm_wday);
  26. printf("Hour:%d,\tMin:%d,\t,sec:%d\n", gmptr->tm_hour, gmptr->tm_min, gmptr->tm_sec);
  27. /* 转换成本地标准时间 */
  28. printf("\n\n ----------local time--------------\n");
  29. if (NULL == (localptr = localtime(&calptr)))
  30. {
  31. printf("Error: can‘t convert time_t to struct tm by localtime()!\n");
  32. exit(0);
  33. }
  34. printf("year:%d,\tMonth:%d,\tDay:%d,\tWeek:%d\n", localptr->tm_year, localptr->tm_mon, localptr->tm_mday, localptr->tm_wday);
  35. printf("Hour:%d,\tMin:%d,\t,sec:%d\n", localptr->tm_hour, localptr->tm_min, localptr->tm_sec);
  36. return 0;
  37. }

运行结果:

  1. [email protected]:~/Windeal/apue$ ./exe
  2. Time(time_t) now is: 1409207607
  3. ----------gm time--------------
  4. year:114, Month:7, Day:28, Week:4
  5. Hour:6, Min:33, ,sec:27
  6. ----------local time--------------
  7. year:114, Month:7, Day:28, Week:4
  8. Hour:14, Min:33, ,sec:27

东八区,快了8个小时

2.2 转换成格式化字符串

  1. #include <time.h>
  2. size_t strftime(char *restrict buf,size_t maxsize,
  3. const char *restrict format,
  4. const struct tm *restrict tmptr);
  5. size_t strftime_l(char *restrict buf,size_t maxsize,
  6. const char *restrict format,
  7. const struct tm *restrict tmptr,locale_t locale);
  8. ——Both return: number of characters stored in array if room, 0 otherwise

Example:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. int
  5. main(void)
  6. {
  7. time_t t;
  8. struct tm *tmp;
  9. char buf1[16];
  10. char buf2[64];
  11. time(&t);
  12. tmp = localtime(&t);
  13. if (strftime(buf1, 16, "time and date: %r, %a %b %d, %Y", tmp) == 0)
  14. printf("buffer length 16 is too small\n");
  15. else
  16. printf("%s\n", buf1);
  17. if (strftime(buf2, 64, "time and date: %r, %a %b %d, %Y", tmp) == 0)
  18. printf("buffer length 64 is too small\n");
  19. else
  20. printf("%s\n", buf2);
  21. exit(0);
  22. }
  23. ~

运行结果:

  1. [email protected]:~/Windeal/apue$ ./exe
  2. buffer length 16 is too small
  3. time and date: 02:43:55 PM, Thu Aug 28, 2014

字符串转换成struct tm格式

  1. #include <time.h>
  2. char *strptime(const char *restrictbuf,const char *restrictformat,struct tm *restricttmptr);
  3. Returns: pointer to one character past last character parsed,NULLotherwise

关于转换符号:

时间: 2024-10-08 02:28:51

APUE学习笔记——6.10 时间与时间例程 time_t的相关文章

APUE学习笔记——3.10文件共享

基本概念 内核使用3个数据结构描述一个打开的文件:进程表.文件表.V节点表 首先了解3种数据结构的概念 1 进程表 每一个进程有一个进程表.进程表里是一组打开的文件描述符,如标准输入0,标准输出1,标准错误2... 2 文件表 进程打开一个文件时,内核就为该文件创建一个文件表. 进程表对文件表是 一对多的关系    文件表对文件描述符也是一对多的关系(可能多个文件描述符指向同一文件表) 文件表中包含了文件状态标志.当前偏移量.和V-node pointer表项 文件状态标志如:read,  wr

APUE学习笔记:第七章 进程环境

7.1 引言 本章将学习:当执行程序时,其main函数是如何被调用的:命令行参数是如何传送给执行程序的:典型的存储器布局是什么样式:如何分配另外的存储空间:进程如何使用环境变量:各种不同的进程终止方式等:另外还将说明longjmp和setjmp函数以及它们与栈的交互作用:还将介绍研究进程的资源限制 7.2 main函数 C程序总是从main函数开始执行.当内核执行C程序时,在调用main前先调用一个特殊的启动例程.可执行程序文件将此启动例程指定为程序的起始地址——这是由连接编辑器设置的,而连接编

APUE学习笔记:第四章 文件和目录

4.1 引言 本章将描述文件的特征和文件的性质 4.2 stat.fstat和lstat函数 #include<sys/stat.h> int stat(const char *restrict pathname,struct stat *restrict buf); int fstat(int filedes,struct stat *buf) int lstat(const char *restrict pathname,struct stat *restrict buf); 三个函数的返

APUE学习笔记:第一章 UNUX基础知识

1.2 UNIX体系结构 从严格意义上,可将操作系统定义为一种软件(内核),它控制计算机硬件资源,提供程序运行环境.内核的接口被称为系统调用.公用函数库构建在系统调用接口之上,应用软件即可使用公用函数库,也可使用系统调用.shell是一种特殊的应用程序,它为运行其他应用程序提供了一个接口 从广义上,操作系统包括了内核和一些其他软件,这些软件使得计算机能够发挥作用,并给予计算机以独有的特性(软件包括系统实用程序,应用软件,shell以及公用函数库等) 1.3  shell shell是一个命令行解

APUE学习笔记:第三章 文件I/O

3.1 引言 术语不带缓冲指的是每个read和write都调用内核中的一个系统调用.这些不带缓冲的I/O函数不是ISO C的组成部分,但是,它们是POSIX.1和Single UNIX Specification的组成部分 3.2 文件描述符 UNIX系统shell使用文件描述符0与进程的标准输入相关联.文件描述符1与标准输出相关联.文件描述符2与标准出错输出相关联. 在依从POSIX的应用程序中,幻数0.1.2应当替换成符号常量STDIN_FILENO,STDOUT_FILENO和STDERR

APUE学习笔记:第六章 系统数据文件和信息

6.1 引言 UNIX系统的正常运行需要使用大量与系统有关的数据文件,针对这些数据文件的可移植接口是本章的主题.本章还介绍了系统标识函数.时间和日期函数 6.2 口令文件 UNIX系统的口令文件包含了下列各字段,这些字段包含在<pwd.h>中定义的passwd结构中 用户名 char *pw_name 加密口令 char *pw_passwd 数值用户ID uid_t pw_uid 数值组ID gid_t pw_gid 注释字段 char *pw_gecos 初始工作目录 char *pw_d

APUE学习笔记:第二章 UNIX标准化及实现

2.2UNIX标准化 2.2.1 ISO C 国际标准化组织(International Organization for Standardization,ISO) 国际电子技术委员会(International Electrotechnical Commission,IEC) ISO C标准的意图是提供C程序的可移植性,使其能适合于大量不同的操作系统,而不只是UNIX系统.此标准不仅定义了C程序设计语言的语法和语义,还定义了其标准库.因为所有现今的UNIX系统都提供C标准中定义的库例程,所以该

APUE学习笔记:第八章 进程控制

8.1 引言 本章介绍UNIX的进程控制,包括创建新进程.执行程序和进程终止.还将说明进程属性的各种ID-----实际.有效和保存的用户和组ID,以及他们如何受到进程控制原语的影响.本章还包括了解释器文件和system函数.本章最后讲述大多数UNIX系统所提供的进程会计机制.这种机制使我们能够从另一个角度了解进程的控制功能. 8.2 进程标识符 每个进程都有一个非负整型表示的惟一进程ID.因为进程标识符是惟一的,常将其用作其他标识符的一部分以保证其惟一性.虽然是惟一的,但是进程ID可以重用.(大

APUE学习笔记:第五章 标准I/O库

5.1 引言 标准I/O库处理很多细节,例如缓冲区分配,以优化长度执行I/O等.这些处理不必担心如何使用正确的块长度.这使得它便于用户使用,但是如果不较深入地了解I/O库函数的操作,也会带来一些问题 5.2 流和FILE对象 对于ASCII字符集,一个字符用一个字节表示.对于国际字符集,一个字符可用多个字节表示.标准I/O文件流可用于单字节或多字节字符集. 流的定向决定了所读.写的字符是单字节还是多字节的.当一个流最初被创建时,它并没有定向.如若在未定向的流上使用一个多字节I/O函数,则将该流的