在夏令时中DateUtils.addDays()类问题

时间:2015-10-01 09:17:35

标签: java date datetime timezone simpledateformat

最近新西兰于9月27日观察到夏令时。

SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
sd.setTimeZone(TimeZone.getTimeZone("Pacific/Auckland"));
Date dateValue = sd.parse("2015-09-30");
System.out.println(dateValue); // prints "Tue Sep 29 07:00:00 EDT 2015" My local system timzone in EDT 
dateValue = DateUtils.addDays(dateValue, -6); // 6 days back 24 Sep of  Pacific/Auckland
System.out.println(dateValue); // prints "Tue Sep 23 07:00:00 EDT 2015"

第二个打印语句应打印Tue Sep 29 08:00:00 EDT 2015,因为夏令时没有生效。

问题出在9月27日之前新西兰= UTC + 12 在NZ = UTC +13之后 所以在9月23日,它应该有时间08:00:00而不是07:00:00

2 个答案:

答案 0 :(得分:2)

问题在于来自Apache Commons的DateUtils.addDays:它使用带有默认时区的Calendar来添加和减去天数,而不是使用用户提供的时区。您可以在方法add的源代码中看到这一点:它调用Calendar.getInstance()而不是Calendar.getInstance(someTimezone)

如果你自己构建Calendar并设置正确的时区,问题就会消失:

SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
sd.setTimeZone(TimeZone.getTimeZone("Pacific/Auckland"));
Date dateValue = sd.parse("2015-09-30");
System.out.println(dateValue); // prints "Tue Sep 29 13:00:00 CEST 2015"

Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Pacific/Auckland")); // set correct timezone to calendar
calendar.setTime(dateValue);
calendar.add(Calendar.DAY_OF_MONTH, -6);
dateValue = calendar.getTime();
System.out.println(dateValue); // prints "Wed Sep 23 14:00:00 CEST 2015"

答案 1 :(得分:1)

我也使用joda api来解决这个时区问题。

org.joda.time.DateTimeZone timeZone = org.joda.time.DateTimeZone.forID( "Pacific/Auckland" );
    DateTime currentDate= new DateTime( new Date(), timeZone );
DateTime dateValue = now.plusDays( -6 ); // prints Tue Sep 29 08:00:00 EDT 2015