DateUtils.addDays() class 夏令时问题
DateUtils.addDays() class issue in daylight saving time
最近新西兰于 2015 年 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
,因为夏令时没有生效。
问题发生在 27 Sep 15 之前 NZ = UTC+12
在 NZ = UTC +13 之后
所以在 9 月 23 日它应该有时间 08:00:00
而不是 07:00:00
问题出在 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"
我还使用 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
最近新西兰于 2015 年 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
,因为夏令时没有生效。
问题发生在 27 Sep 15 之前 NZ = UTC+12
在 NZ = UTC +13 之后
所以在 9 月 23 日它应该有时间 08:00:00
而不是 07:00:00
问题出在 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"
我还使用 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