fix: add i18n options for past tense, future tense time (#3245)

This commit is contained in:
Charles Kerr
2022-06-14 21:56:27 -05:00
committed by GitHub
parent 922ae556d7
commit b85edf8d0f
5 changed files with 153 additions and 69 deletions

View File

@@ -86,37 +86,136 @@ Glib::ustring tr_strlsize(guint64 bytes)
return bytes == 0 ? Q_("None") : tr_formatter_size_B(bytes);
}
Glib::ustring tr_strltime(time_t seconds)
namespace
{
if (seconds < 0)
std::string tr_format_future_time(time_t seconds)
{
if (auto const days_from_now = seconds / 86400U; days_from_now > 0U)
{
seconds = 0;
return fmt::format(
ngettext("{days_from_now:L} day from now", "{days_from_now:L} days from now", days_from_now),
fmt::arg("days_from_now", days_from_now));
}
auto const days = (int)(seconds / 86400);
auto const d = fmt::format(ngettext("{days:L} day", "{days:L} days", days), fmt::arg("days", days));
int const hours = (seconds % 86400) / 3600;
auto const h = fmt::format(ngettext("{hours} hour", "{hours} hours", hours), fmt::arg("hours", hours));
if (days != 0)
if (auto const hours_from_now = (seconds % 86400U) / 3600U; hours_from_now > 0U)
{
return (days >= 4 || hours == 0) ? d : fmt::format(FMT_STRING("{:s}, {:s}"), d, h);
return fmt::format(
ngettext("{hours_from_now:L} hour from now", "{hours_from_now:L} hours from now", hours_from_now),
fmt::arg("hours_from_now", hours_from_now));
}
int const minutes = (seconds % 3600) / 60;
auto const m = fmt::format(ngettext("{minutes} minute", "{minutes} minutes", minutes), fmt::arg("minutes", minutes));
if (hours != 0)
if (auto const minutes_from_now = (seconds % 3600U) / 60U; minutes_from_now > 0U)
{
return (hours >= 4 || minutes == 0) ? h : fmt::format(FMT_STRING("{:s}, {:s}"), h, m);
return fmt::format(
ngettext("{minutes_from_now:L} minute from now", "{minutes_from_now:L} minutes from now", minutes_from_now),
fmt::arg("minutes_from_now", minutes_from_now));
}
seconds = (seconds % 3600) % 60;
auto const s = fmt::format(ngettext("{seconds} second", "{seconds} seconds", seconds), fmt::arg("seconds", seconds));
if (minutes != 0)
if (auto const seconds_from_now = seconds % 60U; seconds_from_now > 0U)
{
return (minutes >= 4 || seconds == 0) ? m : fmt::format(FMT_STRING("{:s}, {:s}"), m, s);
return fmt::format(
ngettext("{seconds_from_now:L} second from now", "{seconds_from_now:L} seconds from now", seconds_from_now),
fmt::arg("seconds_from_now", seconds_from_now));
}
return s;
return _("now");
}
std::string tr_format_past_time(time_t seconds)
{
if (auto const days_ago = seconds / 86400U; days_ago > 0U)
{
return fmt::format(ngettext("{days_ago:L} day ago", "{days_ago:L} days ago", days_ago), fmt::arg("days_ago", days_ago));
}
if (auto const hours_ago = (seconds % 86400U) / 3600U; hours_ago > 0U)
{
return fmt::format(
ngettext("{hours_ago:L} hour ago", "{hours_ago:L} hours ago", hours_ago),
fmt::arg("hours_ago", hours_ago));
}
if (auto const minutes_ago = (seconds % 3600U) / 60U; minutes_ago > 0U)
{
return fmt::format(
ngettext("{minutes_ago:L} minute ago", "{minutes_ago:L} minutes ago", minutes_ago),
fmt::arg("minutes_ago", minutes_ago));
}
if (auto const seconds_ago = seconds % 60U; seconds_ago > 0U)
{
return fmt::format(
ngettext("{seconds_ago:L} second ago", "{seconds_ago:L} seconds ago", seconds_ago),
fmt::arg("seconds_ago", seconds_ago));
}
return _("now");
}
} // namespace
std::string tr_format_time(time_t secs)
{
if (auto const days = secs / 86400U; days > 0U)
{
return fmt::format(ngettext("{days:L} day", "{days:L} days", days), fmt::arg("days", days));
}
if (auto const hours = (secs % 86400U) / 3600U; hours > 0U)
{
return fmt::format(ngettext("{hours:L} hour", "{hours:L} hours", hours), fmt::arg("hours", hours));
}
if (auto const minutes = (secs % 3600U) / 60U; minutes > 0U)
{
return fmt::format(ngettext("{minutes:L} minute", "{minutes:L} minutes", minutes), fmt::arg("minutes", minutes));
}
if (auto const seconds = secs % 60U; seconds > 0U)
{
return fmt::format(ngettext("{seconds:L} second", "{seconds:L} seconds", seconds), fmt::arg("seconds", seconds));
}
return _("now");
}
std::string tr_format_time_left(time_t seconds)
{
if (auto const days_left = seconds / 86400U; days_left > 0U)
{
return fmt::format(
ngettext("{days_left:L} day left", "{days_left:L} days left", days_left),
fmt::arg("days_left", days_left));
}
if (auto const hours_left = (seconds % 86400U) / 3600U; hours_left > 0U)
{
return fmt::format(
ngettext("{hours_left:L} hour left", "{hours_left:L} hours left", hours_left),
fmt::arg("hours_left", hours_left));
}
if (auto const minutes_left = (seconds % 3600U) / 60U; minutes_left > 0U)
{
return fmt::format(
ngettext("{minutes_left:L} minute left", "{minutes_left:L} minutes left", minutes_left),
fmt::arg("minutes_left", minutes_left));
}
if (auto const seconds_left = seconds % 60U; seconds_left > 0U)
{
return fmt::format(
ngettext("{seconds_left:L} second left", "{seconds_left:L} seconds left", seconds_left),
fmt::arg("seconds_left", seconds_left));
}
return _("now");
}
std::string tr_format_time_relative(time_t src, time_t dst)
{
return src < dst ? tr_format_future_time(dst - src) : tr_format_past_time(src - dst);
}
namespace