時間語言支援

本頁將詳細說明如何在 Fuchsia 上開發軟體時處理時間。

一般而言,您可以使用任何適用於您語言的任何時間程式庫。大多數 程式庫可連結至 Fuchsia 的 libc 實作, 收集時間。除非您需要 Fuchsia 專屬的時間作業,否則建議您使用平台無關的程式庫。

提供多種時間選項,例如:

語言 單調 世界標準時間
C clock_gettime time
C++ std::chrono::steady_clock std::chrono::system_clock
荒漠油廠 std::time::Instant std::time::SystemTime

Fuchsia 特定時間作業

在某些情況下,您需要以 Fuchsia 特定方式處理時間。當您需要直接處理 Fuchsia 的時間表示法,或需要處理 Fuchsia 專屬的 UTC 行為時,就必須使用此方法。

單調時間

Fuchsia 上的單調時間以帶正負號的 64 位元整數表示,其中包含系統開機後經過的奈秒數。詳情請見 zx_clock_get_monotonic

C 罩杯

您可以透過 libzircon 存取單調時間。

#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 存取單調時間。

#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());
}

荒漠油廠

你可以使用 zx Crate 存取單調時間。 這個 Crate 只能在樹狀結構內使用。


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

世界標準時間

Fuchsia 上的 UTC 時間以帶正負號的 64 位元整數表示,其中包含自 Unix 紀元 (1970 年 1 月 1 日) 起算的奈秒數。

對世界標準時間時鐘執行的作業需要取得提供給執行階段的世界標準時間時鐘的句柄。

直接處理 UTC 時鐘可啟用幾個 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 中的 syscall 包裝函式。

#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);
  }
}

荒漠油廠

您可以使用 fuchsia_runtime 和使用 zx Crate。fuchsia_async Crate 包含的公用程式,可協助等待時鐘啟動。請注意 只有樹狀結構內才能使用 Crate。

use fuchsia_runtime::duplicate_utc_clock_handle;
use {fuchsia_async as fasync, 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);
}