以下是示例代码
public class DateFormatSampleCode {
public static void main(String[] args) throws ParseException {
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
cal.setTime(sdf.parse("2016-03-12T02:00:00-0800"));
sdf.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
System.out.println(sdf.format(cal.getTime()));
cal.add(Calendar.DATE, 1);
System.out.println(sdf.format(cal.getTime()));
}
}
这里的答案是
“2016-03-12T01:00:00-0800”
,但从我的观点来看,它应该是“
2016-03-12T03:00:00-0700
”。
答案 0 :(得分:2)
如您所知,“2016年夏令时(DST)从2016年3月13日凌晨2点(当地时间)至2016年11月6日凌晨2点(当地时间)生效”({{3} })。因此,如果您在3月12日凌晨2点之前添加24小时,那么您可以准确地将时钟从2点移到凌晨3点。因此,我认为不太清楚结果是什么。我会立即期待02:00:00-0800
或03:00:00-0700
(后者是您的预期)。
您正在使用pre-Java-8 Calendar
类。如果结果准确记录,我就错过了。该文档仅表示添加“基于日历的规则”。考虑到这个问题,如果你从3月12日的2到3岁之间开始,那么问题就是期待。在2之前,你将在3月13日,24小时后获得相同的时间。 3之后也很容易,你得到的是同一时间,只有23小时后因为变化。对于2到3之间的时间,3月13日不存在相同的时间,因此必须做出选择。似乎选择减去一个小时。他们还选择在凌晨2:00进行此操作,但不是在3:00:00进行此操作,以使规则在半小时开放的时间间隔内有效。至少这是一致的。我们可能无法完全避免意外结果。
例如java.time
之类的Java 8 ZonedDateTime
类更好地记录,因此更可靠。例如,ZonedDateTime.plusDays()
会将day / s添加到本地日期时间并转换回ZonedDateTime
。如果本地日期时间在间隙(如此处),则“将通过间隙的长度向前调整”(此处为1小时)。因此,您的结果将是2016-03-13T03:00-07:00[America/Los_Angeles]
,与您预期的完全一样。
要学习的一个可能的教训是,如果可以使用Java 8,请使用java.time
类。