Rustで日付時刻を扱うとき、多くの開発者が最初に出会うのがchronoクレートです。しかし「chronoはメンテナンスモードに入っている」「timeクレートに乗り換えるべき」という情報を見かけて、不安を感じた方も多いのではないでしょうか。

結論から言えば、chronoが公式に「メンテナンスモード」を宣言した事実はありません。2021年頃にメンテナー不在で開発が停滞した時期がありましたが、その後メンテナーが引き継ぎ、セキュリティ問題も解決済みです。2026年2月にもv0.4.44がリリースされており、完全に放棄されたわけではありません。

ただし、メインメンテナーのDirkjan Ochtman氏が2026年1月に「今後chronoのメンテナンスを縮小する意向がある」とブログで表明しており、長期的な先行きには不透明な部分があります。さらに、2024年にはBurntSushi氏(ripgrepの作者)による新クレートjiffが登場し、Rustの日時処理はchrono・time・jiffの三つ巴の状況になっています。

chronoに「メンテナンスモード」の噂が広まった背景

chronoの停滞が語られるようになった背景には、複雑な歴史があります。

Rustの日時処理クレート略年表

時期出来事
2014年chronoの開発が開始。Rust標準ライブラリのstd::timeが持たない暦やタイムゾーン機能を補う目的で誕生
2016年頃time v0.1がrust-lang-deprecated組織に移管され、公式にメンテナンス停止
2019年Jacob Pratt氏がtimeクレートのメンテナンスを引き継ぎ、v0.2を「実質的な新クレート」としてリリース
2020年11月RUSTSEC-2020-0159が発行(chrono/time v0.1共通のセキュリティ問題)
2021年9月Rust Forumに「What’s going on with Chrono?」スレッドが立つ。約1年リリースなし、PRがマージされず放置されていた
2022年chrono v0.4.20でセキュリティ問題を解決(Rust純正コードへの置き換え)
2023年chrono v0.4.30でtime v0.1への依存を完全排除
2024年7月BurntSushi氏がjiffクレートを公開
2026年1月Dirkjan Ochtman氏がchronoのメンテナンス縮小の意向を表明
2026年2月chrono v0.4.44リリース(開発は継続中)

ポイントは 2021年の約1年間の停滞期 です。この時期にメンテナー1人が連絡不能となり、マージ権限を持つ人がいない状態が続きました。この経験が「chronoはメンテナンスモード」という認識を広めた主因です。

一方、混同されやすいのが time v0.1の正式なメンテナンスモードです。time v0.1は2016年にdeprecatedとなり、現在のtime v0.3系とは完全に別のクレートです。chronoが内部でtime v0.1に依存していた時期があり、これが「chrono = メンテナンスモード」という誤解を助長しました。

RUSTSEC-2020-0159: chronoのセキュリティ問題とその解決

chronoの信頼性が問われたもう一つの要因が、2020年に発行されたRUSTSEC-2020-0159です。

問題の内容

Unix系OSでローカル時間を取得する際、chronoはPOSIX関数localtime_rを使用していました。この関数は内部で環境変数TZを読み取りますが、Rustのロック機構を経由しないためスレッド安全ではありません。別スレッドがstd::env::set_varで環境変数を変更すると、ダングリングポインタによるセグメンテーション違反が発生する可能性がありました。

解決の経緯

バージョン対応内容
v0.4.20 (2022年)localtime_rの使用を廃止。tz-rsクレートのコードをフォークし、Rust純正のタイムゾーンクエリコードに置き換え
v0.4.30 (2023年)time v0.1への依存を完全排除。Duration型を自前実装に置換

2026年現在、この脆弱性はすでに解消されています。 chrono v0.4.20以降を使っていれば影響を受けません。

2026年3月時点のchrono・time・jiff比較

3つのクレートの現在の状況を整理します。

基本データ比較

指標chrono v0.4.44time v0.3.47jiff v0.2.22
最終リリース2026-02-232026-02-052026年2月
総ダウンロード約4.8億回約5.6億回約7,500万回
直近90日DL約7,600万回約7,700万回約2,600万回
GitHub Stars約3,800約1,300約2,600
Open Issues187件11件40件
MSRV1.62.01.88.0-
ライセンスMIT / Apache-2.0Apache-2.0MIT / UNLICENSE

出典: crates.io chrono, crates.io time, crates.io jiff

ダウンロード数では3クレートとも活発に利用されていますが、Open Issuesの差(chrono: 187件 vs time: 11件)はメンテナンス体制の違いを示しています。

主要な型の対応関係

日時処理でよく使う型を3クレートで対応させると以下のようになります。

概念chronotimejiff
日付(TZなし)NaiveDateDatecivil::Date
時刻(TZなし)NaiveTimeTimecivil::Time
日付時刻(TZなし)NaiveDateTimePrimitiveDateTimecivil::DateTime
日付時刻(固定オフセット)DateTime<FixedOffset>OffsetDateTimeTimestamp
日付時刻(TZ付き)DateTime<Tz>(chrono-tz併用)非サポートZoned
期間TimeDeltaDurationSpan

タイムゾーンサポートの違い

3クレート間で最も差が出るのがタイムゾーン処理です。

chrono: DateTime<Utc>DateTime<Local>DateTime<FixedOffset>を標準提供します。IANAタイムゾーンデータベース(Asia/Tokyoなど)を使う場合は外部クレートchrono-tzが必要です。chrono-tzはタイムゾーンデータをバイナリに埋め込むため、コンパイル時間とバイナリサイズが増加します。

time: 固定オフセット(UtcOffset)のみを標準サポートしています。IANAタイムゾーンのネイティブサポートはなく、非公式のtime-tzクレートで限定的に対応できますが、夏時間(DST)を考慮した安全な演算は困難です。

jiff: IANAタイムゾーンが設計レベルで統合されています。OSのタイムゾーンデータベースを自動的に読み取り、DSTの遷移を正しく処理します。さらにRFC 9557に準拠しており、タイムゾーン識別子を含めたロスレスなシリアライズ・デシリアライズが可能です。

// chronoでのタイムゾーン処理(chrono-tz併用)
use chrono::TimeZone;
use chrono_tz::Asia::Tokyo;
let dt = Tokyo.with_ymd_and_hms(2026, 3, 2, 15, 0, 0).unwrap();

// timeではIANAタイムゾーンを直接扱えない
use time::OffsetDateTime;
let dt = OffsetDateTime::now_utc().to_offset(time::UtcOffset::from_hms(9, 0, 0).unwrap());

// jiffならIANAタイムゾーンがネイティブ
use jiff::Zoned;
let dt: Zoned = "2026-03-02T15:00:00[Asia/Tokyo]".parse().unwrap();

serde統合

機能chronotimejiff
デフォルト形式RFC 3339RFC 3339/2822/ISO 8601から選択RFC 9557
Unixタイムスタンプchrono::serde::ts_secondsカスタム実装が必要Timestampで対応
TZ識別子のシリアライズ不可(オフセットのみ)非対応可能(RFC 9557)
コンパイル時チェックなしformat_description!マクロあり

chronoではDateTime<Tz>をシリアライズするとタイムゾーン識別子(Asia/Tokyoなど)が失われ、固定オフセット(+09:00)のみが保存されます。デシリアライズ時にDST情報が復元できないため、夏時間をまたぐ演算で不正確な結果が生じる可能性があります。jiffはRFC 9557によりこの問題を解決しています。

WASM・no_std対応

機能chronotimejiff
WASM (wasm32-unknown-unknown)wasmbind featurewasm-bindgen feature対応
no_std部分的設計レベルで対応部分的
組み込み環境困難推奨困難

組み込み環境やメモリ制約の厳しい場面ではtimeが最適です。#![no_std]環境を前提とした設計で、std featureを無効にすることでヒープアロケーションなしで動作します。

ユースケース別クレート選定ガイド

2026年3月時点で、新規プロジェクトのクレート選定は以下の基準で判断できます。

UTCタイムスタンプのみで十分な場合

APIサーバーのログ、データベースのcreated_atカラムなど、UTC基準のタイムスタンプだけを扱うケースです。

推奨: chrono または time

どちらでも十分に対応可能です。エコシステムとの互換性を考慮してください。SQLx・Dieselなどのデータベースクレートはchronoとの統合が最も成熟しています。

IANAタイムゾーンが必要な場合

ユーザーのローカル時刻表示、カレンダーアプリ、国際的なスケジューリングなど、Asia/TokyoAmerica/New_YorkといったIANAタイムゾーンを正確に扱う必要がある場面です。

推奨: jiff

海外のRustコミュニティでは、タイムゾーンが必要な場面でjiffが推奨されつつあります(出典: State of the Crates 2025)。DST遷移を正しく処理し、ロスレスなシリアライズが可能です。ただし2026年3月時点でv0.2系(1.0未満)であり、APIの破壊的変更が発生する可能性がある点は留意してください。

no_std / 組み込み環境の場合

推奨: time

no_std対応が設計レベルで組み込まれているtimeが最適です。ヒープアロケーションなしでの日時処理が可能で、IoTデバイスやカーネルモジュールなどのリソース制約環境に適しています。

既存のchronoプロジェクトの場合

即座の移行は不要です。 chrono v0.4系は2026年2月時点でもリリースが続いており、セキュリティ問題も解消済みです。ただし以下の理由から、中長期的にjiffの1.0リリース後に移行を検討する価値があります。

  • メインメンテナーがメンテナンス縮小の意向を示している
  • chrono 0.5(メジャーアップデート)の見通しが不透明
  • Open Issuesが187件と多く、対応が追いつかない可能性がある
  • API設計が2014年基準のままで、モダンなRustのイディオムに合わない部分がある

選定フローチャート

Rust日付時刻クレート選定フロー:IANAタイムゾーンの必要性、no_std対応、DB連携の有無に応じてjiff・chrono・timeを選択する判断チャート

chrono → time 移行のコード例

chronoからtimeへの移行で頻出するパターンを示します。

現在時刻の取得

// chrono
use chrono::Utc;
let now = Utc::now();

// time
use time::OffsetDateTime;
let now = OffsetDateTime::now_utc();

日付の生成

// chrono
use chrono::NaiveDate;
let date = NaiveDate::from_ymd_opt(2026, 3, 2).unwrap();

// time
use time::Date;
use time::Month;
let date = Date::from_calendar_date(2026, Month::March, 2).unwrap();

文字列からのパース

// chrono
use chrono::DateTime;
let dt = DateTime::parse_from_rfc3339("2026-03-02T15:00:00+09:00").unwrap();

// time
use time::OffsetDateTime;
use time::format_description::well_known::Rfc3339;
let dt = OffsetDateTime::parse("2026-03-02T15:00:00+09:00", &Rfc3339).unwrap();

カスタムフォーマットでの出力

// chrono
use chrono::Utc;
let formatted = Utc::now().format("%Y年%m月%d日 %H:%M").to_string();

// time(コンパイル時にフォーマットを検証)
use time::OffsetDateTime;
use time::macros::format_description;
let format = format_description!("[year]年[month padding:zero]月[day padding:zero]日 [hour]:[minute]");
let formatted = OffsetDateTime::now_utc().format(&format).unwrap();

timeのformat_description!マクロはコンパイル時にフォーマット文字列を検証するため、実行時エラーを防げるという利点があります。

期間の計算

// chrono
use chrono::{Utc, TimeDelta};
let future = Utc::now() + TimeDelta::days(30);

// time
use time::{OffsetDateTime, Duration};
let future = OffsetDateTime::now_utc() + Duration::days(30);

移行時の注意点

  1. Months型の非対応: chronoのMonths型(月単位の期間)にはtimeに直接対応する型がありません。手動での実装が必要です
  2. strftime形式の廃止: chronoの%Y-%m-%d形式はtimeでは使えません。format_description!マクロの独自記法に書き換える必要があります
  3. タイムゾーン機能の縮小: DateTime<Local>のような便利な型がtimeにはありません。ローカル時刻の取得はOffsetDateTime::now_local()で可能ですが、環境によっては失敗します
  4. 相互変換: 段階的な移行にはtimetravelerクレートが使えます。chrono ↔ time間の型変換を提供します

jiffの登場: Rustの日時処理の新たな選択肢

2024年7月にBurntSushi氏(Andrew Gallant氏、ripgrepの作者)がリリースしたjiffは、chrono・timeの双方が抱える課題を根本から解決するために設計されたクレートです。海外のRustコミュニティでは急速に採用が広がっており、日本の開発者も注目すべき存在です。

jiffが解決する3つの課題

1. ロスレスなタイムゾーンのシリアライズ

chronoではDateTime<Tz>をJSON等にシリアライズすると、タイムゾーン識別子(Asia/Tokyo)が失われ、固定オフセット(+09:00)のみが保存されます。デシリアライズ後にDSTをまたぐ演算を行うと不正確な結果になるリスクがあります。

jiffはRFC 9557に準拠し、2026-03-02T15:00:00+09:00[Asia/Tokyo]のようにタイムゾーン識別子を含めてシリアライズします。

2. DST安全なカレンダー演算

「3月の第2日曜日の午前2時に1時間進む」といったDST遷移をまたぐ演算を、正しく処理します。chronoでは日単位のDST対応加算は可能ですが、月・年を含む複合演算は不完全です。timeはIANAタイムゾーン自体を標準サポートしないため、DST安全な演算は困難です。

3. システムタイムゾーンDBとの連携

jiffはOSが提供するタイムゾーンデータベースを自動的に読み取ります。chrono-tzのようにバイナリに全データを埋め込む必要がなく、コンパイル時間とバイナリサイズへの影響が軽微です。Windowsでは埋め込みデータにフォールバックする仕組みも備えています。

jiffの注意点

  • 2026年3月時点でv0.2系(1.0未満)。APIの破壊的変更の可能性があります
  • 1.0リリースは2026年春〜夏を目標としています
  • Zoned型はCopyトレイトを実装していません(内部にタイムゾーンデータへの参照を保持するため)。chronoのDateTime<Utc>Copy可能であるのと対照的です
  • エコシステムとの統合はchronoほど成熟していません

chronoの「うるう秒」処理に関する留意点

海外のRustコミュニティでは、chronoのうるう秒処理に対する技術的な批判も存在します。

chronoは秒の値として60(うるう秒)を許容します。これによりNaiveTime::from_hms_opt(23, 59, 60)が有効な値として扱われますが、演算の数学的な性質が壊れるケースがあります。具体的には、異なる2つの時刻t1t2t1 != t2)に同じDurationを加算した結果が一致する(t1 + delta == t2 + delta)という現象が起こり得ます。

一般的なWebアプリケーションやビジネスロジックでうるう秒を考慮する必要はほぼありませんが、金融系のタイムスタンプや科学計算など精密な時刻処理が求められる場面では、この挙動を把握しておく必要があります。

まとめ: 2026年のRust日時クレート選びの結論

chronoは「メンテナンスモード」ではなく、2026年2月時点でもリリースが続いているアクティブなクレートです。ただし、メインメンテナーのメンテナンス縮小表明やOpen Issuesの多さ(187件)から、長期的な安定性には注意が必要です。

3クレートの立ち位置を一言で整理すると以下のとおりです。

  • chrono: 最大のエコシステム互換性。DB連携が豊富。API設計はやや古い
  • time: モダンなAPI設計とno_std対応。タイムゾーンサポートは限定的
  • jiff: タイムゾーン処理の最適解。1.0未満だが急成長中

既存のchronoプロジェクトを急いで移行する必要はありません。v0.4.20以降ならセキュリティ問題も解消済みです。新規プロジェクトでタイムゾーンが重要ならjiffを、no_stdが必要ならtimeを、DB連携重視ならchronoを選ぶのが合理的です。jiffの1.0リリース(2026年春〜夏予定)を注視しつつ、プロジェクトの要件に合ったクレートを選定してください。