Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

%Z can't print the timezone abbreviation #960

Closed
howjmay opened this issue Feb 13, 2023 · 12 comments
Closed

%Z can't print the timezone abbreviation #960

howjmay opened this issue Feb 13, 2023 · 12 comments

Comments

@howjmay
Copy link

howjmay commented Feb 13, 2023

Hi I am having a use case that I need to generate formatted time, and the text should contain the abbreviation of the timezone.
I am using format_with_items(), and a format string "%a %b %d %I:%M:%S '%Z' %p %Y". However, %Z doesn't return the abbreviation. What should I do?

@djc
Copy link
Contributor

djc commented Feb 13, 2023

This issue doesn't come with a reproducible example, nor does it show the actual output. Please extend your bug report.

@howjmay
Copy link
Author

howjmay commented Feb 13, 2023

@djc An example is like following

use chrono::{format::StrftimeItems, Local};

fn main() {
    let now = Local::now();
    now.with_timezone(now.offset());
    let formatted = now
        .format_with_items(StrftimeItems::new("%a %b %d %I:%M:%S '%Z' %Y"))
        .to_string();
    println!("{formatted}");
}

expected result

Tue Feb 14 00:55:01 'CET' 2023

actual result

Tue Feb 14 12:56:24 '+08:00' 2023

The expected abbreviation CET is replaced by +08:00. Or I should use other escape character then I can get the abbreviation of timezone?

@djc
Copy link
Contributor

djc commented Feb 14, 2023

chrono itself doesn't know timezones beyond their offsets, so I don't think it can do what you want. Maybe look at the chrono-tz crate and see if it can help with this?

@esheppa
Copy link
Collaborator

esheppa commented Feb 14, 2023

@howjmay - please see also this issue: #749.

chrono-tz should do this correctly as per here as the display implementation of the TimeZone type is called. You can use chrono-tz and iana-time-zone (a dependency of chrono) together to have behaviour equivalent to local. First use iana-time-zone to get the name of the locally set timezone, then you can parse that into a chrono_tz::Tz, as per the example:

let tz_str = iana_time_zone::get_timezone()?;
let tz: chrono_tz::Tz = tz_str.parse()?;

There is also a partially complete PR to solve this #750 and we would appreciate any thoughts or comments you have on it.

@howjmay
Copy link
Author

howjmay commented Feb 15, 2023

Hi @esheppa the method you provided is good.
However, I found a problem when I checkout the list in chono_tz. The abbreviations of the timezones in chrono_tz seems not complete.
See the wiki https://en.wikipedia.org/wiki/List_of_time_zone_abbreviations
Most of the abbreviation doesn't exist in the list in chono_tz. Or I misunderstand the way to use it?

@djc
Copy link
Contributor

djc commented Feb 15, 2023

chrono-tz includes data from the IANA database. It's definitely possible that this doesn't encompass all abbreviations listed on Wikipedia. I think it is reasonable to consider the IANA database authoritative in this regard.

@howjmay
Copy link
Author

howjmay commented Feb 15, 2023

thanks!

@campbellcole
Copy link
Contributor

While this being an issue is understandable, the documentation makes it seem like chrono should be able to do this:

https://docs.rs/chrono/latest/chrono/format/strftime/index.html

There are even footnotes for this specifier but none that say it isn't supported for formatting. If possible, I would love the documentation to reflect this. Thanks for your time.

@pitdicker
Copy link
Collaborator

@campbellcole Would you be willing to make a PR?

@campbellcole
Copy link
Contributor

campbellcole commented May 6, 2023 via email

@campbellcole
Copy link
Contributor

For anyone finding this issue from the documentation, you can accomplish this using two additional crates (chrono-tz and iana-time-zone):

use chrono::{TimeZone, Utc};
use chrono_tz::{OffsetName, Tz};
use iana_time_zone::get_timezone;

let tz_str = get_timezone().unwrap();
let tz: Tz = tz_str.parse().unwrap();
let offset = tz.offset_from_utc_date(&Utc::now().date_naive());
let abbreviation = offset.abbreviation();
println!("{abbreviation}");

@djc
Copy link
Contributor

djc commented May 15, 2023

Better documented in #1051.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants