Browse Source

Better formatting of date times, including time zones

David Peter 1 year ago
parent
commit
6af1f872af
2 changed files with 39 additions and 1 deletions
  1. 20 0
      examples/tests/datetime.nbt
  2. 19 1
      numbat/src/datetime.rs

+ 20 - 0
examples/tests/datetime.nbt

@@ -47,6 +47,26 @@ assert_eq(format_datetime("%Y-%m-%dT%H:%M:%S%:z", test_date2), "2024-01-02T13:24
 assert_eq(format_datetime("%Y-%m-%dT%H:%M:%S.%3f%:z", test_date3), "2024-01-02T13:24:56.789+00:00")
 
 
+
+# Time zone conversions
+
+fn as_string(dt: DateTime) -> String = "{dt}"
+
+assert_eq(as_string(test_date3), "2024-01-02 13:24:56 UTC")
+assert_eq(as_string(test_date3 -> UTC),
+          "2024-01-02 13:24:56 UTC")
+
+assert_eq(as_string(test_date3 -> tz("Europe/Berlin")),
+          "2024-01-02 14:24:56 CET (UTC +01), Europe/Berlin")
+assert_eq(as_string(test_date3 -> tz("US/Eastern")),
+            "2024-01-02 08:24:56 EST (UTC -05), US/Eastern")
+assert_eq(as_string(test_date3 -> tz("Asia/Kathmandu")),
+            "2024-01-02 19:09:56 (UTC +05:45), Asia/Kathmandu")
+
+
+
+
+
 # Test leap years (2020 was a leap year)
 let dt_leap = datetime("2020-02-28 20:00 UTC")
 assert_eq(format_datetime("%Y/%m/%d", dt_leap + 12 hours), "2020/02/29")

+ 19 - 1
numbat/src/datetime.rs

@@ -69,9 +69,27 @@ pub fn parse_datetime(input: &str) -> Result<Zoned, jiff::Error> {
 }
 
 pub fn to_string(dt: &Zoned) -> String {
+    let tz = dt.time_zone();
+
     if dt.time_zone() == &TimeZone::UTC {
         dt.strftime("%Y-%m-%d %H:%M:%S UTC").to_string()
     } else {
-        dt.strftime("%Y-%m-%d %H:%M:%S %Z (UTC %z)").to_string()
+        let offset = dt.offset();
+        let zone_abbreviation = dt.strftime("%Z").to_string();
+        let abbreviation_and_offset =
+            if zone_abbreviation.starts_with('+') || zone_abbreviation.starts_with('-') {
+                format!("(UTC {})", offset)
+            } else {
+                format!("{} (UTC {})", zone_abbreviation, offset)
+            };
+
+        let timezone_name = if let Some(iana_tz_name) = tz.iana_name() {
+            format!(", {iana_tz_name}")
+        } else {
+            "".into()
+        };
+
+        let dt_str = dt.strftime("%Y-%m-%d %H:%M:%S");
+        format!("{dt_str} {abbreviation_and_offset}{timezone_name}")
     }
 }