diff --git a/examples/tests/human.nbt b/examples/tests/human.nbt index e3e91536..328397b5 100644 --- a/examples/tests/human.nbt +++ b/examples/tests/human.nbt @@ -10,11 +10,14 @@ assert_eq((60.1 seconds -> human), "1 minute + 0.1 seconds") assert_eq((1 minute -> human), "1 minute") assert_eq((1.25 minute -> human), "1 minute + 15 seconds") assert_eq((2.5 minute -> human), "2 minutes + 30 seconds") +assert_eq(((2 min + 59.99999 s )-> human), "3 minutes") assert_eq((1 hour -> human), "1 hour") assert_eq((1.5 hour -> human), "1 hour + 30 minutes") assert_eq((2 hour -> human), "2 hours") assert_eq((1 hour + 1 sec -> human), "1 hour + 1 second") +assert_eq((123 min -> human), "2 hours + 3 minutes") +assert_eq((1234 min -> human), "20 hours + 34 minutes") assert_eq((1 day -> human), "1 day") assert_eq((1.37 day -> human), "1 day + 8 hours + 52 minutes + 48 seconds") @@ -41,7 +44,7 @@ assert_eq((1 ms -> human), "0.001 seconds") assert_eq((1 µs -> human), "0.000001 seconds") assert_eq((1 ns -> human), "1.0e-9 seconds") assert_eq((1234 ns -> human), "0.000001234 seconds") -assert_eq((1s + 1234 ns -> human), "1 second") +assert_eq((1 s + 1234 ns -> human), "1 second") assert_eq((-1 second -> human), "1 second ago") assert_eq((-7.89 hour -> human), "7 hours + 53 minutes + 24 seconds ago") diff --git a/numbat/modules/core/mixed_units.nbt b/numbat/modules/core/mixed_units.nbt index 1f4a44a2..04c29a5d 100644 --- a/numbat/modules/core/mixed_units.nbt +++ b/numbat/modules/core/mixed_units.nbt @@ -15,7 +15,7 @@ fn _mixed_unit_list(val: D, units: List, acc: List) -> List = else _mixed_unit_list(val - unit_val, tail(units), cons_end(unit_val, acc)) where unit_val: D = if (len(units) > 0) - then (val |> trunc_in(head(units))) + then ((val -> head(units)) |> trunc_in(head(units))) else error("Units list cannot be empty") fn _negate(x: D) = -x diff --git a/numbat/modules/datetime/human.nbt b/numbat/modules/datetime/human.nbt index 3e4dcd2e..d78fb7a8 100644 --- a/numbat/modules/datetime/human.nbt +++ b/numbat/modules/datetime/human.nbt @@ -1,8 +1,11 @@ use core::functions +use core::lists use core::strings +use core::quantities use units::si use units::time use datetime::functions +use units::mixed fn _human_join(a: String, b: String) -> String = if a == "" then b else if b == "" then a else "{a} + {b}" @@ -24,36 +27,42 @@ fn _precise_human_months(time: Time) -> String = "{(time -> months) / month } fn _precise_human_days(time: Time) -> String = "{(time -> days) / day } days" -> _prettier fn _precise_human_seconds(time: Time) -> String = "{(time -> seconds) / second} seconds" -> _prettier -fn _human_recurse(t: Time, result: String, time_unit: String) -> String = - if time_unit == "day" - then _human_recurse((t -> day) - (t |> floor_in(day)), _human_join(result, t -> _human_days), "hour") - else if time_unit == "hour" - then _human_recurse((t -> hour) - (t |> floor_in(hour)), _human_join(result, t -> _human_hours), "minute") - else if time_unit == "minute" - then _human_recurse((t -> min) - (t |> floor_in(min)), _human_join(result, t -> _human_minutes), "second") - else _human_join(result, (t |> round_in(ms)) -> _precise_human_seconds) +fn _human_unit(time: Time) -> String = + if time_unit >= year then _human_years(time) + else if time_unit >= month then _human_months(time) + else if time_unit >= day then _human_days(time) + else if time_unit >= hour then _human_hours(time) + else if time_unit >= minute then _human_minutes(time) + else if time != 0 s then _precise_human_seconds(time |> round_in(ms)) + else "" + where time_unit = if (time == 0) then 0 s else unit_of(time) -fn _year_month_approx(t: Time) -> String = _human_join(the_years -> _human_years, t - the_years -> _human_months) - where the_years = t |> floor_in(year) +fn _round_mixed_in(base: D, value: List) -> List = + value |> sum |> round_in(base) |> _unit_list(units) + where units: List = value |> filter(is_nonzero) |> map(unit_of) -fn _human_manage_past(str: String, time: Time) = str_append(str, if time < 0 s then " ago" else "") +fn _human_time(base: Time, time_segments: List