专栏名称: 嵌入式微处理器
关注这个时代最火的嵌入式微处理器,你想知道的都在这里。
目录
相关文章推荐
阿拉善宏桥信息网  ·  2025.02.23更新【5】家政服务、生活 ... ·  10 小时前  
素食星球  ·  椰香四溢的纯素雪花酥,颠覆传统的味蕾体验 ·  17 小时前  
素食星球  ·  椰香四溢的纯素雪花酥,颠覆传统的味蕾体验 ·  17 小时前  
赛博禅心  ·  超级硬广:输入 ikun,解锁 ... ·  昨天  
赛博禅心  ·  超级硬广:输入 ikun,解锁 ... ·  昨天  
51好读  ›  专栏  ›  嵌入式微处理器

Linux C语言时间相关知识总结

嵌入式微处理器  · 公众号  ·  · 2024-11-28 12:00

正文

对于嵌入式工程师,在实际开发中经常要 获取各种 时间。下面汇总了6个常用的时间接口,希望能对大家有所帮助

1、clock_gettime

#include 

/**
 * @brief 根据系统时钟的类型,获取当前时间
 *
 * Detailed function description
 *
 * @param[in] __clock_id: 系统时钟的类型。常用取值:
                          - CLOCK_REALTIME: 从1970年1月1日到目前的时间
                          - CLOCK_MONOTONIC: 系统启动时间
                          - CLOCK_PROCESS_CPUTIME_ID: 本进程运行时间
                          - CLOCK_THREAD_CPUTIME_ID: 本线程运行的时间
 * @param[out] __tp: 存放当前的时间。
 *
 * @return 成功则返回0,失败则返回-1
 */

int clock_gettime (clockid_t __clock_id, struct timespec *__tp);

timespec结构体:

struct timespec
{

  __time_t tv_sec;  /* Seconds. 秒 */
  __syscall_slong_t tv_nsec; /* Nanoseconds.  纳秒*/
};

例子:

#include 
#include 
#include 

long long get_clock_sys_time_ns(void)
{
    struct timespec tp;
    long long time_ns = 0;

    clock_gettime(CLOCK_MONOTONIC, &tp);
    time_ns = (long long)tp.tv_sec * 1000000000 + tp.tv_nsec;

    return time_ns;
}

int main(void)
{
    struct timespec tp;

    ///< 获取从1970年1月1日到目前的时间
    memset(&tp, 0sizeof(struct timespec));
    clock_gettime(CLOCK_REALTIME, &tp);
    printf("clock_id = CLOCK_REALTIME, sec = %ld, nsec = %ld\n", tp.tv_sec, tp.tv_nsec);

    ///< 获取系统启动时间
    memset(&tp, 0sizeof(struct timespec));
    clock_gettime(CLOCK_MONOTONIC, &tp);
    printf("clock_id = CLOCK_MONOTONIC, sec = %ld, nsec = %ld, sys_time = %lld ns\n", tp.tv_sec, tp.tv_nsec, get_clock_sys_time_ns());

    ///< 获取本进程运行时间
    memset(&tp, 0sizeof(struct timespec));
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp);
    printf("clock_id = CLOCK_PROCESS_CPUTIME_ID, sec = %ld, nsec = %ld\n", tp.tv_sec, tp.tv_nsec);

    ///< 获取本线程运行时间
    memset(&tp, 0sizeof(struct timespec));
    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp);
    printf("clock_id = CLOCK_THREAD_CPUTIME_ID, sec = %ld, nsec = %ld\n", tp.tv_sec, tp.tv_nsec);

    return 0;
}

编译、运行:

2、gettimeofday

#include 

/**
 * @brief 获取当前时间(从1970年1月1日到目前的时间)
 *
 * Detailed function description
 *
 * @param[out] tv: 当前UTC时间
 * @param[out] tz: 当前时区信息
 *
 * @return 成功则返回0,失败则返回-1
 */

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

timeval结构体:

struct timeval
{

  __time_t tv_sec;  /* Seconds.  秒*/
  __suseconds_t tv_usec; /* Microseconds.  微秒*/
};

timezone结构体:

struct timezone
  {

    int tz_minuteswest;  /* Minutes west of GMT. 和Greenwich时间差了多少分钟 */
    int tz_dsttime;  /* Nonzero if DST is ever in effect. 日光节约时间的状态  */
  };

例子:

#include 
#include 
#include 

long long get_sys_time_ms(void)
{
    long long time_ms = 0;
    struct timeval tv;

    gettimeofday(&tv, NULL);
    time_ms = ((long long)tv.tv_sec*1000000 + tv.tv_usec) / 1000;

    return time_ms;
}

int main(void)
{
    ///< 获取系统时间
    printf("sys_time = %lld ms\n", get_sys_time_ms());

    return 0;
}

编译、运行:

3、time

#include




    
 

/**
 * @brief 获取1970-01-01 00:00:00 +0000至今的秒数(UTC)
 *
 * Detailed function description
 *
 * @param[out] tloc: 返回的秒存储指针
 *
 * @return 成功则返回秒数,失败则返回-1,错误原因存在errno中。
 */

time_t time(time_t *tloc);

time_t的类型:

typedef long time_t;

例子:

#include 
#include 

time_t get_utc_time(void)
{
    return time(NULL);
}

int main(int argc, char **argv)
{
    time_t utc_time = get_utc_time();
    printf("utc_time = %ld s\n", utc_time);

    return 0;
}

编译、运行:

4、localtime

#include 

/**
 * @brief 将time_t类型的时间转换为struct tm类型的时间
 *
 * Detailed function description
 *
 * @param[in] timep: 当前UTC秒数
 *
 * @return 返回当地时间
 */

struct tm *localtime(const time_t *timep);

tm结构体:

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] 注意:0代表1月,以此类推*/
  int tm_year;   /* Year - 1900.  该值为实际年份减去1900*/
  int tm_wday;   /* Day of week. [0-6] 注意:0代表星期一,以此类推*/
  int tm_yday;   /* Days in year.[0-365] 从每年的1月1日开始的天数,其中0代表1月1日,以此类推*/
  int tm_isdst;   /* DST.  [-1/0/1] 夏玲时标识符*/
};

例子:

#include 
#include 

time_t get_utc_time(void)
{
    return time(NULL);
}

int main(int argc, char **argv)
{
    time_t utc_time = get_utc_time();
    printf("utc_time = %ld s\n", utc_time);

    struct tm *local_tm = localtime(&utc_time); 
    printf("local time = %.4d-%.2d-%.2d %.2d:%.2d:%.2d\n", local_tm->tm_year + 1900,
                                                           local_tm->tm_mon + 1,
                                                           local_tm->tm_mday,
                                                           local_tm->tm_hour,
                                                           local_tm->tm_min,
                                                           local_tm->tm_sec);

    return 0;
}

编译、运行:

5、localtime_r

#include 

/**
 * @brief 将time_t类型的时间转换为struct tm类型的时间
 *
 * Detailed function description
 *
 * @param[in] timep: 当前UTC秒数
 * @param[out] timep: 当地时间
 *
 * @return 返回当地时间
 */

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

localtime不是一个线程安全的函数,关于线程安全的知识点,看阅读往期文章: 如何理解线程安全?

对于实时性要求较高的系统,多个线程同时调用localtime,可能会造成数据被覆盖。我们项目中之前是用localtime来获取系统时间、日期。并使用这个数据去做逻辑,数据异常导致了逻辑异常。

后面使用localtime_r来替代,问题解决。

例子:

#include 
#include 

time_t get_utc_time(void)
{
    return time(NULL);
}

int main(int argc, char **argv)
{
    time_t utc_time = get_utc_time();
    printf("utc_time = %ld s\n", utc_time);
    struct tm result;
    struct tm *local_tm = localtime_r(&utc_time, &result); 
    printf("local time = %.4d-%.2d-%.2d %.2d:%.2d:%.2d\n", local_tm->tm_year + 1900,
                                                           local_tm->tm_mon + 1,
                                                           local_tm->tm_mday,
                                                           local_tm->tm_hour,
                                                           local_tm->tm_min,
                                                           local_tm->tm_sec);

    printf("result time = %.4d-%.2d-%.2d %.2d:%.2d:%.2d\n", result.tm_year + 1900,
                                                            result.tm_mon + 1,
                                                            result.tm_mday,
                                                            result.tm_hour,
                                                            result.tm_min,
                                                            result.tm_sec);

    return 0;
}

编译、运行:

6、gmtime

#include 

/**
 * @brief 返回tm结构的GMT时间(UTC时间)
 *
 * Detailed function description
 *
 * @param[in] timep: 当前UTC秒数
 *
 * @return 返回当地时间
 */

struct tm *gmtime(const time_t *timep);

例子:

#include 
#include 

time_t get_utc_time(void)
{
    return time(NULL);
}

int main(int argc, char **argv)
{
    time_t utc_time = get_utc_time();
    printf("utc_time = %ld s\n", utc_time);

    struct tm *gmt_tm = gmtime(&utc_time); 
    printf("gmt time = %.4d-%.2d-%.2d %.2d:%.2d:%.2d\n", gmt_tm->tm_year + 1900,
                                                         gmt_tm->tm_mon + 1,
                                                         gmt_tm->tm_mday,
                                                         gmt_tm->tm_hour,
                                                         gmt_tm->tm_min,
                                                         gmt_tm->tm_sec);

    return 0;
}

编译、运行:







请到「今天看啥」查看全文