From 16858c9a276224ca632130e22f3bb7fcb2db3555 Mon Sep 17 00:00:00 2001 From: Christopher Illarionova Date: Wed, 14 Jan 2026 19:58:29 +0000 Subject: [PATCH] strtime: apply uppercase flag to compound specifiers Fixes #486, Ref #513 for coming up with a better fix --- CHANGELOG.md | 5 +++++ src/fmt/strtime/mod.rs | 32 ++++++++++++++++++++++++-------- src/fmt/strtime/printer.rs | 22 ++++++++++++++++++++++ 3 files changed, 51 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c6f9ab5..a171d386 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,11 @@ Update comparison with the `time` crate in the Jiff documentation. * [#502](https://github.com/BurntSushi/jiff/issues/502): Enable some non-default features for the Rust Playground deployment. +Bug fixes: + +* [#486](https://github.com/BurntSushi/jiff/issues/486): +Make `%^c` result in uppercase strings where appropriate. + 0.2.19 (2026-02-05) =================== diff --git a/src/fmt/strtime/mod.rs b/src/fmt/strtime/mod.rs index 383be5b3..d18d868d 100644 --- a/src/fmt/strtime/mod.rs +++ b/src/fmt/strtime/mod.rs @@ -668,11 +668,15 @@ pub trait Custom: Sized { fn format_datetime( &self, config: &Config, - _ext: &Extension, + ext: &Extension, tm: &BrokenDownTime, wtr: &mut W, ) -> Result<(), Error> { - tm.format_with_config(config, "%Y M%m %-d, %a %H:%M:%S", wtr) + if matches!(ext.flag, Some(Flag::Uppercase)) { + tm.format_with_config(config, "%Y M%m %-d, %^a %H:%M:%S", wtr) + } else { + tm.format_with_config(config, "%Y M%m %-d, %a %H:%M:%S", wtr) + } } /// Called when formatting a datetime with the `%x` flag. @@ -708,11 +712,15 @@ pub trait Custom: Sized { fn format_12hour_time( &self, config: &Config, - _ext: &Extension, + ext: &Extension, tm: &BrokenDownTime, wtr: &mut W, ) -> Result<(), Error> { - tm.format_with_config(config, "%-I:%M:%S %p", wtr) + if matches!(ext.flag, Some(Flag::Uppercase)) { + tm.format_with_config(config, "%-I:%M:%S %^p", wtr) + } else { + tm.format_with_config(config, "%-I:%M:%S %p", wtr) + } } } @@ -791,11 +799,15 @@ impl Custom for PosixCustom { fn format_datetime( &self, config: &Config, - _ext: &Extension, + ext: &Extension, tm: &BrokenDownTime, wtr: &mut W, ) -> Result<(), Error> { - tm.format_with_config(config, "%a %b %e %H:%M:%S %Y", wtr) + if matches!(ext.flag, Some(Flag::Uppercase)) { + tm.format_with_config(config, "%^a %^b %e %H:%M:%S %Y", wtr) + } else { + tm.format_with_config(config, "%a %b %e %H:%M:%S %Y", wtr) + } } fn format_date( @@ -821,11 +833,15 @@ impl Custom for PosixCustom { fn format_12hour_time( &self, config: &Config, - _ext: &Extension, + ext: &Extension, tm: &BrokenDownTime, wtr: &mut W, ) -> Result<(), Error> { - tm.format_with_config(config, "%I:%M:%S %p", wtr) + if matches!(ext.flag, Some(Flag::Uppercase)) { + tm.format_with_config(config, "%I:%M:%S %^p", wtr) + } else { + tm.format_with_config(config, "%I:%M:%S %p", wtr) + } } } diff --git a/src/fmt/strtime/printer.rs b/src/fmt/strtime/printer.rs index 85817ba0..4688bc9d 100644 --- a/src/fmt/strtime/printer.rs +++ b/src/fmt/strtime/printer.rs @@ -1421,6 +1421,28 @@ mod tests { ); } + #[test] + fn ok_format_compound_uppercase() { + let f = |fmt: &str, date: DateTime| format(fmt, date).unwrap(); + + insta::assert_snapshot!( + f("%^c", date(2024, 7, 14).at(0, 0, 0, 0)), + @"2024 M07 14, SUN 00:00:00", + ); + insta::assert_snapshot!( + f("%^x", date(2024, 7, 14).at(0, 0, 0, 0)), + @"2024 M07 14", + ); + insta::assert_snapshot!( + f("%^X", date(2024, 7, 14).at(8, 30, 0, 0)), + @"08:30:00", + ); + insta::assert_snapshot!( + f("%^r", date(2024, 7, 14).at(8, 30, 0, 0)), + @"8:30:00 AM", + ); + } + #[test] fn ok_format_posix_locale() { let f = |fmt: &str, date: DateTime| {