c语言utc时间转换北京时间_STM32开发 -- UTC、UNIX时间戳、北京时间之间的转换

我碰到的问题,GPS上UTC时间转北京时间和STM32上UNIX时间戳转北京时间。

这部分之前讲RTC和GPS的时候有涉及到一部分。

具体的RTC如何得到UNIX时间戳,和GNRMC如何解析得到UTC时间可以参看一下。

参看:STM32开发 – RTC详解

参看:STM32开发 – GPS模块开发详解

扩展:C语言再学习 – 时间函数

这里主要看三者转换方法:

一、UTC时间转换为北京时间

参看:UTC时间转换为北京时间

时间类型结构体

//UTC时间信息

__packed typedef struct

{

uint16_t year;//年份

uint8_t month;//月份

uint8_t date;//日期

uint8_t hour; //小时

uint8_t min; //分钟

uint8_t sec; //秒钟

}nmea_time;

UTC时间转任意时区时间

其中,北京时间 = UTC time + 8 hours

void UTC_to_BJtime(nmea_time*utc_time, int8_ttimezone)

{

int year,month,day,hour;

int lastday = 0;//last day of this month

int lastlastday = 0;//last day of last month

year = utc_time->year; //utc time

month  = utc_time->month;

day = utc_time->date;

hour = utc_time->hour + timezone;

if(month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12){

lastday = 31;

if(month == 3){

if((year%400 == 0)||(year%4 == 0 && year%100 != 0))//if this is lunar year

lastlastday = 29;

else

lastlastday = 28;

}

if(month == 8)

lastlastday = 31;

}

else if(month == 4 || month == 6 || month == 9 || month == 11){

lastday = 30;

lastlastday = 31;

}

else{

lastlastday = 31;

if((year%400 == 0)||(year%4 == 0 && year%100 != 0))

lastday = 29;

else

lastday = 28;

}

if(hour >= 24){// if >24, day+1

hour -= 24;

day += 1;

if(day > lastday){ // next month,  day-lastday of this month

day -= lastday;

month += 1;

if(month > 12){//next year , month-12

month -= 12;

year += 1;

}

}

}

if(hour < 0){// if <0, day-1

hour += 24;

day -= 1;

if(day < 1){  // month-1, day=last day of last month

day = lastlastday;

month -= 1;

if(month < 1){ // last year , month=12

month = 12;

year -= 1;

}

}

}

// transfer value to NMEA_result.local_time

NMEA_result.local_time.year  = year;

NMEA_result.local_time.month = month;

NMEA_result.local_time.date  = day;

NMEA_result.local_time.hour  = hour;

NMEA_result.local_time.min = utc_time->min;

NMEA_result.local_time.sec = utc_time->sec;

}

二、UNIX Time 时间戳 与 北京时间 相互转换

参看:UNIX Time 时间戳 与 北京时间 相互转换

typedef struct t_xtime {

int year; int month;  int day;

int hour; int minute;  int second;

} _xtime ;

#define xMINUTE   (60             ) //1分的秒数

#define xHOUR      (60*xMINUTE) //1小时的秒数

#define xDAY        (24*xHOUR   ) //1天的秒数

#define xYEAR       (365*xDAY   ) //1年的秒数

1、将localtime(UTC+8北京时间)转为UNIX TIME,以1970年1月1日为起点

unsigned int  xDate2Seconds(_xtime *time)

{

static unsigned int  month[12]={

/*01月*/xDAY*(0),

/*02月*/xDAY*(31),

/*03月*/xDAY*(31+28),

/*04月*/xDAY*(31+28+31),

/*05月*/xDAY*(31+28+31+30),

/*06月*/xDAY*(31+28+31+30+31),

/*07月*/xDAY*(31+28+31+30+31+30),

/*08月*/xDAY*(31+28+31+30+31+30+31),

/*09月*/xDAY*(31+28+31+30+31+30+31+31),

/*10月*/xDAY*(31+28+31+30+31+30+31+31+30),

/*11月*/xDAY*(31+28+31+30+31+30+31+31+30+31),

/*12月*/xDAY*(31+28+31+30+31+30+31+31+30+31+30)

};

unsigned int  seconds = 0;

unsigned int  year = 0;

year = time->year-1970;       //不考虑2100年千年虫问题

seconds = xYEAR*year + xDAY*((year+1)/4);  //前几年过去的秒数

seconds += month[time->month-1];      //加上今年本月过去的秒数

if( (time->month > 2) && (((year+2)%4)==0) )//2008年为闰年

seconds += xDAY;            //闰年加1天秒数

seconds += xDAY*(time->day-1);         //加上本天过去的秒数

seconds += xHOUR*time->hour;           //加上本小时过去的秒数

seconds += xMINUTE*time->minute;       //加上本分钟过去的秒数

seconds += time->second;               //加上当前秒数

seconds -= 8 * xHOUR;

return seconds;

}

2、将UNIX时间转为UTC+8 即北京时间

//UNIX转为UTC 已进行时区转换 北京时间UTC+8

void xSeconds2Date(unsigned long seconds,_xtime *time )

{

static unsigned int month[12]={

/*01月*/31,

/*02月*/28,

/*03月*/31,

/*04月*/30,

/*05月*/31,

/*06月*/30,

/*07月*/31,

/*08月*/31,

/*09月*/30,

/*10月*/31,

/*11月*/30,

/*12月*/31

};

unsigned int days;

unsigned short leap_y_count;

time->second      = seconds % 60;//获得秒

seconds          /= 60;

time->minute      =  seconds % 60;//获得分

seconds          += 8 * 60 ;        //时区矫正 转为UTC+8 bylzs

seconds          /= 60;

time->hour        = seconds % 24;//获得时

days              = seconds / 24;//获得总天数

leap_y_count = (days + 365) / 1461;//过去了多少个闰年(4年一闰)

if( ((days + 366) % 1461) == 0)

{//闰年的最后1天

time->year = 1970 + (days / 366);//获得年

time->month = 12;              //调整月

time->day = 31;

return;

}

days -= leap_y_count;

time->year = 1970 + (days / 365);     //获得年

days %= 365;                       //今年的第几天

days = 01 + days;                  //1日开始

if( (time->year % 4) == 0 )

{

if(days > 60)--days;            //闰年调整

else

{

if(days == 60)

{

time->month = 2;

time->day = 29;

return;

}

}

}

for(time->month = 0;month[time->month] < days;time->month++)

{

days -= month[time->month];

}

++time->month;               //调整月

time->day = days;

[1] [2]

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页