chrono_tz-mbt

    MoonBit IANA 时区库 — 597 时区 + DST 三分支 + Hinnant civil↔days + RFC3339 + strftime/strptime,移植自 Rust chrono-tz 0.11.0

    timezone
    iana
    tzdata
    dst
    rfc3339
    strftime
    hinnant
    chrono
    Download zip
    Author
    Version
    0.1.9
    License
    Apache-2.0
    Last updated
    1 hour ago
    Downloads
    14

    #walkzzz/chrono_tz-mbt

    MoonBit IANA 时区库,移植自 chrono_tz_cangjie(仓颉 v2.157.0,Rust chrono-tz 0.11.0)。

    聚焦 IANA tzdata 2025b(597 时区)+ DST 三分支 + Hinnant civil↔days + RFC3339 + strftime/strptime。不含农历/术数。

    #依赖

    # moon.mod import { "walkzzz/chrono_tz-mbt/tz" @tz, }

    #示例

    let tz = @tz.Tz::from_str("Asia/Shanghai").unwrap()
    let naive = @tz.NaiveDateTime::from_timestamp(0L)
    let utc_tz = @tz.Tz::from_str("UTC").unwrap()
    let off = utc_tz.offset_from_utc_date_time(naive)
    let dt = @tz.DateTime::make(0L, off)
    let shanghai_dt = dt.with_timezone(tz)
    println(shanghai_dt.to_rfc3339()) // 1970-01-01T08:00:00+08:00

    #核心 API

    • Tz::from_str(s) -> Tz? — 二分查找解析 IANA 时区名
    • Tz::name() -> String — 时区名
    • Tz::all() -> Array[Tz] / Tz::all_names() -> Array[String] — 全 597 时区
    • Tz::offset_from_utc_date_time(dt) -> TzOffset — UTC→本地偏移
    • Tz::offset_from_local_date_time(dt) -> LocalResult[TzOffset] — 本地→UTC 偏移(DST 三分支)
    • NaiveDateTime::from_timestamp(ts) -> NaiveDateTime — Unix 时间戳→civil(Hinnant)
    • DateTime::parse_rfc3339(s) -> DateTime? — RFC3339 解析
    • DateTime::to_rfc3339() -> String — RFC3339 格式化
    • DateTime::strftime(fmt) -> String — strftime 格式化
    • DateTime::with_timezone(tz) -> DateTime — 时区转换

    #DST 三分支

    enum LocalResult[T] { Single(T) // Normal — 唯一解 Ambiguous(T, T) // 秋季回拨 — 两个解 None // 春季前跳 — 无解 }

    #包

    • tz — 时区算法(Tz 枚举 597 + DateTime + DST + RFC3339 + strftime/strptime + JSON 序列化)
    • core — 零依赖核心类型(Hinnant + FixedTimespan + 全局查表)
    • data — 6 大洲 IANA tzdata 数据(38711 行)

    #构建与测试

    moon check # 类型检查(0 warnings) moon test --target native # 运行测试(201 个,native target) moon info && moon fmt # 更新接口 + 格式化

    注:WASM target 有 597 match arm local count 限制,需用 --target native。

    #许可证

    Apache-2.0

    convert_timezone

    将 DateTime 转换到目标时区,时间戳不变、偏移与本地表示随之改变。

    这是纯时区转换,不涉及任何时长加减。

    datetime_from_timestamp

    fn datetime_from_timestamp(timestamp : Int64, tz :
    Tz
    ) ->
    DateTime

    从 UTC 时间戳(Unix 秒)和时区构造 DateTime。

    构造出的 DateTime 携带该时区在 timestamp 时刻的偏移, timestamp 字段与传入值一致,to_rfc3339() 输出对应本地时间。

    detect_gap

    检测给定本地时刻在指定时区是否处于 DST gap(时钟向前跳,该本地时刻不存在)。

    返回 Some(GapInfo) 表示处于 gap,None 表示正常。

    from_local

    从本地时刻构造 DateTime,处理 DST gap 与 ambiguous。

    • Single(dt) — 唯一对应
    • Ambiguous(dt1, dt2) — 时钟回拨,两个时刻都合法
    • None — 时钟前跳,该本地时刻不存在

    offset_from_local

    返回时区在给定本地时刻下的偏移结果,处理 DST gap(时钟前跳)与 ambiguous(时钟回拨)两种边界。

    • Single(off) — 唯一偏移
    • Ambiguous(off1, off2) — 时钟回拨,两个偏移都合法
    • None — 时钟前跳,该本地时刻不存在

    offset_from_utc

    fn offset_from_utc(tz :
    Tz
    , timestamp : Int64) -> Int

    返回时区在给定 UTC 时间戳(Unix 秒)下的偏移量(秒)。

    东区为正、西区为负。例如 Asia/Shanghai 全年 +28800(+08:00)。 该函数按 UTC 时刻查表,自动包含 DST 偏移,不会产生歧义。

    parse_rfc3339

    fn parse_rfc3339(s : String) ->
    DateTime
    ?

    解析 RFC 3339 字符串为 DateTime,失败返回 None。

    接受形如 2026-11-05T12:34:56+08:00、2026-11-05T12:34:56Z 的输入, 偏移信息直接内嵌于结果,无需额外传入时区。

    strftime

    fn strftime(fmt : String, dt :
    DateTime
    ) -> String

    按 strftime 格式串格式化 DateTime。

    支持 %Y %m %d %H %M %S %Z %z %A %a %B %b %j %% 等 specifier。

    strptime

    fn strptime(fmt : String, s : String, tz :
    Tz
    ) ->
    DateTime
    ?

    按 strptime 格式串解析字符串为 DateTime,需指定结果所属时区。

    支持 %Y %m %d %H %M %S %y %j %% 及字面字符。失败返回 None。

    to_rfc3339

    fn to_rfc3339(dt :
    DateTime
    ) -> String

    将 DateTime 序列化为 RFC 3339 字符串,如 "2026-11-05T12:34:56+08:00"。

    tz_count

    fn tz_count() -> Int

    返回支持的 IANA 时区总数(597)。

    tz_from_str

    fn tz_from_str(name : String) ->
    Tz
    ?

    解析 IANA 时区名称(如 "Asia/Shanghai"、"UTC"),失败返回 None。

    内部委托 @tz.Tz::from_str,采用纯二分查找,无 LRU 缓存。

    tz_name

    fn tz_name(tz :
    Tz
    ) -> String

    返回时区的 IANA 名称(如 "Asia/Shanghai")。

    tz_names

    fn tz_names() -> Array[String]

    返回全部 IANA 时区名称,顺序与 @tz.Tz::all() 一致。

    Source Files