源码分享:将UTC转化为包含夏令时的local time(以欧州中部为例)

来源:岁月联盟 编辑:猪蛋儿 时间:2012-05-23

最近做的一个项目,涉及到GPS NEMA数据中的GPRMC的处理。从中提取的UTC需要转化为更易理解和应用的local time。
直接看源码:
[java]
//Convert the date, assume this is in Europe 
        int date = Integer.parseInt( lineData.get(9) ); 
        int days = date / 10000; 
        int months = ( date / 100 ) % 100; 
        int years = date % 100+2000; 
        String getDate = "Date: "+days+"/"+months+"/"+years+"/r/n"; 
        System.out.println("/n"+getDate); 
         
        //Convert the time, assume this is in Europe 
        int time = Integer.parseInt( lineData.get(1) ); 
        int hours = time / 10000; 
        int minutes = ( time / 100 ) % 100; 
        int seconds = time % 100; 
        int count= seconds+minutes*60+hours*60*60; 
         
        //setup for converting UTC into local time 
        int Marchday=(31-(((5*years/4)+4)%7)); 
        int Octoday=(31-(((5*years/4)+1)%7)); 
         
        if(     (months>3 && months<10)  
            ||  (months==3 && days>Marchday) 
            ||  (months==10 && days<Octoday) 
            ||  (months==3 && days== Marchday && count>=60*60) 
            ||  (months==10 && days== Octoday && count<=60*60) 
            ) 
            hours=hours+2;    // central Europe summer 
        else 
            hours=hours+1; 
          
        String getTime = "Time: "+hours+":"+minutes+":"+seconds+"/r/n"; 
        System.out.println(getTime); 

代码中的LineData 是ArrayList, 用来存放GPRMC每一个单元的信息。
下边是测试结果:
Testing by the example code:
$GPRMC,010001,A,3907.356,N,12102.482,W,000.0,360.0,261008,015.5,E*6F,234,12,123,45
$GPRMC,005959,A,3907.482,N,12102.436,W,000.0,360.0,261008,015.5,E*67,234,12,123,45
$GPRMC,183731,A,3907.482,N,12102.436,W,000.0,360.0,081111,015.5,E*67,234,12,123,45
$GPRMC,183731,A,3907.482,N,12102.436,W,000.0,360.0,291011,015.5,E*67,234,12,123,45
$GPRMC,003731,A,3907.482,N,12102.436,W,000.0,360.0,270311,015.5,E*67,234,12,123,45
$GPRMC,183731,A,3907.482,N,12102.436,W,000.0,360.0,270311,015.5,E*67,234,12,123,45
And the output of the time and date is below:
Date: 26/10/2008


Time: 2:0:1 


Date: 26/10/2008

Time: 2:59:59


Date: 8/11/2011

Time: 19:37:31


Date: 29/10/2011

Time: 20:37:31


Date: 27/3/2011

Time: 1:37:31


Date: 27/3/2011

Time: 20:37:31

The test seems OK.
(以下背景资料引自维基百科)
欧洲夏令时是为了利用季节性的日光而在春季开始提前一个小时的作息方法。此方法在全欧洲除冰岛外的所有国家实行(冰岛全年实行格林尼治时间)。在欧盟国家和其他一些非欧盟国家中,此方法实行时期从每年三月份的最后一个周日1:00(格林尼治时间)开始,至十月份最后一个周日 1:00(格林尼治时间)结束。
欧洲夏令时于以下日期的格林尼治标准时间1:00开始(时钟提前一个小时):

2008年3月30日
2009年3月29日
2010年3月28日
2011年3月27日
用于计算欧洲夏令时开始时间的公式为:

3月(31-(5y÷4+4) mod 7)日的1:00(格林尼治标准时间)

(至2099年有效[3])其中y指年份,而对于非负数a,a mod b表示将a和b截尾后,两数相除所得的余数。

欧洲夏令时于以下日期的格林尼治标准时间1:00结束(时钟调后一个小时):

2008年10月26日
2009年10月25日
2010年10月31日
2011年10月30日
用于计算欧洲夏令时结束始时间的公式为:

10月(31-(5y÷4+1) mod 7)日的1:00(格林尼治标准时间)

(至2099年有效)

以上两个方程对今天(05月20日)给出的夏令时偏移量为1 (1表示目前实施夏令时)。[4]

 

 

摘自 崔立学的博客专栏

图片内容