最近新西兰于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
答案 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