根据分钟、秒、毫秒等确定瞬间的精度?

Determine precision of an instant in terms of minutes, seconds, milliseconds, etc?

在java.time中可以查询时间单位的精度:

java.time.Instant.now().query(java.time.temporal.TemporalQueries.precision())

当我这样做时,我得到的响应是瞬间具有精度:java.time.temporal.ChronoUnit/NANOS

是否有可能知道一个瞬间是否只有足够的信息:java.time.temporal.ChronoUnit/MINUTES(或另一个可以打包成瞬间的时间单位,例如秒、小时等)?

tl;博士

instant.truncatedTo( someChronoUnit ).equals( instant )

截断

如您所述,TemporalQueries.precision returns a TemporalQuery<TemporalUnit> 表示数据类型的 capability,而不是 contents 实例的 contents那种。

在找到不再匹配原始 Instant实例。

ChronoUnit enum in Java defines the levels of granularity in java.time, and implements TemporalUnit界面。循环遍历相关的 ChronoUnit 枚举对象(小时、分钟、秒、纳秒),将目标 Instant 对象截断为每个对象。

for ( ChronoUnit unit : List.of( ChronoUnit.HOURS , ChronoUnit.MINUTES , ChronoUnit.SECONDS , ChronoUnit.NANOS ) )
{
    if ( instant.truncatedTo( unit ).equals( instant ) ) { return unit; }
}

完整示例代码。

package work.basil.example.datetime;

import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Objects;

public class Granularity
{
    private final static List < java.time.temporal.ChronoUnit > CHRONO_UNITS = List.of( ChronoUnit.HOURS , ChronoUnit.MINUTES , ChronoUnit.SECONDS , ChronoUnit.NANOS );

    public static ChronoUnit resolve ( final Instant instant )
    {
        Objects.requireNonNull( instant );
        for ( ChronoUnit unit : Granularity.CHRONO_UNITS )
        {
            if ( instant.truncatedTo( unit ).equals( instant ) ) { return unit; }
        }
        throw new IllegalStateException();  // Should never reach this point.
    }

    public static void main ( String[] args )
    {
        Instant instant = Instant.parse( "2021-01-23T12:00:00.000000123Z" );
        ChronoUnit unit = Granularity.resolve( instant );
        System.out.println( "unit = " + unit );
    }
}

您也可以通过调用 Instant#get for each part (each ChronoField) 来测试非零值来做类似的事情。

一种方法是使用 truncatedTo 方法将一个瞬间与另一个瞬间进行比较。

例如

Instant one = Instant.now();
Instant two = Instant.ofEpochSecond(one.getEpochSecond());
System.out.println(one);
System.out.println(two);
Instant three = one.truncatedTo(ChronoUnit.SECONDS);
System.out.println(three);

这会打印

2021-03-11T07:43:43.579704700Z
2021-03-11T07:43:43Z
2021-03-11T07:43:43Z

二和三相等。

在一般情况下,如果“原始”瞬间等于其基于计时单位(秒、分钟等)截断后的自身,则该瞬间仅具有指定计时单位的足够信息。

类似

boolean onlyEnoughFor(Instant instant, ChronoUnit unit) {
    return instant.truncatedTo(unit).equals(instant);
}