時間語言支援

本頁詳細說明在 Fuchsia 上開發軟體時,您可以如何處理的時間。

一般來說,您可以使用任何適用您語言的程式庫。大多數程式庫都能連結至 Fuchsia 的 libc 實作項目來預留時間。除非您需要 Fuchsia 特定時間作業,否則建議使用各平台通用的程式庫。

市面上有許多不同的時間選項可供選擇,例如:

語言 單色 世界標準時間
C clock_gettime time
C++ std::chrono::steady_clock std::chrono::system_clock
Rust std::time::Instant std::time::SystemTime

富士亞特定時間作業

在某些情況下,您可能需要以富士亞特定方式處理時間。如果需要直接處理 Fuchsia 的時間表示法,或是需要處理 Fuchsia 專屬的 UTC 行為時,就需要使用此方法。

單聲道時間

Fuchsia 上的單音時間會以帶正負號的 64 位元整數表示,包含自系統開機以來的奈秒數量。詳情請參閱 zx_clock_get_monotonic

C 調

您可以透過 libzircon 存取 Monotonic 時間。

#include <stdio.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/clock.h>

void monotonic_examples(void) {
  // Read monotonic time.
  zx_time_t mono_nsec = zx_clock_get_monotonic();
  printf("The monotonic time is %ld ns.\n", mono_nsec);
}

C++

您可以透過 libzx 存取 Monotonic 時間。

#include <lib/zx/clock.h>
#include <lib/zx/time.h>
#include <stdio.h>

void monotonic_examples() {
  // Read monotonic time.
  zx::time monotonic_time = zx::clock::get_monotonic();
  printf("The monotonic time is %ld ns.\n", monotonic_time.get());
}

Rust

您可以透過 fuchsia_zircon Crate 存取 Monotonic 時間。這個 Crate 僅適用樹狀結構內。

use fuchsia_zircon as zx;

pub fn monotonic_examples() {
    // Read monotonic time.
    let monotonic_time = zx::Time::get_monotonic();
    println!("The monotonic time is {:?}.", monotonic_time);
}

世界標準時間

Fuchsia 上的世界標準時間時間是以經過簽署的 64 位元整數表示,其中包含自 Unix 紀元 (1970 年 1 月 1 日) 起的奈秒數量。

世界標準時間時鐘的作業需要取得給執行階段提供的世界標準時間的控制代碼。

直接處理世界標準時間時鐘,即可啟用幾項 Fuchsia 特定作業,包括:

  • 檢查 UTC 時鐘的屬性。
  • 等待 UTC 時鐘開始執行,這表示時間已同步處理,然後再讀取。

C 調

您可以使用 zx_utc_reference_get 取得世界標準時間時鐘的控制代碼,並使用 libzircon 中公開的系統呼叫。

#include <stdio.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/clock.h>
#include <zircon/utc.h>

void utc_examples(void) {
  // This is a borrowed handle. Do not close it, and do not replace it using
  // zx_utc_reference_swap while using it.
  zx_handle_t utc_clock = zx_utc_reference_get();

  if (utc_clock != ZX_HANDLE_INVALID) {
    // Wait for the UTC clock to start.  The clock may never start on a device
    // that does not have a RTC or a network connection.
    // A started clock may, but also may not have a valid UTC actual.
    zx_status_t status = zx_object_wait_one(utc_clock, ZX_CLOCK_STARTED, ZX_TIME_INFINITE, NULL);
    if (status == ZX_OK) {
      printf("UTC clock is started.\n");
    } else {
      printf("zx_object_wait_one syscall failed (status = %d).\n", status);
    }

    // Wait for the UTC clock to be externally synchronized.  Once that happens,
    // the clock is known to correspond to UTC actual (with error bounds available through
    // zx_clock_get_details).
    status = zx_object_wait_one(utc_clock, ZX_USER_SIGNAL_0, ZX_TIME_INFINITE, NULL);
    if (status == ZX_OK) {
      printf("UTC clock is externally synchronized.\n");
    } else {
      printf("zx_object_wait_one syscall failed (status = %d).\n", status);
    }

    // Wait for the UTC clock to be of "logging quality".  Logging quality UTC
    // clock is started, but not necessarily corresponding to UTC actual. This
    // clock is to be used only for logging timestamps.
    status = zx_object_wait_one(utc_clock, ZX_USER_SIGNAL_1, ZX_TIME_INFINITE, NULL);
    if (status == ZX_OK) {
      printf("UTC clock is of logging quality.\n");
    } else {
      printf("zx_object_wait_one syscall failed (status = %d).\n", status);
    }

    // Read the UTC clock.
    zx_time_t nsec;
    status = zx_clock_read(utc_clock, &nsec);
    if (status == ZX_OK) {
      printf("It has been %ld ns since the epoch.\n", nsec);
    } else {
      printf("zx_clock_read syscall failed (status = %d).\n", status);
    }

    // Read UTC clock details.
    zx_clock_details_v1_t details;
    status = zx_clock_get_details(utc_clock, ZX_CLOCK_ARGS_VERSION(1), &details);
    if (status == ZX_OK) {
      printf("The UTC clock's backstop time is %ld ns since the epoch.\n", details.backstop_time);
    } else {
      printf("zx_clock_get_details failed (status = %d).\n", status);
    }

  } else {
    printf("Error, our runtime has no clock assigned to it!\n");
  }
}

C++

您可以使用 zx_utc_reference_get 取得世界標準時間時鐘的控制代碼,並在 libzx 中使用系統呼叫包裝函式。

#include <lib/zx/clock.h>
#include <lib/zx/time.h>
#include <stdio.h>
#include <zircon/utc.h>

void utc_examples() {
  // This is a borrowed handle. Do not close it, and do not replace it using
  // zx_utc_reference_swap while using it.
  zx_handle_t utc_clock_handle = zx_utc_reference_get();
  zx::unowned_clock utc_clock(utc_clock_handle);

  // Wait for the UTC clock to start.  The clock may never start on a device
  // that does not have a RTC or a network connection.
  // A started clock may, but also may not have a valid UTC actual.
  zx_status_t status = utc_clock->wait_one(ZX_CLOCK_STARTED, zx::time::infinite(), nullptr);
  if (status == ZX_OK) {
    printf("UTC clock is started.\n");
  } else {
    printf("Waiting for the UTC clock to start failed (status = %d).\n", status);
  }

  // Wait for the UTC clock to be externally synchronized.  Once that happens,
  // the clock is known to correspond to UTC actual (with error bounds available through
  // `zx::Clock::get_details`).
  status = utc_clock->wait_one(ZX_USER_SIGNAL_0, zx::time::infinite(), nullptr);
  if (status == ZX_OK) {
    printf("UTC clock is externally synchronized.\n");
  } else {
    printf("Waiting for the UTC clock to start failed (status = %d).\n", status);
  }

  // Wait for the UTC clock to be of "logging quality".  Logging quality UTC
  // clock is started, but not necessarily corresponding to UTC actual. This
  // clock is to be used only for logging timestamps.
  status = utc_clock->wait_one(ZX_USER_SIGNAL_1, zx::time::infinite(), nullptr);
  if (status == ZX_OK) {
    printf("UTC clock is of logging quality.");
  } else {
    printf("zx_object_wait_one syscall failed (status = %d).\n", status);
  }

  // Read the UTC clock.
  zx_time_t utc_time;
  status = utc_clock->read(&utc_time);
  if (status == ZX_OK) {
    printf("The UTC time is %ld ns since the epoch\n", utc_time);
  } else {
    printf("Reading the UTC clock failed (status = %d).\n", status);
  }

  // Read clock details.
  zx_clock_details_v1_t details;
  status = utc_clock->get_details(&details);
  if (status == ZX_OK) {
    printf("The UTC clock's backstop time is %ld ns since the epoch.\n", details.backstop_time);
  } else {
    printf("Reading the UTC clock details failed (status = %d).\n", status);
  }
}

Rust

您可以使用 fuchsia_runtime crate 取得 UTC 時鐘的處理常式,然後在 fuchsia_zircon Crate 中使用 syscall 包裝函式。fuchsia_async crate 內含有助於等待時鐘啟動的公用程式。請注意,這些 Crate 只能樹狀結構內使用。

use fuchsia_async as fasync;
use fuchsia_runtime::duplicate_utc_clock_handle;
use fuchsia_zircon as zx;

pub async fn utc_examples() {
    // Obtain a UTC handle.
    let utc_clock = duplicate_utc_clock_handle(zx::Rights::SAME_RIGHTS)
        .expect("Failed to duplicate UTC clock handle.");

    // Wait for the UTC clock to start.  The clock may never start on a device
    // that does not have a RTC or a network connection.
    // A started clock may, but also may not have a valid UTC actual.
    fasync::OnSignals::new(&utc_clock, zx::Signals::CLOCK_STARTED)
        .await
        .expect("Failed to wait for ZX_CLOCK_STARTED.");
    println!("UTC clock is started.");

    // Wait for the UTC clock to be externally synchronized.  Once that happens,
    // the clock is known to correspond to UTC actual (with error bounds available through
    // `zx::Clock::get_details`).
    fasync::OnSignals::new(&utc_clock, zx::Signals::USER_0)
        .await
        .expect("Failed to wait for ZX_SIGNAL_USER_0.");
    println!("UTC clock is externally synchronized.");

    // Wait for the UTC clock to be of "logging quality".  Logging quality UTC
    // clock is started, but not necessarily corresponding to UTC actual. This
    // clock is to be used only for logging timestamps.
    fasync::OnSignals::new(&utc_clock, zx::Signals::USER_1)
        .await
        .expect("Failed to wait for ZX_SIGNAL_USER_1.");
    println!("UTC clock is of logging quality.");

    // Read the UTC clock.
    let utc_time = utc_clock.read().expect("Failed to read UTC clock.");
    println!("The UTC time is {:?}.", utc_time);

    // Read UTC clock details.
    let clock_details = utc_clock.get_details().expect("Failed to read UTC clock details.");
    println!("The UTC clock's backstop time is {:?}.", clock_details.backstop);
}