fed3a09695
* New Marathon.Domain.ValueObjects.MoscowTime with Offset, Now, and EndOfMoscowDay(DateOnly) — replaces ~15 inline TimeSpan.FromHours(3) literals across Domain/Application/Infrastructure/UI. * New Marathon.UI.Services.SportLabels.Resolve(IStringLocalizer, int) — replaces 6 near-identical SportLabel switch bodies in EventListShell, Events/Detail, Anomalies/AnomalyFeed, Results/ResultsList, Results/ResultsLoader, and AnomalyCard. Single source of truth for the 6/11/22723/43658 sport-code mapping. Pages keep a one-liner wrapper so the call sites stay terse.
33 lines
1.3 KiB
C#
33 lines
1.3 KiB
C#
namespace Marathon.Domain.ValueObjects;
|
|
|
|
/// <summary>
|
|
/// Single source of truth for the Moscow timezone offset.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// <para>
|
|
/// marathonbet.by serves all timestamps in Moscow time (UTC+3) and the domain
|
|
/// invariant on <see cref="Marathon.Domain.Entities.Event.ScheduledAt"/>
|
|
/// rejects any other offset. Code that constructs <see cref="DateTimeOffset"/>
|
|
/// values for events, results, snapshots, or test fixtures MUST use this
|
|
/// constant rather than re-deriving <c>TimeSpan.FromHours(3)</c>.
|
|
/// </para>
|
|
/// </remarks>
|
|
public static class MoscowTime
|
|
{
|
|
/// <summary>The Moscow time offset (UTC+3).</summary>
|
|
public static readonly TimeSpan Offset = TimeSpan.FromHours(3);
|
|
|
|
/// <summary>Current Moscow time.</summary>
|
|
public static DateTimeOffset Now => DateTimeOffset.UtcNow.ToOffset(Offset);
|
|
|
|
/// <summary>
|
|
/// Returns the inclusive end-of-day for the given Moscow date — i.e.,
|
|
/// the moment one second before the next day starts. Used by date-range
|
|
/// filters where the user picks "to: 2026-05-09" meaning "through the
|
|
/// rest of that day."
|
|
/// </summary>
|
|
public static DateTimeOffset EndOfMoscowDay(DateOnly date) =>
|
|
new DateTimeOffset(date.ToDateTime(TimeOnly.MinValue), Offset)
|
|
.AddDays(1).AddSeconds(-1);
|
|
}
|