我有一个以毫秒为单位的时间戳,我想检查它是否在两个LocalDateTime
戳之间。用Java做到这一点的最好方法是什么?
答案 0 :(得分:3)
一种方法是将毫秒转换为LocalDateTime
LocalDateTime date = Instant.ofEpochMilli(milliseconds)
.atZone(ZoneId.systemDefault())
.toLocalDateTime();
LocalDateTime start = LocalDateTime.now().minusMinutes(1);
LocalDateTime end = LocalDateTime.now().plusMinutes(1);
if (date.isAfter(start) && date.isBefore(end)) {
// date is between start and end
}
答案 1 :(得分:2)
您不能将LocalDateTime
与时刻进行比较,直到分配时区(或自UTC偏移)为止。
org.threeten.extra.Interval // Represents a span-of-time attached to the timeline, as a pair of `Instant` objects, a pair of moments in UTC.
.of (
myLocalDateTimeStart
.atZone( ZoneId.of( "Pacific/Auckland" ) ) // Determine a moment by assigning an time zone to a `LocalDateTime` to produce a `ZonedDateTime`, from which we extract an `Instant` to adjust into UTC.
.toInstant() ,
myLocalDateTimeStop
.atZone( ZoneId.of( "Pacific/Auckland" ) ) // Returns a `ZonedDateTime` object.
.toInstant() // From the `ZonedDateTime`, extract a `Instant` object.
) // Returns `Interval` object.
.contains(
Instant.ofEpochMilli( 1_532_463_173_752L ) // Parse a count of milliseconds since 1970-01-01T00:00:00Z as a moment in UTC, a `Instant` object.
) // Returns a boolean.
比较Java中的时间(以毫秒为单位)和LocalDateTime之间的时间
您不能。这种比较是不合逻辑的。
一个LocalDateTime
代表 not 不是一个时刻,是 not 在时间轴上的一个点。 LocalDateTime
代表大约26-27小时(世界各地时区范围)内的潜在时刻。
因此,它没有实际意义,除非您将其放在时区的上下文中。如果该特定日期和时间在该区域中是无效的,例如在Daylight Saving Time (DST)转换期间或在某些其他此类异常期间,则ZonedDateTime
类将进行调整。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = myLocalDateTime.atZone( z ) ;
为了进行比较,我们将从您的开始和结束Instant
对象中提取ZonedDateTime
对象来适应UTC。
Instant start = zdtStart.toInstant() ;
Instant stop = zdtStop.toInstant() ;
现在将自1970年第一时刻的纪元参考以来的毫秒数解析为Instant
。 Instant
的分辨率甚至更高,纳秒。
Instant instant = Instant.ofEpochMilli( 1_532_463_173_752L ) ;
比较一下您的纪元是否代表我们停止和开始Instant
对象之间的时刻。通常在日期时间工作中,最好使用半开放式方法,其中开始为包含,而结束为排他。
提示:说“等于或在……之后”的简短方法是说“不在……之前”。
boolean inRange = ( ! instant.isBefore( start ) ) && instant.isBefore( stop ) ;
要使此工作更容易,请将ThreeTen-Extra库添加到您的项目中。使用Interval
类。
Interval interval = Interval.of( start , stop ) ;
boolean inRange = interval.contains( instant ) ; // Uses Half-Open approach to comparisons.
提示:如果您打算跟踪时刻,则完全不应该使用LocalDateTime
类。而是使用Instant
,OffsetDateTime
和ZonedDateTime
类。
java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和SimpleDateFormat
。
目前位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。
您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*
类。
在哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如Interval
,YearWeek
,YearQuarter
和more。
答案 2 :(得分:1)
在比较Instant
(自Epoch以来的时间)和LocalDateTime
时,始终需要考虑当地时间的时区。这是一个示例:
Instant now = Instant.now();
LocalDateTime start = LocalDateTime.of(2018, 7, 24, 0, 0);
LocalDateTime end = LocalDateTime.of(2018, 7, 24, 23, 59);
final ZoneId myLocalZone = ZoneId.of("Europe/Paris");
if (now.isAfter(start.atZone(myLocalZone).toInstant())
&& now.isBefore(end.atZone(myLocalZone).toInstant())) {
// the instant is between the local date-times
}