Linux应用层查看系统时间的方法

一、基本概念:     1、linux系统时间和硬件时间:     系统时间:一般来说就是我们执行date命令查看到的时间,Linux系统下所有的时间调用(除了直接访问硬件时间的命令)都是使用这个时间。     硬件时间:主板上BIOS中的时间,由主板电池供电来维持运行,系统开机时要读取这个时间,并根据它来设定系统时间。(注意:系统启动时根据硬件时间设定系统时间的过程可能存在时区换算,这要视具体的系统及相关设置而定)。     2、UTC时间与问题时间:     UTC时间:Coordinated Universal Time,也就是协调世界时,又称世界统一时间,世界标准时间,国际协调时间。在一般精度要求下,它与GMT(Greenwich Mean Time,世界时UT即格林威治标准时间)是一样的。     本地时间:由于处在不同的时区,本地时间一般与UTC是不同的,换算方法是:本地时间 = UTC + 时区。时区东为正,西为负,例如在中国,本地时间都是使用北京时间,在Linux上就是CST(China Standard Time,中国标准时,注意美国的中部标准时Central Standart Time也缩写为CST,与这里的CST不是一回事),时区为东八区,也就是+8区,所以CST = UTC + (+8小时)     例如,我通过时间指令(下面会讲解),查看嵌入式开发板的系统时间和硬件时间如下:

    从上图可以看出,正好验证了上面提到的CST = UTC + 时区的关系。 二、时间指令     1、系统时间date     查看系统时间和UTC的操作:直接调用date,可以得到本地时间。如果想得到UTC时间的话,使用date -u;     设置系统时间的操作:格式:#date 月日时分年.秒。例如我之前查看的时间不正确,我要手动更改到现在的时间,输入指令如下:

    通过指令也可以查看到,系统时间确实已经更改了。     2. 硬件时间 hwclock     直接调用 hwclock 显示的时间就是 BIOS 中的时间吗?未必!这要看相关配置文件中是否启用了UTC,如果启用了UTC(UTC=true),显示的其实是经过时区换算的时间而不是BIOS中真正的时间,如果加上 –localtime 选项,则得到的总是 BIOS 中实际的时间。查看指令如下:

    因为是指令是相继输入,所以不是同一时刻的,但是可以看出,嵌入式开发板里的hwclock指令查看的,就是BIOS中实际的时间。     设置硬件时间的操作:格式:hwclock –set –date==”月/日/年 时:分:秒”。     更多详细指令可以通过man、help指令进行查看。 三、其他常用查看时间指令     1、uptime命令

    2、查看/proc/uptime文件计算系统启动时间

    第一个数字即是系统已经运行的时间482.15秒,用系统工具date即可计算出系统启动时间,指令如下:

date -d "$(awk -F. '{print $1}' /proc/uptime) second ago" +"%Y-%m-%d %H:%M:%S"

    结果显示:

    3、通过/proc/uptime文件计算系统运行时间,指令如下;

cat /proc/uptime| awk -F. '{run_days=$1 / 86400;run_hour=($1 % 86400)/3600;run_minute=($1 % 3600)/60;run_second=$1 % 60;printf("系统已运行:%d天%d时%d分%d秒\n",run_days,run_hour,run_minute,run_second)}'

    结果显示:

    4、who命令     who -b #查看最后一次系统启动的时间

    5、last rebbot查看Linux系统最后一次启动时间

    6、还有一些top、w也可以查看到时间

四、计算系统时间的程序     时间对操作系统来说非常重要,从内核级到应用层,时间的表达方式及精度各部相同。linux内核里面用一个名为jiffes的常量来计算时间的滴答数。而应用层,可以利用time()、localtime()等函数,通过tm结构体得到系统时间。     Linux内核版本为3.0.35的tm结构体如下:

#ifndef _TM_DEFINED
struct tm {
int tm_sec; /* 秒 – 取值区间为[0,59] */
int tm_min; /* 分 - 取值区间为[0,59] */
int tm_hour; /* 时 - 取值区间为[0,23] */
int tm_mday; /* 一个月中的日期 - 取值区间为[1,31] */
int tm_mon; /* 月份(从一月开始,0代表一月) - 取值区间为[0,11] */
int tm_year; /* 年份,其值等于实际年份减去1900 */
int tm_wday; /* 星期 – 取值区间为[0,6],其中0代表星期天,1代表星期一,以此类推 */
int tm_yday; /* 从每年的1月1日开始的天数 – 取值区间为[0,365],其中0代表1月1日,1代表1月2日,以此类推 */
int tm_isdst; /* 夏令时标识符,实行夏令时的时候,tm_isdst为正。不实行夏令时的进候,tm_isdst为0;不了解情况时,tm_isdst()为负。*/

    程序中需要用到的函数:     time函数获得日历时间。日历时间,是用“从一个标准时间点到此时的时间经过的秒数”来表示的时间。这个标准时间点对不同的编译器来说会有所不同,但对一个编译系统来说,这个标准时间点是不变的,该编译系统中的时间对应的日历时间都通过该标准时间点来衡量,所以可以说日历时间是“相对时间”,但是无论你在哪一个时区,在同一时刻对同一个标准时间点来说,日历时间都是一样的。     localtime()函数是将日历时间转化为本地时间。     asctime()函数是把timeptr指向的tm结构体中储存的时间转换为字符串字符串格式返格式为:回,Www Mmm dd hh:mm:ss yyyy。其中Www为星期;Mmm为月份;dd为日;hh为时;mm为分;ss为秒;yyyy为年份     最终代码如下:

#include <stdio.h>
#include <sys/sysinfo.h>
#include <time.h>
#include <errno.h>

int print_system_boot_time();

int main ( int argc, char ** argv )
{
    if ( print_system_boot_time() != 0 )
        return -1;
    return 0;
}

print_system_boot_time()
{
    int year,month,day,wday,hour,min,sec;
    struct sysinfo info;
    struct tm *ptm = NULL;
    time_t cur_time = 0;
    if(sysinfo(&info))
    {
        fprintf(stderr, "Failed to get sysinfo, errno:%u, reason:%s\n", errno, strerror(errno));
    }
    time(&cur_time);
    ptm = localtime(&cur_time);
    year = ptm->tm_year + 1900;           //年
    month = ptm->tm_mon + 1;              //月
    day = ptm->tm_mday;                   //日
    wday = ptm->tm_wday;                  //星期
    hour = ptm->tm_hour;                  //小时
    min = ptm->tm_min;                    //分
    sec = ptm->tm_sec;                    //秒
    printf("The current date: %d-%-.2d-%d 星期%d %d:%.2d:%.2d\n", year, month, day, wday, hour, min, sec);
    printf("The current date is %s",asctime(ptm));
    return 0;
}

    结果显示:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Linuxer的专栏

宋宝华:LEP ( Linux 易用剖析器 ) 是什么,为什么以及怎么办 ( 1 )

LEP是 Linuxer 之 LEP 项目组(Barry Song,Mac Xu,陈松等以及陈莉君老师)正在致力于打造的一个开源项目,本文是 LEP 文档《 L...

51900
来自专栏云加头条

Linux Kernel 4.11 发布

4月30日,Linus Torvalds 在内核邮件列表上宣布释出 Linux Kernel 4.11。

24800
来自专栏潘嘉兴的专栏

手把手教你如何优化linux服务器

服务器的优化是我们最小化安装系统后应该做的事情,下面是一些常见的基本的优化服务器的方法。关闭不需要的服务。列出需要启动的的服务crond、network、ssh...

68400
来自专栏莫韵的专栏

linux 根分区的空间去哪里了 ?记一次根分区满的服务故障排查记录

linux 根分区的空间去哪里了 ?记一次根分区满的服务故障排查记录。我的排查思路是先找占用没有占用,找占用的文件句柄。

1.5K00
来自专栏邹立巍的专栏

Linux 的进程间通信:文件和文件锁

我们首先引入文件进行 IPC ,试图先使用文件进行通信引入一个竞争条件的概念,然后使用文件锁解决这个问题,从而先从文件的角度来管中窥豹的看一下后续相关 IPC ...

1.3K00
来自专栏刘远飞的专栏

CentOS6.5系统yum安装LAMP环境

采用Linux下二进制模式来安装LAMP,适合初学者,测试使用。

87300
来自专栏郑剑的专栏

linux 内存管理初探

本文主要介绍 linux 内存组织结构和页面布局,内存碎片产生原因和优化算法,linux 内核几种内存管理的方法,内存使用场景以及内存使用的那些坑。

2.6K90
来自专栏皮振伟的专栏

linux、pthread、qemu 的一次 pthread create 失败的分析

qemu 因为 pthread create 失败而发生了 crash 。这种类型的问题比较少见,这里记录一下问题的分析过程以及解决思路。

54800
来自专栏Linuxer的专栏

吴锦华 / 明鑫 : 用户态文件系统 ( FUSE ) 框架分析和实战

用户态文件系统(filesystem in userspace, 简称 FUSE),它能使用户在无需编辑和编译内核代码的情况下,创建用户自定义的文件系统。

1.6K10
来自专栏张戈的专栏

【ES私房菜】收集 Linux 系统日志

ES环境已经就绪,我们需要先调通一类简单日志作为数据上报全链路的试运行。恰好Linux系统日志就是这样一个角色,随处可见,风险可控。这里,我们选择了2种Linu...

1K10

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励