Chrono: Rust 日期與時間庫

chronochrono

Chrono旨在提供在公曆格里高利曆中執行正確日期和時間操作所需的所有功能:

  • DateTime類型預設是時區感知的,同時提供單獨的時區無關類型。
  • 可能產生無效或模糊日期和時間的操作會返回OptionMappedLocalTime
  • 可配置的解析和格式化,具有受strftime啟發的日期和時間格式化語法。
  • Local時區可以與操作系統的當前時區一起工作。
  • 類型和操作的實現考慮了合理的效率。
  • 為了限制二進制大小,Chrono預設不附帶時區數據。使用配套的crate Chrono-TZtzfile獲取完整的時區支援。

功能特性

Chrono支援各種運行時環境和操作系統,並具有幾個可啟用或禁用的功能。

預設功能:

  • alloc:啟用依賴於記憶體分配的功能(主要是字串格式化)。
  • std:啟用依賴於標準庫的功能。這是alloc的超集,增加了與標準庫類型和特徵的互操作。
  • clock:啟用讀取本地時區(Local)的功能。這是now的超集。
  • now:啟用讀取系統時間(now)的功能。
  • wasmbind:為wasm32目標提供與JS Date API的介面。

可選功能:

  • serde:通過serde啟用序列化/反序列化。
  • rkyv:已棄用,使用rkyv-*功能。
  • rkyv-16rkyv-32rkyv-64:通過rkyv啟用序列化/反序列化,分別使用16位、32位或64位整數。
  • rkyv-validation:使用bytecheck啟用rkyv驗證支援。
  • arbitrary:使用Arbitrary crate構造類型的任意實例。
  • unstable-locales:啟用本地化。這添加了帶有_localized後綴的各種方法。

概述

時間差/持續時間

Chrono提供了TimeDelta類型來表示時間跨度的大小。這是一個以秒和納秒表示的"精確"持續時間,不表示如天或月等"名義"組件。

TimeDelta類型以前命名為Duration(仍作為類型別名提供)。與類似的core::time::Duration的一個顯著區別是它是有符號值而不是無符號值。

日期和時間

Chrono提供了DateTime類型來表示時區中的日期和時間。

DateTime是時區感知的,必須從TimeZone對象構造,該對象定義了本地日期如何轉換為UTC日期並返回。有三個眾所周知的TimeZone實現:

  • Utc指定UTC時區。它最高效。
  • Local指定系統本地時區。
  • FixedOffset指定任意固定時區,如UTC+09:00或UTC-10:30。

不同TimeZone類型的DateTime是不同的,不能混用,但可以使用DateTime::with_timezone方法相互轉換。

您可以在UTC時區(Utc::now())或本地時區(Local::now())獲取當前日期和時間。

use chrono::prelude::*;

let utc: DateTime<Utc> = Utc::now(); // 例如 `2014-11-28T12:45:59.324310806Z`
let local: DateTime<Local> = Local::now(); // 例如 `2014-11-28T21:45:59.324310806+09:00`

此外,您還可以創建自己的日期和時間:

use chrono::offset::MappedLocalTime;
use chrono::prelude::*;

let dt = Utc.with_ymd_and_hms(2014, 7, 8, 9, 10, 11).unwrap(); // `2014-07-08T09:10:11Z`

格式化和解析

格式化通過format方法完成,其格式等同於熟悉的strftime格式。

預設的to_string方法和{:?}說明符也提供了合理的表示。Chrono還提供了to_rfc2822to_rfc3339方法用於常見格式。

Chrono現在還提供幾乎任何語言的日期格式化功能,無需額外的C庫。此功能在unstable-locales特性下提供:

use chrono::prelude::*;

let dt = Utc.with_ymd_and_hms(2014, 11, 28, 12, 0, 9).unwrap();
assert_eq!(dt.format("%Y-%m-%d %H:%M:%S").to_string(), "2014-11-28 12:00:09");
assert_eq!(dt.format_localized("%A %e %B %Y, %T", Locale::fr_BE).to_string(), 
           "vendredi 28 novembre 2014, 12:00:09");

解析可以通過兩種方法完成:

  1. 標準的FromStr特性(以及字串上的parse方法)可用於解析DateTime<FixedOffset>DateTime<Utc>DateTime<Local>值。
  2. DateTime::parse_from_str解析帶偏移量的日期和時間,並返回DateTime<FixedOffset>
use chrono::prelude::*;

let dt = "2014-11-28T12:00:09Z".parse::<DateTime<Utc>>().unwrap();
let fixed_dt = DateTime::parse_from_str("2014-11-28 21:00:09 +09:00", "%Y-%m-%d %H:%M:%S %z").unwrap();

與EPOCH時間戳的轉換

使用DateTime::from_timestamp(seconds, nanoseconds)從UNIX時間戳構建DateTime<Utc>

使用DateTime.timestampDateTime獲取時間戳(以秒為單位)。此外,您可以使用DateTime.timestamp_subsec_nanos獲取額外的納秒數。

use chrono::{DateTime, Utc};

// 從epoch構建datetime:
let dt: DateTime<Utc> = DateTime::from_timestamp(1_500_000_000, 0).unwrap();
assert_eq!(dt.to_rfc2822(), "Fri, 14 Jul 2017 02:40:00 +0000");

// 從datetime獲取epoch值:
let dt = DateTime::parse_from_rfc2822("Fri, 14 Jul 2017 02:40:00 +0000").unwrap();
assert_eq!(dt.timestamp(), 1_500_000_000);

限制

  • 僅支援向前推算的格里高利曆(即擴展以支援更早的日期)。
  • 日期類型限制為從公元紀元前後約262,000年。
  • 時間類型限制為納秒精度。
  • 可以表示閏秒,但Chrono不完全支援它們。