最近使用GPS模块获取解析GPRMC数据的时候,获取到的是UTC时间,需要转换为北京时间,网上看了一些文章,发现存在一些问题,于是自己完善了一下,并做了注释,方便理解。
typedef struct { uint16_t year; //年份 uint8_t month; //月份 uint8_t date; //日期 uint8_t hour; //小时 uint8_t min; //分钟 uint8_t sec; //秒钟 }*p_nmea_time, s_nmea_time; //UTC时间转换为任意时区时间,如果是转换为北京时间,timezone传8即可 static void utc_to_local_time(p_nmea_time utc_time, int8_t timezone, p_nmea_time local_time) { 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; //1月大,2月小,3月大,4月小,5月大,6月小,7月大,8月大,9月小,10月大,11月小,12月大 if(month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12) { lastday = 31;//本月天数 lastlastday = 30;//这里应该补上上个月的天数 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 || month == 1)//这里应该是8月和1月,因为8月和1月的上一个月(7月和12月)的天数是31天的 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 local_time local_time->year = year; local_time->month = month; local_time->date = day; local_time->hour = hour; local_time->min = utc_time->min; local_time->sec = utc_time->sec; }