using System; using System.Globalization; using Theriapolis.Core.Persistence; namespace Theriapolis.GodotHost.Platform; /// /// Slot-picker label formatting. Pulls the in-game time from /// (e.g. "Howlwind — Y0 Spring D5 /// (Tier 1)") and appends the wall-clock saved-at time parsed from /// , rendered in the player's local /// timezone with a relative label when recent. /// /// Shared between (load picker /// from Title) and 's save picker /// so both surfaces present the same row format. /// public static class SaveSlotFormat { /// Composed row label: "{slot} — {in-game} · saved {when}". public static string FormatRow(string slotPrefix, SaveHeader header) => $"{slotPrefix} — {header.SlotLabel()} · saved {FormatSavedAt(header.SavedAtUtc)}"; /// Parses the SaveHeader's UTC saved-at timestamp and /// renders it relative to now, in local time. Returns "<unknown>" /// for empty / unparseable inputs so the row still shows something. public static string FormatSavedAt(string savedAtUtc) { if (string.IsNullOrWhiteSpace(savedAtUtc)) return ""; if (!DateTime.TryParse( savedAtUtc, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal, out var utc)) return savedAtUtc; DateTime local = utc.ToLocalTime(); DateTime now = DateTime.Now; if (local.Date == now.Date) return $"today, {local:HH:mm}"; if (local.Date == now.Date.AddDays(-1)) return $"yesterday, {local:HH:mm}"; if (local.Year == now.Year) return local.ToString("MMM d, HH:mm", CultureInfo.InvariantCulture); return local.ToString("yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture); } }