31 个版本

0.9.0 2024 年 4 月 5 日
0.8.6 2024 年 2 月 12 日
0.8.5 2023 年 12 月 29 日
0.8.4 2023 年 10 月 30 日
0.2.4 2016 年 11 月 27 日

日期和时间 类别中排名第 2

Download history 283946/week @ 2024-04-25 287697/week @ 2024-05-02 294721/week @ 2024-05-09 322472/week @ 2024-05-16 321329/week @ 2024-05-23 424997/week @ 2024-05-30 500595/week @ 2024-06-06 456607/week @ 2024-06-13 512424/week @ 2024-06-20 564721/week @ 2024-06-27 468967/week @ 2024-07-04 488343/week @ 2024-07-11 481973/week @ 2024-07-18 515165/week @ 2024-07-25 517573/week @ 2024-08-01 421847/week @ 2024-08-08

每月下载量 2,028,258
687 crate 中使用 (直接使用 337 个)

MIT/Apache 许可协议

365KB
604 行代码 (不含注释)

Chrono-TZ

Chrono-TZ 是一个库,它为 TimeZone trait 提供了 rust-chrono 的实现。这些实现由构建脚本生成,使用 IANA 数据库parse-zoneinfo

文档

文档托管在 docs.rs

示例

在某个时区创建一个时间并将其转换为 UTC

use chrono::{TimeZone, Utc};
use chrono_tz::US::Pacific;

let pacific_time = Pacific.ymd(1990, 5, 6).and_hms(12, 30, 45);
let utc_time = pacific_time.with_timezone(&Utc);
assert_eq!(utc_time, Utc.ymd(1990, 5, 6).and_hms(19, 30, 45));

创建一个原始的 datetime 并将其转换为时区感知的 datetime

use chrono::{TimeZone, NaiveDate};
use chrono_tz::Africa::Johannesburg;

let naive_dt = NaiveDate::from_ymd(2038, 1, 19).and_hms(3, 14, 08);
let tz_aware = Johannesburg.from_local_datetime(&naive_dt).unwrap();
assert_eq!(tz_aware.to_string(), "2038-01-19 03:14:08 SAST");

伦敦和纽约在 3 月份的不同日期更改时钟,因此在某些日期只有 4 小时的差异。

use chrono::TimeZone;
use chrono_tz::Europe::London;
use chrono_tz::America::New_York;

let london_time = London.ymd(2016, 3, 18).and_hms(3, 0, 0);
let ny_time = london_time.with_timezone(&New_York);
assert_eq!(ny_time, New_York.ymd(2016, 3, 17).and_hms(23, 0, 0));

如果您想查看标准 UTC 偏移以及给定时间生效的任何特殊偏移(例如夏令时),还可以获取原始偏移。请注意,您需要导入 OffsetComponents trait。

use chrono::{Duration, TimeZone};
use chrono_tz::Europe::London;
use chrono_tz::OffsetComponents;

let london_time = London.ymd(2016, 5, 10).and_hms(12, 0, 0);

// London typically has zero offset from UTC, but has a 1h adjustment forward
// when summer time is in effect.
assert_eq!(london_time.offset().base_utc_offset(), Duration::hours(0));
assert_eq!(london_time.offset().dst_offset(), Duration::hours(1));

在夏令时变更期间跨越 24 小时会导致本地时间发生变化

use chrono::{TimeZone, Duration};
use chrono_tz::Europe::London;

let dt = London.ymd(2016, 10, 29).and_hms(12, 0, 0);
let later = dt + Duration::hours(24);
assert_eq!(later, London.ymd(2016, 10, 30).and_hms(11, 0, 0));

当然,您总是可以将本地时间转换为 Unix 时间戳

use chrono::TimeZone;
use chrono_tz::Asia::Kolkata;

let dt = Kolkata.ymd(2000, 1, 1).and_hms(0, 0, 0);
let timestamp = dt.timestamp();
assert_eq!(timestamp, 946665000);

字符串的格式化输出将使用正确的时区缩写

use chrono::TimeZone;
use chrono_tz::Europe::London;

let dt = London.ymd(2016, 5, 10).and_hms(12, 0, 0);
assert_eq!(dt.to_string(), "2016-05-10 12:00:00 BST");
assert_eq!(dt.to_rfc3339(), "2016-05-10T12:00:00+01:00");

您可以使用 FromStr trait 将时区字符串转换为时区

use chrono::TimeZone;
use chrono_tz::Tz;
use chrono_tz::UTC;

let tz: Tz = "Antarctica/South_Pole".parse().unwrap();
let dt = tz.ymd(2016, 10, 22).and_hms(12, 0, 0);
let utc = dt.with_timezone(&UTC);
assert_eq!(utc.to_string(), "2016-10-21 23:00:00 UTC");

no_std 支持

要使用此库而不依赖于 Rust 标准库,请在您的 Cargo.toml 中添加以下内容

[dependencies]
chrono = { version = "0.4", default-features = false }
chrono-tz = { version = "0.5", default-features = false }

如果您在程序空间有限的环境中(如微控制器)使用此库,请注意您可能还需要启用优化和链接时间优化。

[profile.dev]
opt-level = 2
lto = true

[profile.release]
lto = true

否则,此库增加的二进制大小可能会超出可用的程序空间,并触发链接错误。

限制时区表到感兴趣的区域

Chrono-tz默认为IANA数据库中的所有条目生成时区。如果您只对少数时区感兴趣,可以使用启用filter-by-regex功能并设置环境变量来选择它们。该环境变量名为CHRONO_TZ_TIMEZONE_FILTER,它是一个正则表达式。应在您的顶级构建中指定。

[dependencies]
chrono-tz = { version = "0.6", features = [ "filter-by-regex" ] }
CHRONO_TZ_TIMEZONE_FILTER="(Europe/London|US/.*)" cargo build

这可以显著减少生成数据库的大小,具体取决于您感兴趣的时区数量。维基百科有一个文章列出了时区名称

应用的筛选是自由的;如果您使用如“US/.*”的样式模式,则chrono-tz将包括所有链接的时区,例如“America/Denver”,而不仅仅是“US/Mountain”。

开发

chrono-tz使用git子模块,因此为了本地构建,您需要运行git submodule initgit submodule update

未来改进

  • 处理闰秒
  • 处理儒略历到格里历的转换
  • 始终从最新版本加载tzdata
  • 动态tzdata加载

依赖项

~1–2MB
~32K SLoC