我试图用java创建一个方法,如果一天中的当前时间在一个设置的间隔(starttime和endtime)之间,则返回true。
日期无关紧要。最好的方法是什么?
这是我的尝试,它不起作用:

public boolean isNowBetweenDateTime()
{
    final Date now = new Date();
    return now.after(startTime) && now.before(endTime);
}

在Java中,检查时间是否在两个日期对象内(忽略年、月、日)的最佳方法是什么?

最佳答案

TL;博士

Interval.of( start.toInstant() , stop.toInstant() ).contains( Instant.now() )

半开
在日期时间处理中,半开放方法通常用于定义时间跨度。开始是包含的,而结束是独占的。因此,一周的定义是从周一的第一个时刻开始,一直到下周一的第一个时刻,但不包括下周一的第一个时刻。我们有时会直觉地使用这种半开放的方法,12:1的午餐时间意味着从中午一点开始,但在下午一点钟敲响之前回到你的工作或课堂上。在整个日期时间工作中始终使用半开放将使逻辑和编程更清晰、更清晰和更简单。
所以你的逻辑应该是,“现在不是开始之前,现在是结束之前”。注意“not before”是“等于或晚于”的简洁说法。
boolean isNowBetweenDateTime = ( ! now.before(startTime) ) && now.before(endTime) ; // Not before start AND is before stop.

ZonedDateTime
问题和其他答案使用了麻烦的旧的遗留日期时间类,现在已经被java.time类取代。
ZonedDateTime类表示时间线上具有指定时区的时刻。
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( z );
ZonedDateTime start = now.minusWeeks( 1 );  // Simulating input.
ZonedDateTime stop = now.plusWeeks( 2 );  // Simulating input.

你可以自己写逻辑来测试现在是否介于两者之间。
Boolean isBetween = ( ! now.isBefore( start ) ) && stop.isBefore( stop );

Interval
如果做更多这样的工作,看看ThreeTen-Extra项目。这个库使用附加功能扩展java.time类。特别是Interval类将很有帮助,表示时间线上的一对时刻。实现多种比较方法,如containsenclosesabutsoverlaps
用一对Interval对象实例化aInstantInstant表示UTC中时间线上的某个时刻。我们可以从每个Instant对象中提取ZonedDateTime对象。
Interval interval = Interval.of( start.toInstant() , stop.toInstant() );
Boolean isBetween = interval.contains( now.toInstant() );  // Or pass `Instant.now()`.

您还可以通过调用InstantInstant.now()的形式获取当前时刻。
关于java.time
java.time框架构建在java 8和更高版本中。这些类取代了麻烦的旧日期时间类,如java.util.Date.Calendarjava.text.SimpleDateFormat
现在在Joda-Time中的maintenance mode项目建议迁移到java.time。
要了解更多信息,请参见Oracle Tutorial。和搜索堆栈溢出的许多例子和解释。
java.time的大部分功能在ThreeTen-Backport中被移植到java 6&7,并进一步适应Android中的ThreeTenABP(参见How to use…)。
ThreeTen-Extra项目使用附加类扩展java.time。这个项目是将来可能添加java.time的一个试验场。您可以在这里找到一些有用的类,如IntervalYearWeekYearQuarter等。

09-10 01:59
查看更多