Search code examples
rusttimezonetimezone-offsetchrono-tz

Is there a way to parse a timezone abbreviation into a timezone offset in Rust?


Is there a way of parsing timezone abbreviations (like EST or MDT) to a timezone offset (e.g. -5 hours or -7 hours) in Rust? The chrono_tz crate almost seems to do this, but not quite.


Solution

  • You can use chrono_tz, by subtracting the time in the requested timezone from the same time at UTC:

    use chrono::TimeZone;
    use chrono_tz::Tz;
    use chrono_tz::UTC;
    
    fn main() {
    
        let tz: Tz = "Australia/Melbourne".parse().unwrap();
        let dt = tz.ymd(2019, 05, 09).and_hms(12, 0, 0);
        let utc = UTC.ymd(2019, 05, 09).and_hms(12, 0, 0);
        let offset = utc - dt;
        println!("offset = UTC{:+02}:{:02}", offset.num_hours(), offset.num_minutes() % 60);
    
    }
    

    The result is a Duration from which you can extract hours, minutes, etc. My sample above gives output:

    offset = UTC+10:00
    

    Note that the time zones supported by chrono-tz (which are derived from the IANA TZ database) do not describe fixed offsets. Rather the database contains a set of rules describing the daylight savings changeover times for each time zone. Therefore you can only accurately obtain the offset by supplying the time at which you would like to know the offset (in my example, it was 2019-05-09 12:00:00).

    There are also a set of abbreviations for fixed offsets from UTC. These are not well standardized, and in fact the same abbreviation can mean different things in different countries. For these you may be better off making a simple lookup table for the set of abbreviations you want to support.