以毫秒为单位给出时间戳我如何确定它是否超过 2 天

Give timestamp in milliseconds how do I find out if it is older than 2 days

我有一个时间戳,它来自

System.currentTimeMillis()

问题

  1. 如何在我的代码中确定这是否早于 2 天?
  2. 有没有更好的方法在创建期间分配时间戳而不是使用 system.currentTimeMillis?
  3. System.currentTimeMillis() 是否与机器无关,它是否提供 UTC 时间? 谢谢!

tl;博士

Instant                              // Represents a moment as seen in UTC.
    .ofEpochMilli( yourCount )       // Convert a count of milliseconds since 1970-01-01T00:00Z to an `Instant` object.
    .isBefore(                       // Compares one `Instant` object to another.
        Instant                      
        .now()                       // Capture the current moment as seen in UTC (an offset of zero).
        .minus(                      // Instantiate another `Instant` object for another moment, per immutable objects pattern.
            Duration.ofHours( 48 )   // Define a span-of-time, not attached to the timeline, on a scale of hours-minutes-seconds.
        )                            // Returns another `Instant` object.
    )                                // Returns `boolean` primitive.

问题 1

How do I find out if this is older than 2 days in my code .?

将您的 System.currentTimeMillis() long 整数解析为 Instant

Instant instant = Instant.ofEpochMilli( 1_628_125_542_977L ) ;

你显然想回到 48 小时前。

Duration fortyEightHours = Duration.ofHours( 48 ) ;
Instant ago48Hours = Instant.now().minus( fortyEightHours ) ;

比较。

boolean momentIsMoreThan48HoursAgo = instant.isBefore( ago48Hours ) ;

问题 2

Is there a better way to assigning timestamp during creation instead of using system.currentTimeMillis ?

是的,更好的方法是Instant

而不是 System.currentTimeMillis() 我建议你只使用 Instant class。根据 Java 实施,您可以期望以毫秒或微秒的分辨率捕获当前时刻。

Instant now = Instant.now() ;
String outputIso8601 = now.toString() ;
long millisSinceEpoch = now.toEpochMilli() ;

除非您极度需要压缩数据,否则我建议您使用标准 ISO 8601 格式的字符串而不是神秘数字来序列化日期时间值。

对于当前时刻,格式为:2021-08-04T23:06:06Z 其中 T 将年-月-日与时间分开,Z 表示 +00:00 与 UTC 的偏移量为零。

问题 3

Is not is System.currentTimeMillis() machine agnostic and does it give UTC time ?

我不知道你所说的“机器不可知论者”是什么意思。该调用确实跟踪时间,并且它确实取决于正确设置主机的硬件时钟。

至于 UTC 时间,是的,方法 System.currentTimeMillis() 被记录为返回 milliseconds (give or take, depending on resolution of host computer’s hardware clock) since the epoch reference of first moment of 1970 as seen with an offset-from-UTC of zero hours-minutes-seconds, 1970-01-01T00:00Z, while ignoring leap seconds 的数字。

Instant class 做同样的事情,但可以用 nanoseconds rather than milliseconds. For capturing the current moment, conventional computer hardware clocks are currently accurate only to range of milliseconds to microseconds 的更细粒度表示一个时刻,而不是纳秒。


所有这些都已在 Stack Overflow 上多次提及。 Search 了解更多。

这是一种方法。

long millisecond = System.currentTimeMillis();
Instant fixedTime =
        Instant.ofEpochMilli(millisecond);

在这里你可以看到经过的时间每5秒变化一次

for(int i = 0; i < 4; i++) {
    try {
    Thread.sleep(5000);
    } catch (InterruptedException ie){}
    Duration duration = Duration.of(System.currentTimeMillis()
                    -millisecond, ChronoUnit.MILLIS);
    System.out.println(duration);
}

你也可以通过用之前的毫秒数减去当前的毫秒数然后比较来得到经过的持续时间。我选择了 hours 但你可以使用代表两天的任何单位。

Duration duration = Duration.of(System.currentTimeMillis()
             -millisecond, ChronoUnit.MILLIS);

if (duration.toHours() >= 48) {
    System.out.println("Two days have elapsed");
}

 

ZonedDateTime

不要只使用 System.currentTimeMillis() 中的 long 值作为时间戳。使用来自 java.time 的正确日期时间对象,即现代 Java 日期和时间 API。此外,虽然 System.currentTimeMillis() 是机器不可知的——好吧,取决于机器时钟,但假设时钟设置正确,System.currentTimeMillis() 是机器和时区不可知的。但是 2 天 不是。由于夏令时 (DST) 和其他时间异常,一天可能是 23、24 或 25 小时或您所在时区的其他持续时间。

要处理以上所有情况,请选择您要计算这 2 天的时区。时区的选择很重要。然后使用ZonedDateTime。它知道自己的时区并正确处理夏令时 t运行sitions 等。要获取您的时间戳:

    ZoneId zone = ZoneId.of("America/St_Lucia");
    ZonedDateTime timestamp = ZonedDateTime.now(zone);

检查是否超过2天:

    ZonedDateTime twoDaysAgo = ZonedDateTime.now(zone).minusDays(2);
    if (timestamp.isBefore(twoDaysAgo)) {
        System.out.println("Timestamp is older than 2 days");
    } else {
        System.out.println("Timestamp is *not* older than 2 days");
    }

因为在这种情况下,时间戳当然是新鲜的,所以我现在 运行 代码时得到的输出是:

Timestamp is *not* older than 2 days