1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > java Calandar 夏时制 计算指定日期的前一天出错

java Calandar 夏时制 计算指定日期的前一天出错

时间:2019-06-21 19:50:29

相关推荐

java Calandar 夏时制 计算指定日期的前一天出错

1. 问题描述: 用java 自带的Calendar 类计算指定日期的前 n 天的日期;

2.现象: 设置当前日期为19870912, n 为-1, 即计算19870912 下一天的日期,计算出来的结果如下,没有得到预期的19870913。

default timeZone:Asia/ShanghaitestDate:19870912 nextDate:19870912

调用的getDate() 计算逻辑: 将日期转换成毫秒,然后加上n天的毫秒数(n*24*3600*1000L),即为n天后的日期,代码如下:

package com.ibeifeng.senior.kafka;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date;import java.util.SimpleTimeZone;public class Test {public static void main(String[] args) throws ParseException {SimpleDateFormat yyyymmdd=new SimpleDateFormat( "yyyyMMdd" );String testDateString="19870912";//计算testDate的前一天Date testDate= yyyymmdd.parse(testDateString);Date resDate = getDate(testDate,-1);String res = yyyymmdd.format( resDate );System.out.println( "testDate:"+testDate +" nextDate:"+res );Date testDate1= yyyymmdd.parse(testDateString);System.out.println( "---testDate:"+testDate1 );Date resDateGM = getDateGM(testDate1,-1);String res1 = yyyymmdd.format( resDateGM );System.out.println( "testDate:"+testDate1 +" nextDate:"+res1 );Calendar calendar2 = Calendar.getInstance();String timeZone = calendar2.getTimeZone().getID();System.out.println( "default timeZone:"+timeZone );Date testDate2= yyyymmdd.parse(testDateString);Date resd=getAfterDate(testDate2,-1);String res11 = yyyymmdd.format( resd );System.out.println( "AddDate:"+testDate2 +" nextDate:"+res11 );}//计算在date日期之前的n天的日期public static Date getDate(Date date, int n){Calendar calendar1 = Calendar.getInstance();Calendar calendar2 = Calendar.getInstance();String timeZone = calendar1.getTimeZone().getID();System.out.println( "default timeZone:"+timeZone );calendar2.setTime( date );Long c1TimeInMillis = calendar2.getTimeInMillis() - n*24*3600*1000L;calendar1.setTimeInMillis(c1TimeInMillis);return calendar1.getTime();}public static Date getDateGM(Date date, int n){Calendar calendar1 = Calendar.getInstance();Calendar calendar2 = Calendar.getInstance();calendar2.setTime( date );Long c1TimeInMillis = calendar2.getTimeInMillis() - n*24*3600*1000L;calendar1.setTimeInMillis(c1TimeInMillis);return calendar1.getTime();}}

调试代码,1.发现计算后的日期 是1987-09-12 23:00:00 ,比预期的结果少一个小时,2.并且testDate 是CDT格式,很奇怪。如图:

查阅资料知:

CDT (中部夏令时间); CST:是中国标准时间;

发现是JVM的默认时区为:Asia/Shanghai,然后Asia/Shanghai 这个时区并不一定与GMT+08这个时区相等,他们是2种定义标准。Asia/Shanghai 这个代表的是中国的时区,但在历史中,有国家(包含中国)政策颁布了在1986-1991年等还存在夏令时。在这样的时间区间,夏季时,会将时间拨快1个小时(即东9区时间),夏季结束时会再次将时间拨回一个小时(即东8区时间)。

虽然Calendar 默认的时区是Asia/Shanghai,但是Asia/Shanghai 在1986-1991年间仍然存在夏令时,比正常时间多一个小时,这就导致在计算19870912下一天的时候,增加24小时,但日期仍然是 0912日,而不是预期的13日。

3. 解决方案:

方案1. 在计算日期时,Calendor指定时区为 GMT+8,如getDateGM()方法,但是指定时区后,进行set值的时候会将原来CDT时间转换成GMT时间,即 19780912 00:00:00 变为 19780911 23:00:00 ,即对这个0911这个日期进行加24小时,还是不能达到获取后一天的目地。

public static Date getDateGM(Date date, int n){String timeZone = Calendar.getInstance().getTimeZone().getID();System.out.println( "default timeZone:"+timeZone );TimeZone.setDefault( TimeZone.getTimeZone( "GMT+8" ) );Calendar calendar1 = Calendar.getInstance(TimeZone.getTimeZone( "GMT+8" ));Calendar calendar2 = Calendar.getInstance(TimeZone.getTimeZone( "GMT+8" ));calendar1.clear();calendar2.clear();String timeZone1 = calendar1.getTimeZone().getID();System.out.println( "after timeZone:"+timeZone1 );calendar2.setTime( date );Long c1TimeInMillis = calendar2.getTimeInMillis() - n*24*3600*1000L;calendar1.setTimeInMillis(c1TimeInMillis);return calendar1.getTime();}

方案2. 使用Calendar 的add() 方法,直接对天进行计算。

public static Date getAfterDate(Date date , int n){Calendar calendar1 = Calendar.getInstance();calendar1.setTime( date );calendar1.add( Calendar.DATE,n );return calendar1.getTime();}

结果:

default timeZone:Asia/Shanghai

testDate:Sat Sep 12 00:00:00 CDT 1987 nextDate:19870912

---testDate:Sat Sep 12 00:00:00 CDT 1987

default timeZone:Asia/Shanghai

after timeZone:GMT+08:00

testDate:Fri Sep 11 23:00:00 GMT+08:00 1987 nextDate:19870912

default timeZone:GMT+08:00

AddDate:Fri Sep 11 23:00:00 GMT+08:00 1987 nextDate:19870911

中国夏时制曾策参看:/name/xiashizhi.htm

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。