test_date: Extend coverage to a lot more timezones

Also test %z/%Z formats.
This commit is contained in:
Nicolas Boichat 2025-05-06 11:27:03 +08:00
parent d1525e2d2e
commit dadda0dd6a

View file

@ -2,6 +2,8 @@
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
//
// spell-checker: ignore: AEDT AEST EEST NZDT NZST
use chrono::{DateTime, Datelike, Duration, NaiveTime, Utc}; // spell-checker:disable-line
use regex::Regex;
@ -564,60 +566,43 @@ fn test_date_from_stdin() {
);
}
#[test]
fn test_date_empty_tz() {
new_ucmd!()
.env("TZ", "")
.arg("+%Z")
.succeeds()
.stdout_only("UTC\n");
}
const JAN2: &str = "2024-01-02 12:00:00 +0000";
const JUL2: &str = "2024-07-02 12:00:00 +0000";
#[test]
fn test_date_tz_utc() {
new_ucmd!()
.env("TZ", "UTC0")
.arg("+%Z")
.succeeds()
.stdout_only("UTC\n");
}
fn test_date_tz() {
fn test_tz(tz: &str, date: &str, output: &str) {
println!("Test with TZ={tz}, date=\"{date}\".");
new_ucmd!()
.env("TZ", tz)
.arg("-d")
.arg(date)
.arg("+%Y-%m-%d %H:%M:%S %Z")
.succeeds()
.stdout_only(output);
}
#[test]
fn test_date_tz_berlin() {
new_ucmd!()
.env("TZ", "Europe/Berlin")
.arg("+%Z")
.succeeds()
.stdout_matches(&Regex::new(r"^(CET|CEST)\n$").unwrap());
}
// Empty TZ, UTC0, invalid timezone.
test_tz("", JAN2, "2024-01-02 12:00:00 UTC\n");
test_tz("UTC0", JAN2, "2024-01-02 12:00:00 UTC\n");
// TODO: We do not handle invalid timezones the same way as GNU coreutils
//test_tz("Invalid/Timezone", JAN2, "2024-01-02 12:00:00 Invalid\n");
#[test]
fn test_date_tz_vancouver() {
new_ucmd!()
.env("TZ", "America/Vancouver")
.arg("+%Z")
.succeeds()
.stdout_matches(&Regex::new(r"^(PDT|PST)\n$").unwrap());
}
#[test]
fn test_date_tz_invalid() {
new_ucmd!()
.env("TZ", "Invalid/Timezone")
.arg("+%Z")
.succeeds()
.stdout_only("UTC\n");
}
#[test]
fn test_date_tz_with_format() {
new_ucmd!()
.env("TZ", "Europe/Berlin")
.arg("+%Y-%m-%d %H:%M:%S %Z")
.succeeds()
.stdout_matches(
&Regex::new(r"^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} (CET|CEST)\n$").unwrap(),
);
// Test various locations, some of them use daylight saving, some don't.
test_tz("America/Vancouver", JAN2, "2024-01-02 04:00:00 PST\n");
test_tz("America/Vancouver", JUL2, "2024-07-02 05:00:00 PDT\n");
test_tz("Europe/Berlin", JAN2, "2024-01-02 13:00:00 CET\n");
test_tz("Europe/Berlin", JUL2, "2024-07-02 14:00:00 CEST\n");
test_tz("Africa/Cairo", JAN2, "2024-01-02 14:00:00 EET\n");
// Egypt restored daylight saving in 2023, so if the database is outdated, this will fail.
//test_tz("Africa/Cairo", JUL2, "2024-07-02 15:00:00 EEST\n");
test_tz("Asia/Tokyo", JAN2, "2024-01-02 21:00:00 JST\n");
test_tz("Asia/Tokyo", JUL2, "2024-07-02 21:00:00 JST\n");
test_tz("Australia/Sydney", JAN2, "2024-01-02 23:00:00 AEDT\n");
test_tz("Australia/Sydney", JUL2, "2024-07-02 22:00:00 AEST\n"); // Shifts the other way.
test_tz("Pacific/Tahiti", JAN2, "2024-01-02 02:00:00 -10\n"); // No abbreviation.
test_tz("Antarctica/South_Pole", JAN2, "2024-01-03 01:00:00 NZDT\n");
test_tz("Antarctica/South_Pole", JUL2, "2024-07-03 00:00:00 NZST\n");
}
#[test]
@ -631,14 +616,31 @@ fn test_date_tz_with_utc_flag() {
}
#[test]
fn test_date_tz_with_date_string() {
new_ucmd!()
.env("TZ", "Asia/Tokyo")
.arg("-d")
.arg("2024-01-01 12:00:00")
.arg("+%Y-%m-%d %H:%M:%S %Z")
.succeeds()
.stdout_only("2024-01-01 12:00:00 JST\n");
fn test_date_tz_various_formats() {
fn test_tz(tz: &str, date: &str, output: &str) {
println!("Test with TZ={tz}, date=\"{date}\".");
new_ucmd!()
.env("TZ", tz)
.arg("-d")
.arg(date)
.arg("+%z %:z %::z %:::z %Z")
.succeeds()
.stdout_only(output);
}
test_tz(
"America/Vancouver",
JAN2,
"-0800 -08:00 -08:00:00 -08 PST\n",
);
// Half-hour timezone
test_tz("Asia/Calcutta", JAN2, "+0530 +05:30 +05:30:00 +05:30 IST\n");
test_tz("Europe/Berlin", JAN2, "+0100 +01:00 +01:00:00 +01 CET\n");
test_tz(
"Australia/Sydney",
JAN2,
"+1100 +11:00 +11:00:00 +11 AEDT\n",
);
}
#[test]
@ -649,7 +651,7 @@ fn test_date_tz_with_relative_time() {
.arg("1 hour ago")
.arg("+%Y-%m-%d %H:%M:%S %Z")
.succeeds()
.stdout_matches(&Regex::new(r"^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} PDT\n$").unwrap());
.stdout_matches(&Regex::new(r"^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} P[DS]T\n$").unwrap());
}
#[test]