#date #time #timezone #zone #calendar

chrono-tz

TimeZone implementations for rust-chrono from the IANA database

18 releases

Uses old Rust 2015

0.5.3 Aug 29, 2020
0.5.2 Jun 10, 2020
0.5.1 Mar 19, 2019
0.5.0 Jul 5, 2018
0.2.4 Nov 27, 2016

#2 in Date and time

Download history 9421/week @ 2020-06-04 11475/week @ 2020-06-11 13049/week @ 2020-06-18 9592/week @ 2020-06-25 8304/week @ 2020-07-02 8226/week @ 2020-07-09 8873/week @ 2020-07-16 9020/week @ 2020-07-23 10203/week @ 2020-07-30 11764/week @ 2020-08-06 11709/week @ 2020-08-13 12241/week @ 2020-08-20 13084/week @ 2020-08-27 15358/week @ 2020-09-03 13909/week @ 2020-09-10 13717/week @ 2020-09-17

48,487 downloads per month
Used in 92 crates (61 directly)

MIT/Apache

555KB
7.5K SLoC

C 6.5K SLoC // 0.1% comments Rust 817 SLoC // 0.1% comments Shell 59 SLoC // 0.1% comments Perl 42 SLoC // 0.1% comments

Chrono-TZ 0.5.3

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

Documentation is hosted on docs.rs

Usage

Put this in your Cargo.toml:

[dependencies]
chrono = "0.4"
chrono-tz = "0.5"

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

extern crate chrono;
extern crate chrono_tz;

Examples

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

You can get the raw offsets as well if you want to see the standard UTC offset as well as any special offsets in effect (such as DST) at a given time. Note that you need to import the 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));

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

no_std Support

To use this library without depending on the Rust standard library, put this in your Cargo.toml:

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

If you are using this library in an environment with limited program space, such as a microcontroller, take note that you will also likely need to enable optimizations and Link Time Optimization:

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

[profile.release]
lto = true

Otherwise, the additional binary size added by this library may overflow available program space and trigger a linker error.

Future Improvements

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

Dependencies