C语言 UTC时间tm结构体转当地时间信息

今天遇到个问题,需求如题所示,本来以为直接用time.h提供的各个函数可以解决,但是折腾了半天发现不太可行,只有当地时间转UTC的。而tm结构体转time_t类型的mktime函数又自带时区属性。所以写下博客,让大家以后可以参考参考此方法。

主要是利用gmtime_r和localtime_r手动计算时区差异,使用int类型,保证可正可负。

系统调用较多,效率可能较低,或者可以不获取此时时间,利用utcStrBuf的信息,来计算本地时间和对应UTC时间,得到差值,这样localtime_r可以少调用一次

#include <stdio.h>
#include <time.h>
#include <string.h>

int main()
{
    // 需要求得此时间对应的时区时间
    char utcStrBuf[] = "2021/12/27_22:30:20.369";
    char localStrBuf[30]={0}; 

    printf("utcStrBuf = %s\n",utcStrBuf);

    // 计算时区差值
    time_t now = time(NULL);

    struct tm utcTm;
    struct tm locTm;

    memset(&utcTm,0,sizeof(utcTm));
    memset(&locTm,0,sizeof(locTm));
    gmtime_r(&now,&utcTm);
    localtime_r(&now,&locTm);
    int dTime = difftime(mktime(&locTm),mktime(&utcTm));

/*
    struct tm {
        int tm_sec;    // Seconds (0-60) 
        int tm_min;    // Minutes (0-59) 
        int tm_hour;   // Hours (0-23) 
        int tm_mday;   // Day of the month (1-31) 
        int tm_mon;    // Month (0-11)
        int tm_year;   // Year - 1900 
        int tm_wday;   // Day of the week (0-6, Sunday = 0) 
        int tm_yday;   // Day in the year (0-365, 1 Jan = 0) 
        int tm_isdst;  // Daylight saving time 
    };
*/

    memset(&utcTm,0,sizeof(utcTm));
    memset(&locTm,0,sizeof(locTm));

    // 根据utcStr得到utc的tm结构体
    int milliseconds = 0;   // tm结构体没有毫秒信息,保存起来
    sscanf(utcStrBuf,"%d/%d/%d_%d:%d:%d.%d",&(utcTm.tm_year),&(utcTm.tm_mon),&(utcTm.tm_mday),&(utcTm.tm_hour),&(utcTm.tm_min),&(utcTm.tm_sec),&milliseconds);
    utcTm.tm_mon -=1;
    utcTm.tm_year -=1900;

    time_t locTime = mktime(&utcTm) + dTime;
    localtime_r(&locTime,&locTm);
    //snprintf(localStrBuf,30,"%d/%d/%d_%d:%d:%d.%d",locTm.tm_year+1900,locTm.tm_mon+1,locTm.tm_mday,locTm.tm_hour,locTm.tm_min,locTm.tm_sec,milliseconds);
    char tmStr[25] = {0};
    strftime(tmStr,25,"%Y/%m/%e_%H:%M:%S", &locTm);//以年月日_时分秒的形式表示当前时间
    snprintf(localStrBuf,30,"%s.%d",tmStr,milliseconds);
    printf("localStrBuf = %s\n",localStrBuf);


    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值