这是关于Java日历和我们在多伦多今天的节能变化后遇到的影响。
以下是代码
Date date = new Date(); //Sun Mar 11 00:00:00 EST 2018
Integer time = 349;
Calendar scheduleDateCal = Calendar.getInstance();
scheduleDateCal.setTime(date);
scheduleDateCal.set(Calendar.MINUTE, 0);
scheduleDateCal.set(Calendar.HOUR_OF_DAY, 0);
String strSchAdminTime = String.valueOf(time);
Integer schAdminMinute = time;
if (strSchAdminTime.length() >= 2) {
schAdminMinute = Integer.valueOf(strSchAdminTime.substring(strSchAdminTime.length()-2));
}
if(time>60){
Integer schAdminHour = Integer.valueOf(strSchAdminTime.substring(0,strSchAdminTime.length()-2));
scheduleDateCal.add(Calendar.HOUR_OF_DAY, schAdminHour);
}else{
scheduleDateCal.add(Calendar.HOUR_OF_DAY, 0);
}
scheduleDateCal.add(Calendar.MINUTE, schAdminMinute);
System.out.println(scheduleDateCal.getTime());
我知道这段代码没有完成最佳实践,但是我需要为当前版本维护它。在这里,它使用整数来表示时间部分,然后有一个逻辑来从中提取小时和分钟。
当我遵循逻辑时,小时部分为3.然后有一个逻辑将此时间添加到Calendar对象,其值为' Sun Mar 11 00:00:00 EST 2018'以下声明
scheduleDateCal.add(Calendar.HOUR_OF_DAY, schAdminHour);
理论上,在此计算之后,日历对象应具有值" Sun Mar 11 03:00:00 EDT 2018"。然而,它返回" Sun Mar 11 04:00:00 EDT 2018"我知道从今天开始,夏令时将提前一小时。任何人都可以帮我理解这个
感谢帮助。
答案 0 :(得分:3)
今天00:00:00(2018年3月11日星期日)夏季时间(夏令时)尚未生效,所以时间正确呈现为Sun Mar 11 00:00:00 EST 2018(东部标准的EST)时间)。 Date.toString
根据Date
对象中包含的时间(不基于调用toString
方法的时间)在EST和EDT之间进行选择。当你在那个时间增加3个小时时,你将时钟转换为2时的2时间。因此,在你的开始时间后3小时,时间是美国东部夏令时间04:00:00(美国东部时间夏令时间)。
PS如果您或其他人感兴趣,这里是您的代码的现代版本 - 简单版本和更短版本。将时间设置为03:49:
int time = 349;
ZoneId zone = ZoneId.of("America/Toronto");
ZonedDateTime scheduledDateTime = LocalDate.now(zone)
.atTime(time / 100, time % 100)
.atZone(zone);
System.out.println(scheduledDateTime);
今天这个印刷
2018-03-11T03:49-04:00 [美国/多伦多]
当然,更好的是,如果您可以完全摆脱将03:49表示为整数值349.要使用JVM的时区设置,您可以将zone
设置为ZoneId.systemDefault()
。这很脆弱,因为程序的其他部分或在同一JVM中运行的其他程序可能随时更改该设置。
将时间设置为午夜后的3小时49分钟(与DST过渡不一样,如您所见):
ZonedDateTime scheduledDateTime = LocalDate.now(zone)
.atStartOfDay(zone)
.plusHours(time / 100)
.plusMinutes(time % 100);
这次我得到了
2018-03-11T04:49-04:00 [美国/多伦多]
答案 1 :(得分:1)
EST为-5,EDT为-4,因此当您调用add()时,您将获得1小时。
如果您需要不同时区的结果,则可以使用scheduleDateCal.set(Calendar.HOUR_OF_DAY, schAdminHour)
和scheduleDateCal.set(Calendar.MINUTE, schAdminMinute)
。