Duration format: Add spaces, remove lead zeros for Letters (#10141)

* Add thinspaces between d/h/m/s
* Remove lead zeros
* Make letter `d` for days translatable
* Make thinspace into hairspace when compact
* Adjust and add unit tests
reviewable/pr10159/r1
melyux 1 year ago committed by GitHub
parent b610facfdc
commit 81c0bc396a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -100,10 +100,10 @@ function datetime.secondsToClock(seconds, withoutSeconds, withDays)
mins = string.format("%02d", 0)
hours = string.format("%02d", hours + 1)
end
return (days ~= "0" and (days .. "d") or "") .. hours .. ":" .. mins
return (days ~= "0" and (days .. C_("Time", "d")) or "") .. hours .. ":" .. mins
else
local secs = string.format("%02d", seconds % 60)
return (days ~= "0" and (days .. "d") or "") .. hours .. ":" .. mins .. ":" .. secs
return (days ~= "0" and (days .. C_("Time", "d")) or "") .. hours .. ":" .. mins .. ":" .. secs
end
end
end
@ -111,10 +111,10 @@ end
--- Converts seconds to a period of time string.
---- @int seconds number of seconds
---- @bool withoutSeconds if true 1h30', if false 1h30'10"
---- @bool hmsFormat, if true format 1h30m10s
---- @bool withDays, if true format 1d12h30m10s
---- @bool compact, if set removes all leading zeros (incl. units if necessary)
---- @treturn string clock string in the form of 1h30'10" or 1h30m10s
---- @bool hmsFormat, if true format 1h30m10s
---- @bool withDays, if true format 1d12h30'10" or 1d12h30m10s
---- @bool compact, if set removes all leading zeros (incl. units if necessary) and turns thinspaces into hairspaces (if present)
---- @treturn string clock string in the form of 1h30'10" or 1h30m10s
function datetime.secondsToHClock(seconds, withoutSeconds, hmsFormat, withDays, compact)
local SECONDS_SYMBOL = "\""
seconds = tonumber(seconds)
@ -150,7 +150,7 @@ function datetime.secondsToHClock(seconds, withoutSeconds, hmsFormat, withDays,
if compact then
return T(C_("Time", "%1s"), string.format("%d", seconds))
else
return T(C_("Time", "%1m%2s"), "0", string.format("%02d", seconds))
return T(C_("Time", "%1m\xE2\x80\x89%2s"), "0", string.format("%d", seconds))
end
else
if compact then
@ -177,7 +177,16 @@ function datetime.secondsToHClock(seconds, withoutSeconds, hmsFormat, withDays,
end
if hmsFormat then
return withoutSeconds and time_string or (time_string .. C_("Time", "s"))
time_string = time_string:gsub("0(%d)", "%1") -- delete all leading "0"s
time_string = time_string:gsub(C_("Time", "d"), C_("Time", "d") .. "\xE2\x80\x89") -- add thin space after "d"
time_string = time_string:gsub(C_("Time", "h"), C_("Time", "h") .. "\xE2\x80\x89") -- add thin space after "h"
if not withoutSeconds then
time_string = time_string:gsub(C_("Time", "m"), C_("Time", "m") .. "\xE2\x80\x89") .. C_("Time", "s") -- add thin space after "m"
end
if compact then
time_string = time_string:gsub("\xE2\x80\x89", "\xE2\x80\x8A") -- replace thin space with hair space
end
return time_string
else
time_string = time_string:gsub(C_("Time", "m"), "'") -- replace m with '
return withoutSeconds and time_string or (time_string .. SECONDS_SYMBOL)
@ -187,11 +196,11 @@ end
--- Converts seconds to a clock type (classic or modern), based on the given format preference
--- "Classic" format calls secondsToClock, "Modern" and "Letters" formats call secondsToHClock
---- @string Either "modern" for 1h30'10", "letters" for 1h30m10s, or "classic" for 1:30:10
---- @bool withoutSeconds if true 1h30' or 1h30m, if false 1h30'10" or 1h30m10s
---- @bool withDays, if hours>=24 include days in clock string 1d12h10m10s
---- @bool compact, if set removes all leading zeros (incl. units if necessary)
---- @treturn string clock string in the specific format of 1h30', 1h30'10" resp. 1h30m, 1h30m10s
---- @string Either "modern" for 1h30'10", "letters" for 1h30m10s, or "classic" for 1:30:10
---- @bool withoutSeconds if true 1h30' or 1h30m, if false 1h30'10" or 1h30m10s
---- @bool withDays, if hours>=24 include days in clock string 1d12h10'10" or 1d12h10m10s
---- @bool compact, if set removes all leading zeros (incl. units if necessary) and turns thinspaces into hairspaces (if present)
---- @treturn string clock string in the specific format of 1h30', 1h30'10" resp. 1h30m, 1h30m10s
function datetime.secondsToClockDuration(format, seconds, withoutSeconds, withDays, compact)
if format == "modern" then
return datetime.secondsToHClock(seconds, withoutSeconds, false, withDays, compact)

@ -128,7 +128,7 @@ common_settings.time = {
{
text_func = function()
local datetime = require("datetime")
-- sample text shows 1h23m45s
-- sample text shows 1h23m45s
local duration_format_str = datetime.secondsToClockDuration("letters", 5025, false)
return T(C_("Time", "Letters (%1)"), duration_format_str)
end,

@ -44,10 +44,28 @@ describe("datetime module", function()
assert.is_equal("00:02:00",
datetime.secondsToClock(120))
end)
it("should convert seconds to 0d00:00:00 format", function()
assert.is_equal("00:00:00",
datetime.secondsToClock(0, false, true))
assert.is_equal("00:02:00",
datetime.secondsToClock(120, false, true))
assert.is_equal("5d00:02:00",
datetime.secondsToClock(432120, false, true))
end)
it("should convert seconds to 0d00:00 format", function()
assert.is_equal("00:00",
datetime.secondsToClock(0, true, true))
assert.is_equal("00:02",
datetime.secondsToClock(120, true, true))
assert.is_equal("5d00:02",
datetime.secondsToClock(432110, true, true))
assert.is_equal("5d00:02",
datetime.secondsToClock(432120, true, true))
end)
end)
describe("secondsToHClock()", function()
it("should convert seconds to 0'00'' format", function()
it("should convert seconds to 0' format", function()
assert.is_equal("0'",
datetime.secondsToHClock(0, true))
assert.is_equal("0'",
@ -75,22 +93,38 @@ describe("datetime module", function()
assert.is_equal("10h01'",
datetime.secondsToHClock(36060, true))
end)
it("should round seconds to minutes in 0h00m format", function()
it("should round seconds to minutes in 0h0m (thinspace) format", function()
assert.is_equal("1m",
datetime.secondsToHClock(89, true, true))
assert.is_equal("2m",
datetime.secondsToHClock(90, true, true))
assert.is_equal("2m",
datetime.secondsToHClock(110, true, true))
assert.is_equal("1h00m",
assert.is_equal("1h\xE2\x80\x890m",
datetime.secondsToHClock(3600, true, true))
assert.is_equal("1h00m",
assert.is_equal("1h\xE2\x80\x890m",
datetime.secondsToHClock(3599, true, true))
assert.is_equal("59m",
datetime.secondsToHClock(3569, true, true))
assert.is_equal("10h01m",
assert.is_equal("10h\xE2\x80\x891m",
datetime.secondsToHClock(36060, true, true))
end)
it("should round seconds to minutes in 0h0m (hairspace) format", function()
assert.is_equal("1m",
datetime.secondsToHClock(89, true, true, false, true))
assert.is_equal("2m",
datetime.secondsToHClock(90, true, true, false, true))
assert.is_equal("2m",
datetime.secondsToHClock(110, true, true, false, true))
assert.is_equal("1h\xE2\x80\x8A0m",
datetime.secondsToHClock(3600, true, true, false, true))
assert.is_equal("1h\xE2\x80\x8A0m",
datetime.secondsToHClock(3599, true, true, false, true))
assert.is_equal("59m",
datetime.secondsToHClock(3569, true, true, false, true))
assert.is_equal("10h\xE2\x80\x8A1m",
datetime.secondsToHClock(36060, true, true, false, true))
end)
it("should convert seconds to 0h00'00'' format", function()
assert.is_equal("0\"",
datetime.secondsToHClock(0))
@ -111,7 +145,7 @@ describe("datetime module", function()
it("should change type based on format", function()
assert.is_equal("10h01'30\"",
datetime.secondsToClockDuration("modern", 36090, false))
assert.is_equal("10h01m30s",
assert.is_equal("10h\xE2\x80\x891m\xE2\x80\x8930s",
datetime.secondsToClockDuration("letters", 36090, false))
assert.is_equal("10:01:30",
datetime.secondsToClockDuration("classic", 36090, false))
@ -125,15 +159,29 @@ describe("datetime module", function()
datetime.secondsToClockDuration("modern", 36090, false))
assert.is_equal("10h02'",
datetime.secondsToClockDuration("modern", 36090, true))
assert.is_equal("10h01m30s",
assert.is_equal("10h\xE2\x80\x891m\xE2\x80\x8930s",
datetime.secondsToClockDuration("letters", 36090, false))
assert.is_equal("10h02m",
assert.is_equal("10h\xE2\x80\x892m",
datetime.secondsToClockDuration("letters", 36090, true))
assert.is_equal("10:01:30",
datetime.secondsToClockDuration("classic", 36090, false))
assert.is_equal("10:02",
datetime.secondsToClockDuration("classic", 36090, true))
end)
it("should pass along withDays", function()
assert.is_equal("58h01'30\"",
datetime.secondsToClockDuration("modern", 208890, false, false))
assert.is_equal("2d10h01'30\"",
datetime.secondsToClockDuration("modern", 208890, false, true))
assert.is_equal("58h\xE2\x80\x891m\xE2\x80\x8930s",
datetime.secondsToClockDuration("letters", 208890, false, false))
assert.is_equal("2d\xE2\x80\x8910h\xE2\x80\x891m\xE2\x80\x8930s",
datetime.secondsToClockDuration("letters", 208890, false, true))
assert.is_equal("58:01:30",
datetime.secondsToClockDuration("classic", 208890, false, false))
assert.is_equal("2d10:01:30",
datetime.secondsToClockDuration("classic", 208890, false, true))
end)
end)
describe("secondsToDate()", function()

Loading…
Cancel
Save