UTC时间:这是一个与时区相关的时间,目前将世界时区分为24个:
UTC跟GMT(Greenwich Mean Time,格林威治时间)一致,因为格林威治位于0时区,UTC时间即是0时区的时间。中国位于东八区,所以对应的时间是UTC时间加8小时,即UTC+8,也称为CST(China Standard Time)。UTC倾向于跟标准相关的时间。UTC的查看可以通过date命令(命令需要加上-u,否则看到的是本地时间,即UTC+8的时间);
RTC:Real Time Clock,实时时钟。RTC和UTC不是一个概念上的时间,RTC通常指的是系统上一个计时的芯片,它将时间保存在CMOS中,而CMOS通过电池可以保持数据不丢失,因此在系统没有上电的情况下也还会正常运行。操作系统启动时会查看这个时间,也可以同步这个时间。RTC倾向于跟硬件相关的时间。查看RTC的命令如下(当前最好在root用户下)
Calendar Time:日历时间,指的是从当前时间到某个标准时间经历的秒数。这里的某个时间通常是指1970年1月1日0时0分0秒,这个时间点也被称为Epoch。日历时间是一个相对的时间值,倾向于跟软件相关。
与时间相关的常用函数:
- /* Return the current time and put it in *TIMER if TIMER is not NULL. */
- extern time_t time (time_t *__timer) __THROW;
它的入参和返回值都是time_t,它实际上就是一个长整型,表示的就是从Epoch到函数调用之时经历的秒数,也就是前面提到的日历时间。为了得到这个时间,通常传入一个NULL作为参数,返回值就是我们需要的。
- #include <stdio.h>
- #include <time.h>
-
- time_t time_test(void)
- {
- time_t t = time(NULL);
- return t;
- }
-
- int main(int argc, char *argv[])
- {
- time_t t = time_test();
- printf("time_test:%ld\n", t);
- return 0;
- }
执行结果:
gmtime()函数会利用time_t的值,并将其转换为一个真正的时间,从函数名称就可以看出来是格林威治时间,也就是UTC的时间。与gmtime对应的就是转化为本地时间的函数localtime()。它们的函数原型如下:
- # ifdef __USE_POSIX
- /* Return the `struct tm' representation of *TIMER in UTC,
- using *TP to store the result. */
- extern struct tm *gmtime_r (const time_t *__restrict __timer,
- struct tm *__restrict __tp) __THROW;
-
- /* Return the `struct tm' representation of *TIMER in local time,
- using *TP to store the result. */
- extern struct tm *localtime_r (const time_t *__restrict __timer,
- struct tm *__restrict __tp) __THROW;
- # endif /* POSIX */
这两个函数的返回值就是前面提到的结构体strum tm,接收的参数就是time()函数的返回值time_t;
- #include <stdio.h>
- #include <time.h>
-
- time_t time_test(void)
- {
- time_t t = time(NULL);
- return t;
- }
-
- struct tm *gmttime_test(time_t *t)
- {
- struct tm *tm;
- tm = gmtime(t);
- return tm;
- }
-
- struct tm *localtime_test(time_t *t)
- {
- struct tm *tm;
- tm = localtime(t);
- return tm;
- }
-
- int main(int argc, char *argv[])
- {
- time_t t = time_test();
- printf("time_test:%ld\n", t);
- struct tm *tm = gmttime_test(&t);
- printf("%4d-%02d-%02d %02d:%02d:%02d %s\n", tm->tm_year + 1900, tm->tm_mon + 1,tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_zone);
- tm = NULL;
- tm = localtime_test(&t);
- printf("%4d-%02d-%02d %02d:%02d:%02d %s\n", tm->tm_year + 1900, tm->tm_mon + 1,tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_zone);
- return 0;
- }
执行结果:
注意:struct tm里 年和月两个值的参考值,所以需要增加特定的偏移之后才是真实值。从测试程序可看出本地时间和UTC时间之间的差异刚好是8小时。
ctime()和asctime(): 可自己实现显示时间的字符串
- __BEGIN_NAMESPACE_STD
- /* Return a string of the form "Day Mon dd hh:mm:ss yyyy\n"
- that is the representation of TP in this format. */
- extern char *asctime (const struct tm *__tp) __THROW;
-
- /* Equivalent to `asctime (localtime (timer))'. */
- extern char *ctime (const time_t *__timer) __THROW;
- __END_NAMESPACE_STD
- #include <stdio.h>
- #include <time.h>
-
- time_t time_test(void)
- {
- time_t t = 0;
- t = time(NULL);
- return t;
- }
-
- struct tm *gmttime_test(time_t *t)
- {
- struct tm *tm = NULL;
- tm = gmtime(t);
- return tm;
- }
-
- struct tm *localtime_test(time_t *t)
- {
- struct tm *tm = NULL;
- tm = localtime(t);
- return tm;
- }
-
- char *asctime_test(struct tm *tm)
- {
- char *char_time = {0};
- char_time = asctime(tm);
- return char_time;
- }
-
- char *ctime_test(time_t *t)
- {
- char *char_time = {0};
- char_time = ctime(t);
- return char_time;
- }
-
- int main(int argc, char *argv[])
- {
- time_t t = time_test();
- printf("time_test:%ld\n", t);
- struct tm *tm = gmttime_test(&t);
- //printf("%4d-%02d-%02d 02d:%02d:%02d %s\n", tm->tm_year + 1900, tm->tm_mon + 1,tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_zone);
- printf("asctime %s", asctime_test(tm));
- tm = NULL;
- tm = localtime_test(&t);
- //printf("%4d-%02d-%02d %02d:%02d:%02d %s\n", tm->tm_year + 1900, tm->tm_mon + 1,tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_zone);
- printf("ctime %s", ctime_test(&t));
- return 0;
- }
执行结果:
从执行结果可以看出:ctime()显示的是本地时间。两个函数返回的时间字符串还自带换行,所以不需要我们添加。
- /* Return the `time_t' representation of TP and normalize TP. */
- extern time_t mktime (struct tm *__tp) __THROW;
该函数mktime()的功能与gmtime()和localtime()函数的功能刚好相反,是将struct tm转换为time_t;
RTC与时间函数
RTC时间是存放在CMOS中的时间,其中CMOS是一段非易失的介质,里面的内容是固定的,而这里的值会通过一个芯片按固定的时间修改,以保持时间的同步。time()函数的一个实现方式即为通过读取CMOS里的值,然后与Epoch时间做减法,得到的时间间隔再转化为秒数,即可作为返回值。
关于时区Linux中有很多种方式来查看,例如: