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 条评论
登录 后参与评论

相关文章

来自专栏张善友的专栏

Google SiteMap Protocol协议

在新浪看到这样的新闻Google雅虎微软联手支持网页手工提交标准, Google、微软和雅虎认为,统一标准有助于从整体上改进站点地图,从而搜索引擎可以将更广泛的...

20710
来自专栏腾讯Bugly的专栏

Android Patch 方案与持续交付

Android 不仅系统版本众多,机型众多,而且各个市场都各有各的政策和审核速度,每次发布一个版本对于开发同学来讲都是一种漫长的煎熬。相比于 iOS 两三天就能...

2885
来自专栏DannyHoo的专栏

利用plist文件查看后台返回数据的数据类型

当看客看到标题的时候或许会有些疑惑,有的人甚至会鄙视写者。查看后台返回的数据类型为什么要用plist文件,这也太麻烦了吧。我既然写这篇博客,肯定是有一定的原因的...

561
来自专栏AI2ML人工智能to机器学习

Shiny: R语言来建立开源交互式数据分析微服务的神器

先来说个应用场景: 假设你需要快速Prototype一个数据分析的服务, 而且需要给业务客户一定的自由度来理解数据分析的强大, 例如更换数据, 更换分析手段。 ...

943
来自专栏杨龙飞前端

vue重构后台管理系统调研

Q4要来了,我来这家公司已经一个季度了,通过对公司前端框架的整体认识,对业务的一些认识,发现,这些东西也都是可以重构,无论是v2,还是v3的代码。

601
来自专栏达摩兵的技术空间

app中的webview通识篇(上)

如果你还是第一次与app合作开发webview的页面,那么对于如何调试,可能有哪些问题可能是不够了解的。本文尝试性的根据自己的经验给大家一个入门级别的了解,如果...

642
来自专栏张戈的专栏

小网站最简单实用的动静分离优化方案

很久没写文章了,博客已经长草了,今天挤点时间分享一些小干货,也是回应一下不少站长朋友的留言问题。 有不少站长朋友问张戈博客的静态文件为啥是另外一个域名?有啥好处...

4068
来自专栏AndroidTraveler

责任链模式妙用

除了应用场景比较多的单例模式你能够信手拈来,其他的可能会觉得有点难以掌握。也许压根都没用过。

873
来自专栏向治洪

携程React Native实践

React Native(下文简称 RN)开源已经一年多时间,国内各大互联网公司都在使用,携程也在今年 5 月份投入资源开始引入,并推广给多个业务团队使用,本文...

2957
来自专栏分享达人秀

Android 系统架构和应用组件那些事

继上一期浅谈了Android的前世今生,这一期一起来大致回顾一下Android 系统架构和应用组件。 Android 系统架构 Android系...

2206

扫码关注云+社区