将GPS获得的UTC时间转换成本地时间的方法

通过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;
        lastlastday = 30;
        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个时区,为了让全国人民采用北京时间,将中国版图内的所有时区都划为东八区,如下图所示 
将GPS获得的UTC时间转换成本地时间的方法_第1张图片

上图中,红色矩形内的所有地区都统一划为东八区,也即是:

北纬17.9度~北纬53度,东经75度~东经125度 的区域 
北纬40度~北纬53度,东经125度~东经135度 的区域

这样划分之后,除中国新疆乌鲁克恰提,靠近塔吉克斯坦和阿富汗的部分地区和部分岛屿外,所有中国版图内的地区都属于东八区,使用的是北京时间。 
但这样划分的后果是,印度,孟买,印尼,东南亚各国,部分俄罗斯地图和部分朝鲜地区,都被使用的北京时间。

根据经度来计算时区的方法虽然正确,但全球很多国家由于采用统一的国家时间,他们所使用的时区并不是他们地理位置的真正时区,这个问题是无法解决的,只能说先满足中国再说。

版权声明:本文为博主原创文章,未经博主允许不得转载。

你可能感兴趣的:(项目管理)