java Instant

sayWhat_sayHello發表於2018-08-13

Instant和timestamp

Instant的概念和timestamp類似。但是在表示上有一點差異。
Instant內建兩個變數,一個是seconds,一個是nanos.前者是秒,後者是納秒。
1秒 = 1000毫秒 = 1000_000_000納秒

timestamp位於java.sql下,繼承自java.util.Date.相比下有以下引數
* @param year the year minus 1900
* @param month 0 to 11
* @param date 1 to 31
* @param hour 0 to 23
* @param minute 0 to 59
* @param second 0 to 59
* @param nano 0 to 999,999,999

兩者的轉換也比較簡單:
Instant轉timestamp:

Instant start = Instant.now();
Timestamp timestamp = Timestamp.from(start);

timestamp轉Instant:

timestamp.toInstant();

我們再來看下更深層的原始碼:
首先是toInstant

    public Instant toInstant() {
        return Instant.ofEpochSecond(super.getTime() / MILLIS_PER_SECOND, nanos);
    }

可以看到這裡使用的是Instant ofEpochSecond(long epochSecond, long nanoAdjustment)這個建構函式,前者表示秒,後者則是納秒。這裡super.getTime()返回的是毫秒,所以要除 毫秒/秒 得到秒單位。

然後是from,同樣的也是做一個秒和毫秒的轉換,再呼叫相應的構造方法。

    public static Timestamp from(Instant instant) {
        try {
            Timestamp stamp = new Timestamp(instant.getEpochSecond() * MILLIS_PER_SECOND);
            stamp.nanos = instant.getNano();
            return stamp;
        } catch (ArithmeticException ex) {
            throw new IllegalArgumentException(ex);
        }
    }

Instant

常用Instant構造方法

  1. Instant呼叫now()獲取當前的時間
  2. Instant ofEpochSecond(long epochSecond, long nanoAdjustment)傳入秒和納秒;Instant ofEpochSecond(long epochSecond)傳入秒,實際上呼叫帶值為0的納秒建構函式
  3. Instant ofEpochMilli(long epochMilli)傳入毫秒
  4. Instant from(TemporalAccessor temporal);
    Instant parse(final CharSequence text);

在閱讀parse的原始碼時,對lambda表示式不瞭解的話會感覺這個很難懂:

    public static Instant parse(final CharSequence text) {
        return DateTimeFormatter.ISO_INSTANT.parse(text, Instant::from);
    }

首先Instant::from代表的是方法引用,如果替換成lambda則為x -> Instant.from(x)
x代表的是引數,由於是單個引數所以可以省略(),那麼原本就是(x)->Instant.from(x)
再來就是它可以自行推斷引數型別,這裡parse傳入的兩個引數為(CharSequence text, TemporalQuery query):

public <T> T parse(CharSequence text, TemporalQuery<T> query)

對應的x 為TemporalQuery query
型別T是泛型,在這裡這個函式最終return的會是Instant,那麼T為Instant型別
即為TemporalQuery query
再看TemporalQuery原始碼,發現它是一個函式式介面

@FunctionalInterface
public interface TemporalQuery<R> {
    R queryFrom(TemporalAccessor temporal);
}

故最終如果不用lambda表示式轉為內部類,該句為:

return DateTimeFormatter.ISO_INSTANT.parse(text, Instant::from);
----------------------------------------------------------------
return DateTimeFormatter.ISO_INSTANT.parse(text, (temporal)-> Instant.from(temporal));
----------------------------------------------------------------
return DateTimeFormatter.ISO_INSTANT.parse(text, new TemporalQuery<Instant>() {
            @Override
            public Instant queryFrom(TemporalAccessor temporal) {
                return Instant.from(temporal);
            }
        });

這裡我想了很久這個temporal到底是怎麼傳進去的?沒想明白!
但是我覺得這個可能和ActionListener listener一樣.

public interface ActionListener extends EventListener {
    public void actionPerformed(ActionEvent e);

}

作為ActionListener也沒有接收到一個ActionEvent型別的值,但是還是繼續響應相應的事件。
即ActionEvent接收了包含事件發生的相應資訊。

那麼在這裡TemporalAccessor應該同樣的接收了TemporalQuery相關的資訊。
這個只是我的猜測,如果有大佬看到麻煩解釋一下謝謝~

常用方法

方法主要包含三個方面:秒,毫秒,納秒。這裡大多數方法名都比較容易理解就不贅述。

表示方法

Instant instant = Instant.now();
        instant.getEpochSecond();
        instant.getNano();
        instant.toString();
        instant.toEpochMilli();

操作方法

        instant.plusMillis(0);
        instant.plusSeconds(0);
        instant.plusNanos(0);
        instant.minusMillis(0);

省略兩個常用的minus方法。

判斷方法

        Instant otherInstant = Instant.now();
        instant.isAfter(otherInstant);
        instant.isBefore(otherInstant);

相關文章