aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/weather.lua27
1 files changed, 18 insertions, 9 deletions
diff --git a/lib/weather.lua b/lib/weather.lua
index aea630e..d4b1460 100644
--- a/lib/weather.lua
+++ b/lib/weather.lua
@@ -76,22 +76,25 @@ function M.describe(code)
return DESCRIBE[code] or 'Unknown'
end
-local function round(v) return math.floor(v + 0.5) end
+-- Nearest integer, or nil when v is NaN, infinite or too big for an integer:
+-- %d and utf8.char raise on those, and a raise is a blank dashboard.
+local function round(v) return math.tointeger(math.floor(v + 0.5)) end
-- A temperature as the cards print it. Missing is '--', never '0': zero is a
--- legitimate reading. The '-0' a value just under zero would round to is
--- folded into '0'.
+-- legitimate reading.
function M.deg(v)
if type(v) ~= 'number' then return '--' end
local r = round(v)
- if r == 0 then r = 0 end
+ if not r then return '--' end
return string.format('%d\u{00B0}', r)
end
-- A rounded number with an optional suffix, or '--'.
function M.num(v, suffix)
if type(v) ~= 'number' then return '--' end
- return string.format('%d', round(v)) .. (suffix or '')
+ local r = round(v)
+ if not r then return '--' end
+ return string.format('%d', r) .. (suffix or '')
end
-- The fetcher asks Open-Meteo for km/h or mph to match UNITS.
@@ -101,8 +104,11 @@ end
-- Seconds as '10h 28m'.
function M.duration(s)
- if type(s) ~= 'number' or s < 0 then return '--' end
- return string.format('%dh %02dm', math.floor(s / 3600), math.floor(s % 3600 / 60))
+ -- ponytail: anything over 1e9 s (about 31 years) is bad data, not a duration.
+ if type(s) ~= 'number' or not (s >= 0 and s < 1e9) then return '--' end
+ local h, m = math.tointeger(math.floor(s / 3600)), math.tointeger(math.floor(s % 3600 / 60))
+ if not (h and m) then return '--' end
+ return string.format('%dh %02dm', h, m)
end
-- Threshold role names, which index the palette (colors.ok and so on).
@@ -136,7 +142,9 @@ end
-- One of the 28 Nerd Font moon glyphs, U+E38D (new) to U+E3A8, in phase order.
function M.moon_icon(phase)
if type(phase) ~= 'number' then return M.ICON.unknown end
- return utf8.char(0xE38D + round(phase * 28) % 28)
+ local r = round(phase * 28)
+ if not r then return M.ICON.unknown end
+ return utf8.char(0xE38D + r % 28)
end
-- Eight compass points. The half-step offset is what makes north straddle
@@ -160,7 +168,7 @@ function M.sun_t(now, sunrise, sunset)
local span = sunset - sunrise
if span <= 0 then return 0 end -- polar day/night or bad data: no division
local t = (now - sunrise) / span
- if t < 0 then return 0 elseif t > 1 then return 1 end
+ if not (t >= 0) then return 0 elseif t > 1 then return 1 end
return t
end
@@ -228,6 +236,7 @@ end
function M.age_str(dt, now)
if type(dt) ~= 'number' or type(now) ~= 'number' then return '?' end
local s = now - dt
+ if s ~= s then return '?' end
if s < 0 then s = 0 end
if s < 3600 then return math.floor(s / 60) .. 'm' end
if s < 86400 then return math.floor(s / 3600) .. 'h' end