mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-24 21:34:08 +03:00
time-util: don't use plural units indiscriminately
format_timestamp_relative currently returns the plural form of years and months no matter the quantity, and in many cases (for durations > 1 week) this is the same with days. This patch changes this so that the function takes the quantity into account, returning "1 month 1 week ago" instead of "1 months 1 weeks ago".
This commit is contained in:
parent
df8fd03a7d
commit
45eb4d2261
@ -429,18 +429,36 @@ char *format_timestamp_relative(char *buf, size_t l, usec_t t) {
|
|||||||
s = "left";
|
s = "left";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d >= USEC_PER_YEAR)
|
if (d >= USEC_PER_YEAR) {
|
||||||
snprintf(buf, l, USEC_FMT " years " USEC_FMT " months %s",
|
usec_t years = d / USEC_PER_YEAR;
|
||||||
d / USEC_PER_YEAR,
|
usec_t months = (d % USEC_PER_YEAR) / USEC_PER_MONTH;
|
||||||
(d % USEC_PER_YEAR) / USEC_PER_MONTH, s);
|
snprintf(buf, l, USEC_FMT " %s " USEC_FMT " %s %s",
|
||||||
else if (d >= USEC_PER_MONTH)
|
years,
|
||||||
snprintf(buf, l, USEC_FMT " months " USEC_FMT " days %s",
|
years == 1 ? "year" : "years",
|
||||||
d / USEC_PER_MONTH,
|
months,
|
||||||
(d % USEC_PER_MONTH) / USEC_PER_DAY, s);
|
months == 1 ? "month" : "months",
|
||||||
else if (d >= USEC_PER_WEEK)
|
s);
|
||||||
snprintf(buf, l, USEC_FMT " weeks " USEC_FMT " days %s",
|
}
|
||||||
d / USEC_PER_WEEK,
|
else if (d >= USEC_PER_MONTH) {
|
||||||
(d % USEC_PER_WEEK) / USEC_PER_DAY, s);
|
usec_t months = d / USEC_PER_MONTH;
|
||||||
|
usec_t days = (d % USEC_PER_MONTH) / USEC_PER_DAY;
|
||||||
|
snprintf(buf, l, USEC_FMT " %s " USEC_FMT " %s %s",
|
||||||
|
months,
|
||||||
|
months == 1 ? "month" : "months",
|
||||||
|
days,
|
||||||
|
days == 1 ? "day" : "days",
|
||||||
|
s);
|
||||||
|
}
|
||||||
|
else if (d >= USEC_PER_WEEK) {
|
||||||
|
usec_t weeks = d / USEC_PER_WEEK;
|
||||||
|
usec_t days = (d % USEC_PER_WEEK) / USEC_PER_DAY;
|
||||||
|
snprintf(buf, l, USEC_FMT " %s " USEC_FMT " %s %s",
|
||||||
|
weeks,
|
||||||
|
weeks == 1 ? "week" : "weeks",
|
||||||
|
days,
|
||||||
|
days == 1 ? "day" : "days",
|
||||||
|
s);
|
||||||
|
}
|
||||||
else if (d >= 2*USEC_PER_DAY)
|
else if (d >= 2*USEC_PER_DAY)
|
||||||
snprintf(buf, l, USEC_FMT " days %s", d / USEC_PER_DAY, s);
|
snprintf(buf, l, USEC_FMT " days %s", d / USEC_PER_DAY, s);
|
||||||
else if (d >= 25*USEC_PER_HOUR)
|
else if (d >= 25*USEC_PER_HOUR)
|
||||||
|
@ -360,6 +360,80 @@ static void test_format_timestamp(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_format_timestamp_relative(void) {
|
||||||
|
log_info("/* %s */", __func__);
|
||||||
|
|
||||||
|
char buf[MAX(FORMAT_TIMESTAMP_MAX, FORMAT_TIMESPAN_MAX)];
|
||||||
|
usec_t x;
|
||||||
|
|
||||||
|
/* Only testing timestamps in the past so we don't need to add some delta to account for time passing
|
||||||
|
* by while we are running the tests (unless we're running on potatoes and 24 hours somehow passes
|
||||||
|
* between our call to now() and format_timestamp_relative's call to now()). */
|
||||||
|
|
||||||
|
/* Years and months */
|
||||||
|
x = now(CLOCK_REALTIME) - (1*USEC_PER_YEAR + 1*USEC_PER_MONTH);
|
||||||
|
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
||||||
|
log_info("%s", buf);
|
||||||
|
assert_se(streq(buf, "1 year 1 month ago"));
|
||||||
|
|
||||||
|
x = now(CLOCK_REALTIME) - (1*USEC_PER_YEAR + 2*USEC_PER_MONTH);
|
||||||
|
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
||||||
|
log_info("%s", buf);
|
||||||
|
assert_se(streq(buf, "1 year 2 months ago"));
|
||||||
|
|
||||||
|
x = now(CLOCK_REALTIME) - (2*USEC_PER_YEAR + 1*USEC_PER_MONTH);
|
||||||
|
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
||||||
|
log_info("%s", buf);
|
||||||
|
assert_se(streq(buf, "2 years 1 month ago"));
|
||||||
|
|
||||||
|
x = now(CLOCK_REALTIME) - (2*USEC_PER_YEAR + 2*USEC_PER_MONTH);
|
||||||
|
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
||||||
|
log_info("%s", buf);
|
||||||
|
assert_se(streq(buf, "2 years 2 months ago"));
|
||||||
|
|
||||||
|
/* Months and days */
|
||||||
|
x = now(CLOCK_REALTIME) - (1*USEC_PER_MONTH + 1*USEC_PER_DAY);
|
||||||
|
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
||||||
|
log_info("%s", buf);
|
||||||
|
assert_se(streq(buf, "1 month 1 day ago"));
|
||||||
|
|
||||||
|
x = now(CLOCK_REALTIME) - (1*USEC_PER_MONTH + 2*USEC_PER_DAY);
|
||||||
|
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
||||||
|
log_info("%s", buf);
|
||||||
|
assert_se(streq(buf, "1 month 2 days ago"));
|
||||||
|
|
||||||
|
x = now(CLOCK_REALTIME) - (2*USEC_PER_MONTH + 1*USEC_PER_DAY);
|
||||||
|
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
||||||
|
log_info("%s", buf);
|
||||||
|
assert_se(streq(buf, "2 months 1 day ago"));
|
||||||
|
|
||||||
|
x = now(CLOCK_REALTIME) - (2*USEC_PER_MONTH + 2*USEC_PER_DAY);
|
||||||
|
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
||||||
|
log_info("%s", buf);
|
||||||
|
assert_se(streq(buf, "2 months 2 days ago"));
|
||||||
|
|
||||||
|
/* Weeks and days */
|
||||||
|
x = now(CLOCK_REALTIME) - (1*USEC_PER_WEEK + 1*USEC_PER_DAY);
|
||||||
|
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
||||||
|
log_info("%s", buf);
|
||||||
|
assert_se(streq(buf, "1 week 1 day ago"));
|
||||||
|
|
||||||
|
x = now(CLOCK_REALTIME) - (1*USEC_PER_WEEK + 2*USEC_PER_DAY);
|
||||||
|
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
||||||
|
log_info("%s", buf);
|
||||||
|
assert_se(streq(buf, "1 week 2 days ago"));
|
||||||
|
|
||||||
|
x = now(CLOCK_REALTIME) - (2*USEC_PER_WEEK + 1*USEC_PER_DAY);
|
||||||
|
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
||||||
|
log_info("%s", buf);
|
||||||
|
assert_se(streq(buf, "2 weeks 1 day ago"));
|
||||||
|
|
||||||
|
x = now(CLOCK_REALTIME) - (2*USEC_PER_WEEK + 2*USEC_PER_DAY);
|
||||||
|
assert_se(format_timestamp_relative(buf, sizeof(buf), x));
|
||||||
|
log_info("%s", buf);
|
||||||
|
assert_se(streq(buf, "2 weeks 2 days ago"));
|
||||||
|
}
|
||||||
|
|
||||||
static void test_format_timestamp_utc_one(usec_t val, const char *result) {
|
static void test_format_timestamp_utc_one(usec_t val, const char *result) {
|
||||||
char buf[FORMAT_TIMESTAMP_MAX];
|
char buf[FORMAT_TIMESTAMP_MAX];
|
||||||
const char *t;
|
const char *t;
|
||||||
@ -539,6 +613,7 @@ int main(int argc, char *argv[]) {
|
|||||||
test_usec_sub_signed();
|
test_usec_sub_signed();
|
||||||
test_usec_sub_unsigned();
|
test_usec_sub_unsigned();
|
||||||
test_format_timestamp();
|
test_format_timestamp();
|
||||||
|
test_format_timestamp_relative();
|
||||||
test_format_timestamp_utc();
|
test_format_timestamp_utc();
|
||||||
test_deserialize_dual_timestamp();
|
test_deserialize_dual_timestamp();
|
||||||
test_usec_shift_clock();
|
test_usec_shift_clock();
|
||||||
|
Loading…
Reference in New Issue
Block a user