13397158231   jevian_ma@worldflying.cn

C语言实现时间与时间戳互转,可用于单片机

2021-06-24 20:46:40

小沃最近写代码遇到需要在单片机中使用时间与时间戳互转的需求,随即自己写了一个,使用方法尽可能的模仿linux c中的mktime与localtime函数,代码如下:

time.h

#ifndef __TIME_H__
#define __TIME_H__
struct tm {
    int tm_year; // 年份,其值等于实际年份减去1900
    int tm_mon; // 月份(从一月开始,0代表一月) - 取值区间为[0,11]
    int tm_mday; // 一个月中的日期 - 取值区间为[1,31]
    int tm_hour; // 时 - 取值区间为[0,23]
    int tm_min; // 分 - 取值区间为[0,59]
    int tm_sec; // 秒 – 取值区间为[0,59]
    int tm_wday; // 一周中的第几天 – 取值区间为[0,6]
    int tm_yday; // 一年中的第几天 – 取值区间为[0,365]
};
void localtime(unsigned long timestamp, struct tm *t);
unsigned long mktime(struct tm *t);
#endif

time.c

#include "time.h"
static unsigned int mon_yday[2][12] = {
    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 },
    { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 },
};
static unsigned char isleap(unsigned int year) {
    return (year%4==0 && year%100!=0) || (year%400==0) ? 1 : 0;
}
void localtime(unsigned long timestamp, struct tm *t) {
    unsigned int year = 1970;
    unsigned char mon = 0;
    unsigned char leap;
    unsigned char week = (timestamp%(7*24*3600))/(24*3600)+3;
    if (week > 6) {
        week -= 7;
    }
    t->tm_wday = week;
    // 取秒时间
    t->tm_sec = timestamp % 60;
    timestamp /= 60;
    // 取分钟时间
    t->tm_min  = timestamp % 60;
    timestamp /= 60;
    // 小时数
    t->tm_hour = timestamp % 24;
    timestamp /= 24;
    // 计算年份
    while (1) {
        if (isleap(year)) {
            if (timestamp < 366) {
                break;
            }
            timestamp -= 366;
        } else {
            if (timestamp < 365) {
                break;
            }
            timestamp -= 365;
        }
        year++;
    }
    t->tm_year = year-1900;
    t->tm_yday = timestamp;
    // 计算月分
    leap = isleap(year);
    for (mon = 0 ; mon < 12 ; mon++) {
        if (timestamp < mon_yday[leap][mon]) {
            break;
        }
    }
    mon--;
    timestamp -= mon_yday[leap][mon];
    t->tm_mon = mon;
    t->tm_mday = timestamp+1; // 日期取值为1到31
}
unsigned long mktime(struct tm *t) {
    unsigned int i = 0;
    // 以平年时间计算的秒数
    unsigned int year = t->tm_year + 1900;
    unsigned long result = (year - 1970)*365*24*3600 + (mon_yday[isleap(year)][t->tm_mon]+t->tm_mday-1)*24*3600 + t->tm_hour*3600 + t->tm_min*60 + t->tm_sec;
    // 加上闰年的秒数
    for (i = 1970; i < year; i++) {
        if (isleap(i)) {
            result += 24 * 3600;
        }
    }
    return result;
}
/*
#include <stdio.h>
int main() {
    // 测试1,时间转时间戳
    struct tm t = {
        2021 - 1900,
        6 - 1,
        24,
        18,
        58,
        39
    };
    time_t timestamp = mktime(&t);
    printf("timestamp:%u\n", timestamp);
    // 测试2,时间戳转时间
    struct tm t2;
    localtime(1624536919, &t2);
    printf("%d %d %d %d %d %d %d %d",
        t2.tm_year, t2.tm_mon, t2.tm_mday, t2.tm_hour, t2.tm_min, t2.tm_sec, t2.tm_wday, t2.tm_yday);
    return(0);
}
*/


文章作者:沃航科技

优秀产品推荐:可编程网络IO控制器

上一篇:vscode常用编辑预设置

下一篇:debian通过纯命令安装kvm虚拟机的方法

联系我们

  • 地址:武汉市东湖高新开发区光谷总部国际1栋2412室
  • QQ:932773931
  • 电话:027-59761089-806
  • 手机:13397158231
  • 邮箱:jevian_ma@worldflying.cn

关注公众号

扫码添加微信

沃航(武汉)科技有限公司版权所有

备案号:鄂ICP备16014230号-1

本网站由提供CDN加速/云存储服务