本页详细介绍了您在 Fuchsia 上开发软件时如何处理时间。
一般来说,您可以使用适用于您所用语言的任何时间库。大多数库都可以链接到 Fuchsia 的 libc 实现以节省时间。除非您需要 Fuchsia 特定的时间操作,否则建议您使用与平台无关的库。
有多种时间选项可供选择,例如:
语言 | 单调 | 世界协调时间 (UTC) |
---|---|---|
C | clock_gettime |
time |
C++ | std::chrono::steady_clock |
std::chrono::system_clock |
Rust | 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());
}
Rust
单调时间可通过 fuchsia_zircon crate 获取。此 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);
}
UTC 时间
Fuchsia 上的世界协调时间 (UTC) 用带符号的 64 位整数表示,其中包含自 Unix 纪元(1970 年 1 月 1 日)以来经过的纳秒数。
针对 UTC 时钟的操作需要获取提供给运行时的 UTC 时钟的句柄。
处理 UTC 时钟会直接启用几项特定于 Fuchsia 的操作,包括:
- 检查世界协调时间 (UTC) 时钟的属性。
等待世界协调时间 (UTC) 时钟开始运行(这表示它已同步),然后再读取它。
C
您可以使用 zx_utc_reference_get
获取世界协调时间 (UTC) 时钟的句柄,并使用 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
获取世界协调时间 (UTC) 时钟的句柄,并使用 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 中的系统调用封装容器。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);
}