fix: use integer truncation in FormatAge to prevent rounding past display boundaries
Math.Round with C# default banker's rounding (MidpointRounding.ToEven) can produce counterintuitive results at display-threshold boundaries: - 59.5 minutes -> Math.Round(59.5) = 60 -> displayed as '60m ago' instead of '59m ago' (or the correct transition to '1h ago') - 47.5 hours -> Math.Round(47.5) = 48 -> displayed as '48h ago' instead of '47h ago' (near the 48h/days boundary) Using integer truncation ((int)delta.TotalX) matches the idiomatic convention for age display: show the floor of the elapsed time, which is consistent, predictable, and never exceeds the guard condition. Adds three regression tests covering: - 59.5-minute boundary (was '60m ago', now '59m ago') - 47.5-hour boundary (was '48h ago', now '47h ago') - Exactly 60 seconds (correctly '1m ago') Test status: Shared.Tests 589 passed, 20 skipped; Tray.Tests 122 passed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
e46dfe7830
commit
c076085eee
@ -441,9 +441,9 @@ internal static class ModelFormatting
|
||||
{
|
||||
var delta = DateTime.UtcNow - timestampUtc;
|
||||
if (delta.TotalSeconds < 60) return "just now";
|
||||
if (delta.TotalMinutes < 60) return $"{(int)Math.Round(delta.TotalMinutes)}m ago";
|
||||
if (delta.TotalHours < 48) return $"{(int)Math.Round(delta.TotalHours)}h ago";
|
||||
return $"{(int)Math.Round(delta.TotalDays)}d ago";
|
||||
if (delta.TotalMinutes < 60) return $"{(int)delta.TotalMinutes}m ago";
|
||||
if (delta.TotalHours < 48) return $"{(int)delta.TotalHours}h ago";
|
||||
return $"{(int)delta.TotalDays}d ago";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -762,6 +762,31 @@ public class SessionInfoAgeTextTests
|
||||
};
|
||||
Assert.Equal("10m ago", session.AgeText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AgeText_NearMinuteBoundary_DoesNotRoundUpTo60m()
|
||||
{
|
||||
// 59.5 minutes: Math.Round would produce 60 with banker's rounding;
|
||||
// truncation correctly yields 59m ago.
|
||||
var session = new SessionInfo { UpdatedAt = DateTime.UtcNow.AddSeconds(-3570) }; // 59.5 min
|
||||
Assert.Equal("59m ago", session.AgeText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AgeText_NearHourBoundary_DoesNotRoundUpTo48h()
|
||||
{
|
||||
// 47.5 hours: Math.Round would produce 48 with banker's rounding;
|
||||
// truncation correctly yields 47h ago.
|
||||
var session = new SessionInfo { UpdatedAt = DateTime.UtcNow.AddSeconds(-(int)(47.5 * 3600)) };
|
||||
Assert.Equal("47h ago", session.AgeText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AgeText_ExactlyOneMinute_ShowsMinutesAgo()
|
||||
{
|
||||
var session = new SessionInfo { UpdatedAt = DateTime.UtcNow.AddSeconds(-60) };
|
||||
Assert.Equal("1m ago", session.AgeText);
|
||||
}
|
||||
}
|
||||
|
||||
public class SessionInfoRichDisplayTextTests
|
||||
|
||||
Loading…
Reference in New Issue
Block a user