java日历中的未来日期给出了一种奇怪的行为
我有一个应用程序,我创建的日期,用户可以选择一个约会。如果一个用户在9点开始工作,一个约会需要2个小时,我会在9点、11点、13点创建日期。。。当然,直到极限。然后我改变了一天,重新开始。 这是执行此操作的代码:java日历中的未来日期给出了一种奇怪的行为,java,date,calendar,timezone,Java,Date,Calendar,Timezone,我有一个应用程序,我创建的日期,用户可以选择一个约会。如果一个用户在9点开始工作,一个约会需要2个小时,我会在9点、11点、13点创建日期。。。当然,直到极限。然后我改变了一天,重新开始。 这是执行此操作的代码: public List<Agenda> createListOfDates(Calendar initial, Calendar end, int appointmentDuration, int lunchTimeDuration, int lu
public List<Agenda> createListOfDates(Calendar initial, Calendar end,
int appointmentDuration, int lunchTimeDuration, int lunchTimeStart) {
List<Agenda> agendaList = new ArrayList<Agenda>();
Agenda agenda = new Agenda();
agenda.setWorkingHour(initial.getTime());
agendaList.add(agenda);
while (true) {
initial.add(Calendar.HOUR_OF_DAY, appointmentDuration);
// Logger.error("" + initial.getTime());
if (initial.getTime().after(end.getTime())) {
break;
} else if (initial.get(Calendar.HOUR_OF_DAY) == lunchTimeStart
&& initial.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY
) {
initial.add(Calendar.HOUR_OF_DAY, lunchTimeDuration);
agenda = new Agenda();
agenda.setWorkingHour(initial.getTime());
agendaList.add(agenda);
} else {
agenda = new Agenda();
agenda.setWorkingHour(initial.getTime());
agendaList.add(agenda);
}
}
for(Agenda agendaX : agendaList){
Logger.info("" + agendaX.getWorkingHour());
}
return agendaList;
}
虽然是在格林尼治标准时间,这是正确的,但我不能理解这个英国夏令时。是不是因为它在未来太多了?它总是从四月开始。您的系统时间不是格林尼治标准时间,而是欧洲/伦敦(或类似的时间)。3月份伦敦时间与格林尼治标准时间一致,而不是4月份。这就是为什么
getWorkingHour()
返回Date
的一个实例(另一个设计拙劣且过时很长的类,但现在让它成为另一个故事)。将其附加到空字符串后,将隐式调用Date.toString
,并使用系统时区生成字符串。在标准时间内,它将GMT
打印为时区缩写。夏季时间(DST)从伦敦3月的最后一个星期日开始,在本例中为3月31日。因此,在JVM上的4月Date.toString
使用英国夏季时间及其缩写BST
来打印时间
好的解决方案包括两个变化:
Calendar
和date
,而是使用java.time,即现代的java日期和时间API。使用它更好,代码更清晰,尤其是在时区转换方面Calendar
而使用zoneDateTime
。根据JDBC驱动程序的功能,将其转换为UTC格式的Instant
或OffsetDateTime
,以保存到数据库中
要创建ZoneDateTime
,一个选项是使用其of
方法之一(有几种):
这将在圣保罗创建2019年3月10日09:00的日期时间。要在其中添加2小时,请执行以下操作:
int appointmentDuration = 2;
ZonedDateTime current = initial.plusHours(appointmentDuration);
System.out.println(current);
输出:
2019-03-10T11:00-03:00[美国/圣保罗]
要将数据库转换为即时
:
Instant inst = current.toInstant();
System.out.println(inst);
输出:
2019-03-10T14:00:00Z
瞬间与时区无关,只是一个时间点,但以UTC打印。一些JDBC驱动程序接受UTC时间。如果您的设置不符合要求,则需要为其设置一个OffsetDateTime
。像这样转换:
OffsetDateTime odt = current.toOffsetDateTime().withOffsetSameInstant(ZoneOffset.UTC);
System.out.println(odt);
输出:
2019-03-10T14:00Z
注意,我显式地给出了UTC,而不是依赖于JVM默认值。所以这在UTC中是明确的。您注意到日期和时间与从
Instant
打印的日期和时间一致。您的系统时间不是GMT,而是欧洲/伦敦(或类似的地方)。3月份伦敦时间与格林尼治标准时间一致,而不是4月份。这就是为什么
getWorkingHour()
返回Date
的一个实例(另一个设计拙劣且过时很长的类,但现在让它成为另一个故事)。将其附加到空字符串后,将隐式调用Date.toString
,并使用系统时区生成字符串。在标准时间内,它将GMT
打印为时区缩写。夏季时间(DST)从伦敦3月的最后一个星期日开始,在本例中为3月31日。因此,在JVM上的4月Date.toString
使用英国夏季时间及其缩写BST
来打印时间
好的解决方案包括两个变化:
Calendar
和date
,而是使用java.time,即现代的java日期和时间API。使用它更好,代码更清晰,尤其是在时区转换方面Calendar
而使用zoneDateTime
。根据JDBC驱动程序的功能,将其转换为UTC格式的Instant
或OffsetDateTime
,以保存到数据库中
要创建ZoneDateTime
,一个选项是使用其of
方法之一(有几种):
这将在圣保罗创建2019年3月10日09:00的日期时间。要在其中添加2小时,请执行以下操作:
int appointmentDuration = 2;
ZonedDateTime current = initial.plusHours(appointmentDuration);
System.out.println(current);
输出:
2019-03-10T11:00-03:00[美国/圣保罗]
要将数据库转换为即时
:
Instant inst = current.toInstant();
System.out.println(inst);
输出:
2019-03-10T14:00:00Z
瞬间与时区无关,只是一个时间点,但以UTC打印。一些JDBC驱动程序接受UTC时间。如果您的设置不符合要求,则需要为其设置一个OffsetDateTime
。像这样转换:
OffsetDateTime odt = current.toOffsetDateTime().withOffsetSameInstant(ZoneOffset.UTC);
System.out.println(odt);
输出:
2019-03-10T14:00Z
注意,我显式地给出了UTC,而不是依赖于JVM默认值。所以这在UTC中是明确的。您注意到日期和时间与从
Instant
BST
=“现在我明白了。非常感谢。我现在对另一件事有一个疑问:为什么你们写那个日期是“另一个设计拙劣、过时很久的课程,但现在让它成为一个不同的故事”?现在我明白了。非常感谢。我现在对另一件事有一个疑问:为什么你认为这个日期是“另一个设计拙劣、过时很久的课程,但现在就让它成为一个不同的故事”?