通过GPS模块可以得到UTC时间,但如何将UTC时间转换成你所在地的本地时间呢?下面介绍一种自己曾经使用过并得到过验证的计算方法:
前提:已知UTC时间,经纬度
一、首先通过经纬度来计算出所在地时区
// 计算时区函数,根据经度来计算
static int calculateTimezone(double lat,double lon){
int a,b,c,timezone;
a = (int)(fabs(lon)+0.5);// 对经度进行四舍五入,且取正整数
b = a/15; // 商
c = a%15; // 余数
if((lat >=17.9 && lat <=53 && lon>=75 && lon<=125) || (lat>=40 && lat <=53 && lon>=125 && lon<= 135)){// 如果经纬度处于中国版图内,则都划为东8区,为什么要这样划分详见第三节
timezone = 8;
}
else{
if(c > 7.5)
timezone = b+1;
else
timezone = b;
if(lon > 0.0f)
timezone = timezone;
else
timezone = (-1)*timezone;
}
return timezone;
}
二、将UTC时间转换为本地时间
// UTC时间转换为本地时间函数
static void UTCTOLocalTime(int timezone){
int year,month,day,hour;
int lastday = 0;// 月的最后一天的日期
int lastlastday = 0;// 上月的最后一天的日期
year = gpsData.UTCTime.year; //已知的UTC时间
month = gpsData.UTCTime.month;//已知的UTC时间
day = gpsData.UTCTime.day;//已知的UTC时间
hour = gpsData.UTCTime.hour + timezone; //已知的UTC时间
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))//判断是否为闰年,年号能被400整除或年号能被4整除,而不能被100整除为闰年
lastlastday = 29;// 闰年的2月为29天,平年为28天
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))// 闰年的2月为29天,平年为28天
lastday = 29;
else
lastday = 28;
}
if(hour >= 24){// 当算出的区时大于或等于24:00时,应减去24:00,日期加一天
hour -= 24;
day += 1;
if(day > lastday){ // 当算出的日期大于该月最后一天时,应减去该月最后一天的日期,月份加上一个月
day -= lastday;
month += 1;
if(month > 12){// 当算出的月份大于12时,应减去12,年份加上一年
month -= 12;
year += 1;
}
}
}
if(hour < 0){// 当算出的区时为负数时,应加上24:00,日期减一天
hour += 24;
day -= 1;
if(day < 1){ // 当算出的日期为0时,日期变为上一月的最后一天,月份减去一个月
day = lastlastday;
month -= 1;
if(month < 1){ // 当算出的月份为0时,月份变为12月,年份减去一年
month = 12;
year -= 1;
}
}
}
//得到转换后的本地时间
gpsData.localTime.year = year;
gpsData.localTime.month = month;
gpsData.localTime.day = day;
gpsData.localTime.hour = hour;
}
三、关于世界时区的划分与北京时间的统一
http://map.ps123.net/world/UploadFile/201501/2015012722245397.jpg
从上图可以看出,中国横跨东五区、东六区、东七区、东八区、东九区等五个地理时区。北京时间是中国采用北京所在的东八时区的区时作为标准时间。那么问题来了,由于中国统一采用的是北京时间,而程序中将UTC时间转换成本地时间时,计算时区是根据经度来计算的,这样就会将中国划分为5个时区,为了让全国人民采用北京时间,将中国版图内的所有时区都划为东八区,如下图所示
上图中,红色矩形内的所有地区都统一划为东八区,也即是:
北纬17.9度~北纬53度,东经75度~东经125度 的区域
北纬40度~北纬53度,东经125度~东经135度 的区域
这样划分之后,除中国新疆乌鲁克恰提,靠近塔吉克斯坦和阿富汗的部分地区和部分岛屿外,所有中国版图内的地区都属于东八区,使用的是北京时间。
但这样划分的后果是,印度,孟买,印尼,东南亚各国,部分俄罗斯地图和部分朝鲜地区,都被使用的北京时间。
根据经度来计算时区的方法虽然正确,但全球很多国家由于采用统一的国家时间,他们所使用的时区并不是他们地理位置的真正时区,这个问题是无法解决的,只能说先满足中国再说。