精选文章 RT-thread之RTC时间的获取

RT-thread之RTC时间的获取

作者:guangod 时间: 2020-08-05 04:50:02
guangod 2020-08-05 04:50:02

开启RTC后,用rt-thread官方给的例程,可以正确打印时间了,但如何使用时间的数值呢?比如要判断是白天和晚上的时间??官方没有给出说明,但前面说过,rt-thread与linux操作很相似,和时间相关time.h也是兼容ANSIC的。所以关于时间的获取这块,可以参考linux时间的用法。下面简要说明下linux时间几种使用方式。

RT-thread之RTC时间的获取1

 linux下常用的几个时间函数:asctime,  ctime, gmtime, localtime, gettimeofday ,mktime, asctime_r, ctime_r, gmtime_r, localtime_r,看了下time.h中相关,rt-thread基本上也都有。

我们可以找到下列四种表示“时间”的结构体

/* Returned by `time'. */
typedef __time_t time_t;  //time_t 是一个长整型,用来表示秒数。
 
/* A time value that is accurate to the nearest
   microsecond but also has a range of years. */
struct timeval
{
    __time_t tv_sec;       /* Seconds. */
    __suseconds_t tv_usec; /* Microseconds. */
};
 
struct timespec
{
    __time_t tv_sec;        /* Seconds. */
    long int tv_nsec;       /* Nanoseconds. */
};

struct timezone
{
    int tz_minuteswest;     /* minutes west of Greenwich */
    int tz_dsttime;         /* type of DST correction */
};
int tz_minuteswest;     /* 格林威治时间往西方的时差 */
int tz_dsttime;         /*  时间的修正方式*/  
 
struct tm
{
  int tm_sec;            /* Seconds.    [0-60] (1 leap second) */
  int tm_min;            /* Minutes.    [0-59] */
  int tm_hour;           /* Hours.    [0-23] */
  int tm_mday;           /* Day.        [1-31] */
  int tm_mon;            /* Month.    [0-11] */
  int tm_year;           /* Year    - 1900. */
  int tm_wday;           /* Day of week.    [0-6] */
  int tm_yday;           /* Days in year.[0-365]    */
  int tm_isdst;          /* DST.        [-1/0/1]*/
 
#ifdef    __USE_BSD
  long int tm_gmtoff;        /* Seconds east of UTC. */
  __const char *tm_zone;     /* Timezone abbreviation. */
#else
  long int __tm_gmtoff;       /* Seconds east of UTC. */
  __const char *__tm_zone;    /* Timezone abbreviation. */
#endif
};

其中:

time_t 是一个长整型,用来表示秒数。

struct timeval 结构体是用秒和微妙来表示时间。

struct timespec 结构体是用秒和纳秒来表示时间。

struct timezone结构体用格林尼治时间来表示。

struct tm 直接用秒、分、小时、天、月、年等来表示时间。

很显然它们的精度是各不相同的。供各种不同的需要提供各种不同的选择。

获取时间的方法:

#include

time_t time(time_t *timer);

此函数会返回从公元1970年1月1日的UTC时间从0时0分0秒算起到现在所经过的秒数。如果t 并非空指针的话,此函数也会将返回值存到t指针所指的内存。

参数说明:

参数说明: timer=NULL时得到当前日历时间(从1970-01-01 00:00:00到现在的秒数),timer=时间数值时,用于设置日历时间,time_t是一个unsigned long类型。如果 timer不为空,则返回值也存储在变量 timer中。

函数功能: 得到当前日历时间或者设置日历时间

#include 
#include 
#include 

int main()
{
    time_t seconds;

    seconds = time((time_t *)NULL);
    printf("%d\n", seconds);

    return 0;
}

 

#include

int gettimeofday(struct timeval *tv, struct timezone *tz);

可以获取精确到微秒当前距离1970-01-01 00:00:00 +0000 (UTC)的微秒数。

//gettimeofday函数获取当前时间存于tv结构体中,相应的时区信息则存于tz结构体中
//需要注意的是tz是依赖于系统,不同的系统可能存在获取不到的可能,因此通常设置为NULL

#include 
#include 
#include 

int main()
{
    struct timeval tv;

    gettimeofday(&tv, NULL);

    printf("tv_sec: %d\n", tv.tv_sec);
    printf("tv_usec: %d\n", tv.tv_usec);

    return 0;
}

 

#include

int clock_gettime(clockid_t clk_id, struct timespec *tp);

可以获取精确到纳秒当前距离1970-01-01 00:00:00 +0000 (UTC)的纳秒数。

如以下例子:

#include 
#include 
 
int main()
{
        struct timespec ts;
 
        clock_gettime(CLOCK_REALTIME, &ts);
        printf("%.24s %ld Nanoseconds\n", ctime(&ts.tv_sec), ts.tv_nsec);
 
        return 0;
}

 

此三种方法比较常用。

#include

struct tm *localtime(const time_t *timep);

struct tm *localtime_r(const time_t *timep, struct tm *result);

取得当地目前时间和日期

/*该函数将有time函数获取的值timep转换真实世界所使用的时间日期表示方法,然后将结果由结构tm返回*/

/**需要注意的是localtime函数可以将时间转换本地时间,但是localtime函数不是线程安全的。
多线程应用里面,应该用localtime_r函数替代localtime函数,因为localtime_r是线程安全的**/

如下面例子:

#include 
#include 
#include 

int main()
{
    time_t timep;
    struct tm *p;

    time(&timep);
    p = localtime(&timep);

    printf("%d-%d-%d %d:%d:%d\n", (1900 + p->tm_year), ( 1 + p->tm_mon), p->tm_mday,
                                (p->tm_hour + 12), p->tm_min, p->tm_sec);

    return 0;
}

 

关于时间的格式化输出:

#include

struct tm *gmtime(const time_t *timep);
struct tm *gmtime_r(const time_t *timep, struct tm *result);

char *asctime(const struct tm *tm);
char *asctime_r(const struct tm *tm, char *buf);

将时间和日期以字符串格式返回
/**gmtime是把日期和时间转换为格林威治(GMT)时间的函数。将参数time 所指的time_t 结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果由结构tm返回**/

/**asctime 将时间以换为字符串字符串格式返回 **/

#include 
#include 
#include 

int main()
{
    time_t timep;
    time(&timep);

    printf("%s\n", asctime(gmtime(&timep)));

    return 0;
}

 

#include

char *ctime(const time_t *timep);
char *ctime_r(const time_t *timep, char *buf);

将时间和日期以字符串格式表示

/**ctime()将参数timep所指的time_t结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果以字符串形态返回**/ 

#include 
#include 
#include 

int main(void)
{
    time_t timep;

    time(&timep);
    printf("%s\n", ctime(&timep));

    return 0;
}

 

#include

sizt_t strftime(char *s, size_t max, const char *format, const struct tm *tm);

很显然,要严格控制时间的输出格式,只能用strftime函数,但是该函数只能对struct tm表示的时间进行输出,所以这里要涉及到struct timeval, struct timespec, time_t等表示的时间如何转换成struct tm的形式。另外因为strutc tm只能精确到秒,所i毫秒、微秒、纳秒只能另外进行输出了。

所以,我们采取的方式是:

首先将struct timeval, struct timespec等转换成time_t表示的秒数;

struct timeval tv;

struct timespec ts;

time_t sec_tv = tv.tv_sec;

time_t sec_ts = ts.ts_sec;

然后利用下列函数将time_t转换成struct tm,

1

2

struct tm *gmtime(const time_t *timep);

struct tm *gmtime_r(const time_t *timep, struct tm *result);

或者:

1

2

struct tm *localtime(const time_t *timep);

struct tm *localtime_r(const time_t *timep, struct tm *result);

最后利用strftime函数进行格式化,得到最后的时间字符串。至于毫秒、微秒、纳秒另外用进行输出。如:

#include 
#include 
#include 
 
int main()
{
        struct timeval tv;
        char strTime[32];
 
        gettimeofday(&tv, NULL);
        struct tm *ptm = gmtime(&tv.tv_sec);  //将秒转换成struct tm的形式
        strftime(strTime, 32, "%F %T", ptm);
        printf("%s ", strTime); //输出精确到秒
        printf("%ld Micorseconds\n", (long)tv.tv_usec); //输出微秒
 
        return 0;
}

另:

形如gmtime和形如gmtime_t函数的区别是,gmtime获得的返回的结果存在于一个static的struct tm型的变量中,可能被后面的gmtime调用覆盖掉,如果要防止覆盖,我们可以自己提供一个struct tm 型的变量,利用gmtime_r函数,将我们自己定义的变量的地址传进去,将结果保存在其中。这样就可以避免覆盖。

关于ctime和asctime等函数得到的时间字符串,它具有指定的形如("Wed Jun 30 21:49:08 1993\n")的格式,所以不利与我们不能进行格式化。注意该格式的最后具有换行符:'\n'.

 

 #include   

time_t mktime(struct tm *tm);  

/**将时间结构体struct tm的值转化为经过的秒数**/

#include 
#include 
#include 

int main()
{
    time_t timep;
    struct tm *p;

    time(&timep);
    p = localtime(&timep);
    timep = mktime(p);

    printf("%d\n", timep);

    return 0;
}

 

勿删,copyright占位
分享文章到微博
分享文章到朋友圈

上一篇:Android Studio 本地项目提交到Github

下一篇:AAX交易所2020年7月经营月报

您可能感兴趣

  • RT-Thread智能车目标识别系统连载教程——手写体识别模型 (1)

    前言 这篇文档非常长所以我们会分成5篇来连载,因为机器学习并不是纯软件开发,简单地调用库函数 API,需要有一定的理论支撑,如果完全不介绍理论部分,可能就不知道为什么模型要这样设计,模型出了问题应该怎样改善。不过文档如果写太长大家可能很难有耐心看完,特别是理论部分会有很多公式,但是机器学习确实又对 理论基础 和 编程能力 都有一些要求,相信坚持看下去还是会有很多收获的,我也尽可能把理论和应用...

  • Python个人笔记

    目录 前言 查看Python以及第三方包安装位置 Python打包成exe 安装pyinstaller打包工具 打包 Python操作json 储存json 读取json 中文问题 倒计时关闭程序 Python递归之return None 多个not in的写法 截取字符串 计算长度或者数量len() Python操作MongoDB 配置连接MongoDB 插入数据 查询数据 VS Code...

  • Cache 的基本概念与工作原理

    1.背景知识 随着 CPU 技术的飞速发展,常用的处理器飞奔在越来越高的频率之上,虽然处理器的速度越来越快,但是与之相匹配的存储器的速度却没有获得相应的提升,这大大限制了 CPU 的处理性能。而我们本系列文档所介绍的主角 Cache 技术就是用来解决这个难题的。 在 ARM 发布 Cortex-M7 架构之后,微控制器领域也出现了频率高达数百兆的芯片,如 ST 的 STM32F7 系列和 N...

  • 焦虑的 BAT、不安的编程语言,揭秘程序员技术圈生存现状!

    【编者按】在迭代不休的技术圈中,仅在过去的一个月期间,我们见证了有史以来第一张黑洞照片的诞生;经历了为让人义愤填膺的 996;思考了作为程序员的年龄之槛;膜拜了技术大神的成长历程;追逐了如编程语言、人工智能和区块链的热门技术;探讨了科技巨头们的改革之道…… 而这对我们程序员而言,究竟意味着什么? 出品 | CSDN(ID:CSDNnews) 互联网变革如影,技术境迁如梭,再回首,似有隔世之感...

  • 各种面试题(一)

    1.说说你对缓存的理解? 1.使用缓存的目的: 提高应用程序的性能,减少到数据库的访问次数 2.缓存的介质(缓存的存储位置) 内存:临时性存储空间 存取数据快 减少网络通信量 硬盘:永久性存储空间 存取速度慢 3.缓存的分类 客户端缓存:浏览器 服务器缓存:oscache,redis,memcache 4.缓存什么样的数据? 经常访问,又不经常修改的数据 5.缓存的有效性 为了避免脏数据的产...

  • 转载 mpls ***

    原帖地址: http://support.huawei.com/huaweiconnect/enterprise/thread-294983.html 1 BGP/MPLS IP ×××横空出世 由于当时MPLS技术基于标签转发大大提升了路由器的转发效率,在很长的一段时间MPLS一直独步武林,无人匹敌。最重要的是,MPLS可以承载任意协议类型的报文,使得其与众多帮派相处融洽。不过好景不长,由...

  • 5-Kafka 0.10.0 SASL/PLAIN身份认证及权限实现

    2019独角兽企业重金招聘Python工程师标准>>> 本文主要介绍一下使用官方发布的 Kafka 0.10.0 版如何实现 SASL/PLAIN 认证机制以及权限控制。 Kafka 安全机制 Kafka 的安全机制主要分为两部分: 身份认证(Authentication):对client 与服务器的连接进行身份认证。 权限控制(Authorization):实现对于消息级别的权限控制 In...

  • mysql配置文件my.cnf的事例并附解释

    #更改磁盘调度算法 echo 'deadline' >/sys/block/xvdb/queue/scheduler #关掉NUMA特性 #numactl --interleave=all 下面是my.cnf [client] port = 3306 socket = /tmp/mysql.sock [mysqld_safe] #google优化过的内存分配模块,这个模块可以让MySQL在高...

华为云40多款云服务产品0元试用活动

免费套餐,马上领取!
CSDN

CSDN

中国开发者社区CSDN (Chinese Software Developer Network) 创立于1999年,致力为中国开发者提供知识传播、在线学习、职业发展等全生命周期服务。