TimeZone implementations for rust-chrono from the IANA database
Switch branches/tags
Nothing to show
Clone or download
Latest commit c9b2c55 Dec 15, 2018
Type Name Latest commit message Commit time
Failed to load latest commit information.
src Don't warn on dead code in test Jun 29, 2018
tests upgrade to chrono 0.3 Feb 11, 2017
tz @ 19e2701 update to tz 2018g Dec 15, 2018
.gitignore initial commit Oct 8, 2016
.gitmodules update tz database (as a git submodule) Nov 5, 2016
Cargo.toml Opt-out of the default-features of chrono Dec 15, 2018
LICENSE clarify license applicability Oct 8, 2016
README.md Update README.md Jul 9, 2018
build.rs impl Hash for Tz Dec 21, 2017


Chrono-TZ 0.5.0

Chrono-TZ is a library that provides implementors of the TimeZone trait for rust-chrono. The impls are generated by a build script using the IANA database and parse-zoneinfo.


Documentation is hosted on docs.rs


Put this in your Cargo.toml:

chrono = "0.4"
chrono-tz = "0.5"

Then you will need to write (in your crate root):

extern crate chrono;
extern crate chrono_tz;


Create a time in one timezone and convert it to 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));

Create a naive datetime and convert it to a timezone-aware 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");

London and New York change their clocks on different days in March so only have a 4-hour difference on certain days.

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));

Adding 24 hours across a daylight savings change causes a change in local time

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));

And of course you can always convert a local time to a unix timestamp

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);

Pretty-printing a string will use the correct abbreviation for the timezone

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");

You can convert a timezone string to a timezone using the 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");

Future Improvements

  • Handle leap seconds
  • Handle Julian to Gregorian calendar transitions
  • Load tzdata always from latest version
  • Dynamic tzdata loading