RT 您所在的位置:网站首页 STM32时钟RTC获取当前时间 RT

RT

2024-07-11 14:02| 来源: 网络整理| 查看: 265

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

 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 2018-2019 实验室设备网 版权所有