通俗易懂----C语言时间日期与时间戳互相转化

前言:如果你也对时间转化的高效代码而苦恼,不妨看看以下内容,一定会给你带来良好的体验和启迪。

1.时间戳含义

1.1时间戳是衡量时间的一种标准,用来特定电子数据提供一个绑定时间戳,从而有效地证明该电子数据的产生时间及未被修改,常用于保、防伪等手段。

1.2时间戳具有唯一性,来自与权威机构的统计,间戳取证服务系统由联合信任时间戳服务中心提供,该中心是国家授时中心和联合信任共同创建的我国唯一权威可信时间戳服务机构(TSA)而非用户自定义的时间。

1.3时间戳单位

unix时间戳 单位:秒(s)

毫秒时间戳 单位:毫秒(ms)

2.时间转换代码

#include 

typedef unsigned short  uint16_t;
typedef unsigned int    uint32_t;

const uint16_t month_days_table[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

/**
* @brief        日期结构体对象
*/
typedef struct {
    uint16_t year;
    uint16_t month;
    uint16_t day;
    uint16_t hour;
    uint16_t min;
    uint16_t sec;
}date_time_t;

/**
* @brief        判断是否为闰年
* @param        [in] year 年
* @retval       1 为闰年
* @retval       0 为平年
*/
uint16_t fml_leap_year(uint16_t year)
{
    return (((year % 4 == 0)&&(year % 100 != 0)) || (year % 400 == 0));
}


/**
* @brief        日期转时间戳
* @param        [in] date 日期值
* @retval       =0 成功
* @retval       非0 失败,以及失败原因
*/
uint32_t fml_time_to_stamp(date_time_t date)
{
    static  uint32_t dax = 0;
    static  uint32_t day_count = 0;
    uint16_t leap_year_count = 0;
    uint16_t i;

    // 计算闰年数
    for (i = 1970; i < date.year; i++)
    {
        if (fml_leap_year(i))
        {
            leap_year_count++;
        }
    }

    // 计算年的总天数
    day_count = leap_year_count * 366 + (date.year - 1970 - leap_year_count) * 365;

    // 累加计算当年所有月的天数
    for (i = 1; i < date.month; i++)
    {
        if ((2 == i) && (fml_leap_year(date.year)))
        {
            day_count += 29;
        }
        else
        {
            day_count += month_days_table[i];
        }
    }

    // 累加计算当月的天数
    day_count += (date.day - 1);

    dax = (uint32_t)(day_count * 86400) + (uint32_t)((uint32_t)date.hour * 3600) + (uint32_t)((uint32_t)date.min * 60) + (uint32_t)date.sec;

    /* 北京时间补偿 */
    dax = dax - 8*60*60;

    return dax;
}



/**
* @brief        时间戳转化为日期
* @param        [in] date 日期值
* @retval       =0 成功
* @retval       非0 失败,以及失败原因
*/
uint32_t fml_stamp_to_time( uint32_t timep, date_time_t *date)
{
    uint32_t days = 0;
    uint32_t rem = 0;

    /* 北京时间补偿 */
    timep = timep + 8*60*60;

    // 计算天数
    days = (uint32_t)(timep / 86400);
    rem = (uint32_t)(timep % 86400);


    // 计算年份
    uint16_t year;
    for (year = 1970; ; ++year)
    {
        uint16_t leap = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
        uint16_t ydays = leap ? 366 : 365;
        if (days < ydays)
        {
            break;
        }
        days -= ydays;
    }
    date->year  =  year;


    // 计算月份
    static const uint16_t days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    uint16_t month;
    for (month = 0; month < 12; month++)
    {
        uint16_t mdays = days_in_month[month];
        if (month == 1 && ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0))
        {
            mdays = 29;
        }
        if (days < mdays)
        {
            break;
        }
        days -= mdays;
    }
    date->month = month;
    date->month += 1;

    // 计算日期
    date->day = days + 1;

    // 计算时间
    date->hour = rem / 3600;
    rem %= 3600;
    date->min = rem / 60;
    date->sec = rem % 60;

    return 0;
}

int main()
{
    uint32_t err = 0;
    uint32_t stamp = 0;

    date_time_t data1;
    //结构体初始化赋值 
    date_time_t data = {
        .year = 2023,
        .month = 6,
        .day = 26,
        .hour = 16,
        .min = 47,
        .sec = 12
    };

    stamp = fml_time_to_stamp(data);

    fml_stamp_to_time(stamp,&data1);

    printf("stamp = %d\n",stamp);

    printf("year=%d,month=%d,day=%d,hour=%d,min=%d,sec=%d\n",data1.year,data1.month,data1.day,data1.hour,data1.min,data1.sec);


return err;

}

3.测试验证demo

通俗易懂----C语言时间日期与时间戳互相转化_第1张图片

        可以看出,打印的时间格式与时间戳可以互相转化,说明我们两个函数接口都是正常的;温馨提示:如果所在的时间业务在国外,就要化为国际通用时间,将代码中的北京时间补偿屏蔽即可;北京时间根据纬度区间会比通用国际时间母线多8个小时,最后各位看官如果觉得不错的话,可以点赞鼓励一下哦亲。

你可能感兴趣的:(c语言,开发语言)