我有一些代码使用Calendar.set()返回给定日期值的小时开头。我在2012年11月4日星期日(东部时区 - 美国东部时间到东部时间转换)遇到了以下问题:
public void testStartOfHourDST1() {
Calendar cal = Calendar.getInstance();
long time = 1352005200000L; // Nov 4, 2012, 1AM EDT
cal.setTimeInMillis(time);
cal.set(Calendar.MILLISECOND, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MINUTE, 0);
System.out.println(new Date(time));
System.out.println(new Date(cal.getTimeInMillis()));
System.out.println(System.getProperty("java.version"));
assertEquals(cal.getTimeInMillis(), time); // fails
return;
}
输出继电器:
Sun Nov 04 01:00:00 EDT 2012
Sun Nov 04 01:00:00 EST 2012
1.6.0_35
也许这不是使用日历的正确方法,但在下一个小时(或前一个小时)运行相同的测试工作正常。这是JVM问题吗?
由于
答案 0 :(得分:5)
这不是一个真正的问题,因为它是确定性的并且正在按照程序编程去做。如果您希望选择两个1ams中较早的一个,这是一个问题!
更改日历上的字段后,唯一的信息是“美国/东部时间凌晨1点”。那么,那天你的时区有两个1ams,它应该选择哪一个? OpenJDK的作者做出了一个决定,即当出现这种模糊性时,他们会在标准时间内将其解释为后者。此评论来自java.util.GregorianCalendar OpenJDK 6:
// 2. The transition out of DST. Here, a designated time of 1:00 am - 1:59 am // can be in standard or DST. Both are valid representations (the rep // jumps from 1:59:59 DST to 1:00:00 Std). // Again, we assume standard time.
如果您打印出数字的实际值,您会看到cal.getTimeInMillis()
实际上已经从time
的值改变了一个小时。
答案 1 :(得分:0)
获取正确的时区非常重要。例如,我确信您知道系统当前时间(以毫秒为单位)是从1970年1月1日午夜开始测量的。这是有据可查的。 Date构造函数JavaDoc说:
公开日期(漫长日期)
分配Date对象并初始化它以表示指定的对象 自标准基准时间以来称为“。”的毫秒数 时代“,即1970年1月1日,格林尼治标准时间00:00:00。
这很好,但是这个程序的输出起初有点难以理解:
import java.util.Date;
import java.util.TimeZone;
import java.text.SimpleDateFormat;
public class Demo {
public static void main(String[] args) {
TimeZone tz = TimeZone.getTimeZone("Europe/London");
Date d = new Date(-3600000);
SimpleDateFormat df = new SimpleDateFormat("MMMM dd, yyyy HH:mm:ss.SSS z");
df.setTimeZone(tz);
System.out.println(String.format("%8dms -> %s",
Long.valueOf(d.getTime()) ,df.format(d)));
d.setTime(0);
System.out.println(String.format("%8dms -> %s",
Long.valueOf(d.getTime()) ,df.format(d)));
}
}
输出结果为:
-3600000ms -> January 01, 1970 00:00:00.000 GMT
0ms -> January 01, 1970 01:00:00.000 GMT
正如你所看到的,这个时代显然已经被移走了一个小时!
除非不是。如果您明确使用“GMT”时区,一切都很好。 “欧洲/伦敦”时区就像那样棘手。
使用日历时,请了解您正在使用或被捕获的时区。