Linux 系统设置时间和获取时间

手里的智能锁项目 , 做了个菜单,设置时间的功能 , 弄了大半天弄完了,  记录一下方法

1设置时间

设置时间需要2个结构体,分别是struct tm 和struct timeval还有一个长整型的time_t类型, 总共4个步骤。


1.1 把tm类型里的成员(年 月 日 时 分 秒)逐个赋值

struct tm {
    /*  
     * the number of seconds after the minute, normally in the range
     * 0 to 59, but can be up to 60 to allow for leap seconds
     */
    int tm_sec;
    /* the number of minutes after the hour, in the range 0 to 59*/
    int tm_min;
    /* the number of hours past midnight, in the range 0 to 23 */
    int tm_hour;
    /* the day of the month, in the range 1 to 31 */
    int tm_mday;
    /* the number of months since January, in the range 0 to 11 */
    int tm_mon;
    /* the number of years since 1900 */
    long tm_year;
    /* the number of days since Sunday, in the range 0 to 6 */
    int tm_wday;
    /* the number of days since January 1, in the range 0 to 365 */
    int tm_yday;
};

1.2 通过mktime函数 , 计算出从1970年到现在经过的总共秒数,time_t类型的变量来接收返回值,伪代码如下

time_t timep = mktime(&tm);//当前的tm结构体里的年月日时分秒都已经赋值过

1.3 把mktime计算出来的秒填到tv结构体里的tv_sec域,伪代码如下

struct timeval {
    time_t      tv_sec;     /* seconds */
    long        tv_usec;    /* microseconds */
};

tv.tv_sec = timep;

tv.tv_usec = 0;

1.4 调用系统函数settimeofday(&tv, NULL),设置就OK了 ,

settimeofday函数的原型是 int settimeofday(const struct timeval *tv, struct timezone *tz);  参数tv表示时间的结构体,参数tz表示当地时区(如DST_USA,DST_AUST等等),如果对tz或者tv其中一项不感兴趣, 直接像我一样填NULL就行了。

需要注意的是 ,  settimeofday这个函数只能由root用户调用 , 如果其他用户调用的话会报错EPERM, 即权限不够。


2 代码:

#include <stdio.h>
#include <time.h> //struct tm
#include <sys/time.h>// struct timeval

int main(void)
{
// Set time 需要的struct tm和struct timeval两个结构体以及一个time_t类型
    struct tm set_tm;
    struct timeval set_tv;
    time_t timep;
//1 填充struct tm结构体的实例
    set_tm.tm_year = 2018 - 1900;
    set_tm.tm_mon = 6 - 1;
    set_tm.tm_mday = 10; 
    set_tm.tm_hour = 15; 
    set_tm.tm_min = 55; 
    set_tm.tm_sec = 5;
//2 通过mktime函数把struct tm结构体里的值转换成秒
    timep = mktime(&set_tm);
//3 把1970年到现在总共经过的秒数填充到struct timeval的tv_sec项
    set_tv.tv_sec = timep;
    set_tv.tv_usec = 0;
//4 调用settimeofday函数, 设置系统时间
    if (settimeofday(&set_tv, (struct timezone *)0) < 0) {
        printf("set time error !\n");
        return -1; 
    }   

    return 0;
}

运行结果:


第一次./a.out 显示set time error的原因 , 就是因为我不是root用户 , 第二次运行之前加上sudo就设置成功了。

(t是我自己写的一个命令,平时用来显示当前系统时间的)


2 获取系统时间

因为获取系统时间其实也就是设置系统时间的逆向操作, 原理是一样的, gettimeofday函数获取到1970年到现在总共的秒数,然后用localtime函数通过总共秒数来计算出其他成员的值, 逐个填充到struct tm结构体的成员中,所以我就直接上代码了


3 获取系统时间代码:

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

int main(void)
{
    struct tm *get_tm;
    struct timeval get_tv;

    gettimeofday(&get_tv, NULL);
    get_tm = localtime(&get_tv.tv_sec);

    #if 0
    printf("%s \n", asctime(get_tm));
    #else
    printf("year %d mon %d mday %d hour %d min %d sec  %d \n",  get_tm->tm_year + 1900, get_tm->tm_mon + 1,
                                                                get_tm->tm_mday, get_tm->tm_hour,
                                                                get_tm->tm_min , get_tm->tm_sec);
    #endif

    return 0;
}


运行结果如下


上面显示的方式是调用系统的asctime函数把struct tm转换成字符串来显示, 下面是每个成员逐个手动去打印。


最后提醒一下各位小伙伴 , 如果设置了错误的系统时间,可以使用ntp来同步系统时间,我使用的是阿里云的时间服务器,

命令如下  sudo ntpdate ntp.aliyun.com 


猜你喜欢

转载自blog.csdn.net/weixin_38176039/article/details/80641380