Linux 时区与时间time

本文详细介绍了计算机中的时间概念,包括UTC(协调世界时)、RTC(实时时钟)和日历时间。UTC是基于0时区的格林威治时间,中国位于东八区,故UTC+8。RTC是硬件层面的计时芯片,保存在CMOS中。日历时间是从1970年1月1日开始计算的秒数。文章还探讨了时间相关的C语言函数,如time()、gmtime()、localtime()、mktime(),并展示了如何使用这些函数进行时间转换和显示。最后提到了Linux中查看时区的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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中有很多种方式来查看,例如:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值