Java 在同一天内正确验证时间间隔
我有一个方法如下:Java 在同一天内正确验证时间间隔,java,date,jodatime,localdate,Java,Date,Jodatime,Localdate,我有一个方法如下: public void storeAppointment(int year, int monthOfYear, int dayOfMonth, int hourOfDayFrom, int minuteFrom, int hourOfDayUntil, int minuteUntil) { Calendar appointmentCalendar = Calendar.getInstance(); appointmen
public void storeAppointment(int year,
int monthOfYear,
int dayOfMonth,
int hourOfDayFrom,
int minuteFrom,
int hourOfDayUntil, int minuteUntil) {
Calendar appointmentCalendar = Calendar.getInstance();
appointmentCalendar.set(year, monthOfYear, dayOfMonth);
TimeZone tz = appointmentCalendar.getTimeZone();
DateTimeZone jodaTz = DateTimeZone.forID(tz.getID());
DateTime appointmentDateTime = new DateTime(appointmentCalendar.getTimeInMillis(), jodaTz);
LocalDate localDate = appointmentDateTime.toLocalDate();
// At this point I have the appointment date.
// Should e.g. throw an exception for invalid time interval
validate(hourOfDayFrom, minuteFrom, hourOfDayUntil, minuteUntil);
// set proper times for calendar
appointmentCalendar.set(Calendar.HOUR, hourOfDay);
appointmentCalendar.set(Calendar.MINUTE, minute);
// store date and times
// Should I update the localDate instead of the appointmentCalendar?
}
问题:
localDate
而不是appointmentCalendar
你在这里工作太辛苦了 避免遗留日期时间类 避免使用麻烦的旧日期时间类,例如
date
和Calendar
。现在是遗留类,被java.time类取代
不要混合使用日期时间库
不要混合使用不同的日期时间库。如果使用Joda Time,则不需要java.util.Date
,也不需要java.util.Calendar
。如果使用java.time类,则不需要Joda time,也不需要java.util.Date
/.Calendar
该项目现已启动,建议迁移到java.time
商业规则
是否应包括实际日期,还是不相关
我们不能告诉你是否考虑日期。这取决于你的商业规则
例如,如果您的业务总是从中午到13:00使用午休时间,则任何标有该时间段的业务记录都必须无效。如果你每天都吃同样的午餐休息时间,那么这里的日期就无关紧要了
但是,如果您的场景类似于记录员工的工作周期,那么同一天不应该有两个周期重叠。在这种情况下,你必须考虑日期。
ZoneDateTime
我应该更新localDate而不是appointmentCalendar吗
a) 如上所述,您不应该混合使用这些类
b) 在Joda Time和java.Time中,该类都表示一个只包含日期的值,而不包含一天中的时间。和它的同级Local…
类一样,它故意没有时区的概念。所以根本不适合你的目的
您需要使用ZoneDateTime
来表示在您的预期时区内具有意义的日期和时间
以大陆/地区
的格式指定,例如,或太平洋/奥克兰
。切勿使用3-4个字母的缩写,如EST
或IST
,因为它们不是真正的时区,也不是标准化的,甚至不是唯一的(!)
要获取当前时刻,请执行以下操作:
Instant instant = Instant.now(); // UTC.
ZonedDateTime zdt = instant.atZone( z );
…或者,作为捷径
ZonedDateTime zdt = ZonedDateTime.now( z );
另外,java.time类是。因此,您不会更改(“变异”)它们的值。而是基于原始对象的值实例化一个新对象
间隔
您可能会发现project中的课程在这里很有帮助
Interval a = Interval.of( zdtStart.toInstant() , zdtStop.toInstant() );
您可以使用诸如包含
、重叠
、封闭
、在
之前和在
之后等方法比较间隔
Boolean overlaps = a.overlaps( b );
传递对象
传递对象,而不是仅仅传递零碎数据的原语
因此,不要传递诸如月份、日期和小时的整数之类的原语,而是传递java.time对象,例如Instant
,OffsetDateTime
,ZonedDateTime
。如果只有日期或时间,请传递LocalDate
或LocalTime
默认时区
要获取JVM的当前默认时区,请调用
但是,如果重要的话,您应该询问用户他们想要/期望的时区。在JVM中运行的任何应用程序的任何线程中的任何代码都可以随时更改该默认值。确实非常有用!当我试图通过
Calendar.getInstance().getTimeZone()
进行泛型时,您正在对特定时区进行“硬编码”。如何替换它,以便完全删除日历?@Jim请参阅最后添加的关于默认时区的部分。
Boolean overlaps = a.overlaps( b );