在epoch毫秒和LocalDateTime之间比较java中的时间

问题描述 投票:2回答:3

我有一个epoch毫秒的时间戳,我想检查它是否在两个LocalDateTime邮票之间。在java中执行此操作的最佳方法是什么?

java date time
3个回答
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
}

2
投票

tl;dr

在分配时区(或从UTC偏移)之前,您无法比较LocalDateTime

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.             

Details

在epoch毫秒和LocalDateTime之间比较java中的时间

你不能。这种比较是不合逻辑的。

LocalDateTime不代表片刻,不是时间轴上的一个点。 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类。相反,使用InstantOffsetDateTimeZonedDateTime类。

table of date-time class in Java, both legacy and modern


About java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,如java.util.DateCalendarSimpleDateFormat

现在在Joda-Timemaintenance 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的试验场。你可能会在这里找到一些有用的类,如IntervalYearWeekYearQuartermore


1
投票

当比较Instant(time-since-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

}
© www.soinside.com 2019 - 2024. All rights reserved.