我有一系列有开始日期和结束日期的范围.我想检查日期是否在该范围内.
Date.before()和Date.after()似乎有点尴尬.我真正需要的是像这样的伪代码:
boolean isWithinRange(Date testDate) { return testDate >= startDate && testDate <= endDate; }
不确定它是否相关,但我从数据库中提取的日期有时间戳.
boolean isWithinRange(Date testDate) { return !(testDate.before(startDate) || testDate.after(endDate)); }
对我来说似乎不那么尴尬.请注意,我这样写而不是
return testDate.after(startDate) && testDate.before(endDate);
所以即使testDate完全等于其中一个最终案例,它也会起作用.
ZoneId z = ZoneId.of( "America/Montreal" ); // A date only has meaning within a specific time zone. For any given moment, the date varies around the globe by zone. LocalDate ld = givenJavaUtilDate.toInstant() // Convert from legacy class `Date` to modern class `Instant` using new methods added to old classes. .atZone( z ) // Adjust into the time zone in order to determine date. .toLocalDate(); // Extract date-only value. LocalDate today = LocalDate.now( z ); // Get today’s date for specific time zone. LocalDate kwanzaaStart = today.withMonth( Month.DECEMBER ).withDayOfMonth( 26 ); // Kwanzaa starts on Boxing Day, day after Christmas. LocalDate kwanzaaStop = kwanzaaStart.plusWeeks( 1 ); // Kwanzaa lasts one week. Boolean isDateInKwanzaaThisYear = ( ( ! today.isBefore( kwanzaaStart ) ) // Short way to say "is equal to or is after". && today.isBefore( kwanzaaStop ) // Half-Open span of time, beginning inclusive, ending is *exclusive*. )半开
日期时间工作通常采用"半开"方法来定义时间跨度.开头是包容性的,而结尾是独家的.所以从星期一开始的一周到达,但不包括,在接下来的星期一.
java.timeJava 8及更高版本内置了java.time框架.补充了旧的麻烦类,包括java.util.Date/.Calendar和SimpleDateFormat.灵感来自成功的Joda-Time图书馆.由JSR 310定义.由ThreeTen-Extra项目扩展.
An Instant
是UTC时间轴上的一个时刻,具有纳秒分辨率.
Instant
将java.util.Date对象转换为Instant对象.
Instant start = myJUDateStart.toInstant(); Instant stop = …
如果从数据库通过JDBC获取java.sql.Timestamp对象,则以类似的方式转换为java.time.Instant.java.sql.Timestamp已经是UTC,因此无需担心时区.
Instant start = mySqlTimestamp.toInstant() ; Instant stop = …
获取当前时刻进行比较.
Instant now = Instant.now();
比较使用方法isBefore,isAfter和equals.
Boolean containsNow = ( ! now.isBefore( start ) ) && ( now.isBefore( stop ) ) ;
LocalDate
也许您只想使用日期,而不是时间.
该LocalDate
级表示日期,只值,没有时间的天,没有时区.
LocalDate start = LocalDate.of( 2016 , 1 , 1 ) ; LocalDate stop = LocalDate.of( 2016 , 1 , 23 ) ;
要获取当前日期,请指定时区.在任何特定时刻,今天的日期因时区而异.例如,巴黎的新日早些时候比蒙特利尔早.
LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );
我们可以使用isEqual
,isBefore
和isAfter
方法比较.在日期时间工作中,我们通常使用半开放方法,其中一段时间的开始是包容性的,而结尾是排他性的.
Boolean containsToday = ( ! today.isBefore( start ) ) && ( today.isBefore( stop ) ) ;
Interval
如果您选择将ThreeTen-Extra库添加到项目中,则可以使用Interval
该类来定义时间跨度.该类提供了测试间隔是否包含,邻接,封闭或重叠 其他日期时间/间隔的方法.
本Interval
类适用于Instant
对象.该Instant
级表示时间轴上的时刻UTC,分辨率为纳秒(最多9个(9)小数的位数).
我们可以LocalDate
通过指定时区来调整特定时刻,即当天的第一时刻ZonedDateTime
.从那里我们可以通过提取一个回到UTC Instant
.
ZoneId z = ZoneId.of( "America/Montreal" ); Interval interval = Interval.of( start.atStartOfDay( z ).toInstant() , stop.atStartOfDay( z ).toInstant() ); Instant now = Instant.now(); Boolean containsNow = interval.contains( now );
该java.time框架是建立在Java 8和更高版本.这些类取代麻烦的老传统日期时间类,如java.util.Date
,Calendar
,和SimpleDateFormat
.
现在处于维护模式的Joda-Time项目建议迁移到java.time类.
要了解更多信息,请参阅Oracle教程.并搜索Stack Overflow以获取许多示例和解释.规范是JSR 310.
从哪里获取java.time类?
Java SE 8和 SE 9及更高版本
内置.
带有捆绑实现的标准Java API的一部分.
Java 9增加了一些小功能和修复.
Java SE 6和 SE 7
许多java.time功能都被反向移植到ThreeTen-Backport中的 Java 6和7 .
Android的
所述ThreeTenABP项目适应ThreeTen-反向移植为Android(上面提到的)特异性.
请参阅如何使用.......
该ThreeTen-额外项目与其他类扩展java.time.该项目是未来可能添加到java.time的试验场.您可以在此比如找到一些有用的类Interval
,YearWeek
,YearQuarter
,和更多.
这是正确的方法.日历的工作方式相同.我能给你的最好的(根据你的例子)是这样的:
boolean isWithinRange(Date testDate) { return testDate.getTime() >= startDate.getTime() && testDate.getTime() <= endDate.getTime(); }
Date.getTime()返回自格林尼治标准时间1/1/1970 00:00:00以来的毫秒数,并且很长,因此很容易比较.
考虑使用Joda Time.我喜欢这个库,并希望它能取代现有的Java Date和Calendar类当前可怕的混乱.这是正确的日期处理.
编辑:现在不再是2009了,Java 8已经出了很多年了.使用基于Joda Time的Java 8内置java.time类,正如Basil Bourque在下面提到的那样.在这种情况下,您将需要Period类,以及Oracle的如何使用它的教程.