diff --git a/PluralKit.Bot/Commands/SwitchCommands.cs b/PluralKit.Bot/Commands/SwitchCommands.cs index fcdb2126..d313263a 100644 --- a/PluralKit.Bot/Commands/SwitchCommands.cs +++ b/PluralKit.Bot/Commands/SwitchCommands.cs @@ -79,10 +79,10 @@ namespace PluralKit.Bot.Commands // But, we do a prompt to confirm. var lastSwitchMembers = await Switches.GetSwitchMembers(lastTwoSwitches[0]); var lastSwitchMemberStr = string.Join(", ", lastSwitchMembers.Select(m => m.Name)); - var lastSwitchTimeStr = lastTwoSwitches[0].Timestamp.ToString(Formats.DateTimeFormat, null); - var lastSwitchDeltaStr = SystemClock.Instance.GetCurrentInstant().Minus(lastTwoSwitches[0].Timestamp).ToString(Formats.DurationFormat, null); - var newSwitchTimeStr = time.ToString(Formats.DateTimeFormat, null); - var newSwitchDeltaStr = SystemClock.Instance.GetCurrentInstant().Minus(time.ToInstant()).ToString(Formats.DurationFormat, null); + var lastSwitchTimeStr = Formats.ZonedDateTimeFormat.Format(lastTwoSwitches[0].Timestamp.InZone(Context.SenderSystem.Zone)); + var lastSwitchDeltaStr = Formats.DurationFormat.Format(SystemClock.Instance.GetCurrentInstant() - lastTwoSwitches[0].Timestamp); + var newSwitchTimeStr = Formats.ZonedDateTimeFormat.Format(time); + var newSwitchDeltaStr = Formats.DurationFormat.Format(SystemClock.Instance.GetCurrentInstant() - time.ToInstant()); // yeet var msg = await Context.Channel.SendMessageAsync($"{Emojis.Warn} This will move the latest switch ({lastSwitchMemberStr}) from {lastSwitchTimeStr} ({lastSwitchDeltaStr} ago) to {newSwitchTimeStr} ({newSwitchDeltaStr} ago). Is this OK?"); @@ -104,7 +104,7 @@ namespace PluralKit.Bot.Commands var lastSwitchMembers = await Switches.GetSwitchMembers(lastTwoSwitches[0]); var lastSwitchMemberStr = string.Join(", ", lastSwitchMembers.Select(m => m.Name)); - var lastSwitchDeltaStr = SystemClock.Instance.GetCurrentInstant().Minus(lastTwoSwitches[0].Timestamp).ToString(Formats.DurationFormat, null); + var lastSwitchDeltaStr = Formats.DurationFormat.Format(SystemClock.Instance.GetCurrentInstant() - lastTwoSwitches[0].Timestamp); IUserMessage msg; if (lastTwoSwitches.Length == 1) @@ -116,7 +116,7 @@ namespace PluralKit.Bot.Commands { var secondSwitchMembers = await Switches.GetSwitchMembers(lastTwoSwitches[1]); var secondSwitchMemberStr = string.Join(", ", secondSwitchMembers.Select(m => m.Name)); - var secondSwitchDeltaStr = SystemClock.Instance.GetCurrentInstant().Minus(lastTwoSwitches[1].Timestamp).ToString(Formats.DurationFormat, null); + var secondSwitchDeltaStr = Formats.DurationFormat.Format(SystemClock.Instance.GetCurrentInstant() - lastTwoSwitches[1].Timestamp); msg = await Context.Channel.SendMessageAsync( $"{Emojis.Warn} This will delete the latest switch ({lastSwitchMemberStr}, {lastSwitchDeltaStr} ago). The next latest switch is {secondSwitchMemberStr} ({secondSwitchDeltaStr} ago). Is this okay?"); } diff --git a/PluralKit.Bot/Commands/SystemCommands.cs b/PluralKit.Bot/Commands/SystemCommands.cs index 2de9d0b3..6678034c 100644 --- a/PluralKit.Bot/Commands/SystemCommands.cs +++ b/PluralKit.Bot/Commands/SystemCommands.cs @@ -158,7 +158,7 @@ namespace PluralKit.Bot.Commands if (sw == null) throw Errors.NoRegisteredSwitches; var members = await Switches.GetSwitchMembers(sw); - await Context.Channel.SendMessageAsync(embed: EmbedService.CreateFronterEmbed(sw, members.ToList())); + await Context.Channel.SendMessageAsync(embed: EmbedService.CreateFronterEmbed(sw, members.ToList(), system.Zone)); } [Command("timezone")] @@ -179,7 +179,7 @@ namespace PluralKit.Bot.Commands var currentTime = SystemClock.Instance.GetCurrentInstant().InZone(zone); var msg = await Context.Channel.SendMessageAsync( - $"This will change the system time zone to {zone.Id}. The current time is {currentTime.ToString(Formats.DateTimeFormat, null)}. Is this correct?"); + $"This will change the system time zone to {zone.Id}. The current time is {Formats.ZonedDateTimeFormat.Format(currentTime)}. Is this correct?"); if (!await Context.PromptYesNo(msg)) throw Errors.TimezoneChangeCancelled; Context.SenderSystem.UiTz = zone.Id; await Systems.Save(Context.SenderSystem); diff --git a/PluralKit.Bot/Errors.cs b/PluralKit.Bot/Errors.cs index edff5176..46c737bb 100644 --- a/PluralKit.Bot/Errors.cs +++ b/PluralKit.Bot/Errors.cs @@ -53,7 +53,7 @@ namespace PluralKit.Bot { public static PKError SwitchTimeInFuture => new PKError("Can't move switch to a time in the future."); public static PKError NoRegisteredSwitches => new PKError("There are no registered switches for this system."); - public static PKError SwitchMoveBeforeSecondLast(ZonedDateTime time) => new PKError($"Can't move switch to before last switch time ({time.ToString(Formats.DateTimeFormat, null)}), as it would cause conflicts."); + public static PKError SwitchMoveBeforeSecondLast(ZonedDateTime time) => new PKError($"Can't move switch to before last switch time ({Formats.ZonedDateTimeFormat.Format(time)}), as it would cause conflicts."); public static PKError SwitchMoveCancelled => new PKError("Switch move cancelled."); public static PKError SwitchDeleteCancelled => new PKError("Switch deletion cancelled."); public static PKError TimezoneParseError(string timezone) => new PKError($"Could not parse timezone offset {timezone}. Offset must be a value like 'UTC+5' or 'GMT-4:30'."); diff --git a/PluralKit.Bot/Services/EmbedService.cs b/PluralKit.Bot/Services/EmbedService.cs index edbf0fad..941e7a20 100644 --- a/PluralKit.Bot/Services/EmbedService.cs +++ b/PluralKit.Bot/Services/EmbedService.cs @@ -71,13 +71,13 @@ namespace PluralKit.Bot { return eb.Build(); } - public Embed CreateFronterEmbed(PKSwitch sw, ICollection members) + public Embed CreateFronterEmbed(PKSwitch sw, ICollection members, DateTimeZone zone) { var timeSinceSwitch = SystemClock.Instance.GetCurrentInstant() - sw.Timestamp; return new EmbedBuilder() .WithColor(members.FirstOrDefault()?.Color?.ToDiscordColor() ?? Color.Blue) .AddField("Current fronter", members.Count > 0 ? string.Join(", ", members.Select(m => m.Name)) : "*(no fronter)*", true) - .AddField("Since", $"{sw.Timestamp.ToString(Formats.DateTimeFormat, null)} ({timeSinceSwitch.ToString(Formats.DurationFormat, null)} ago)", true) + .AddField("Since", $"{Formats.ZonedDateTimeFormat.Format(sw.Timestamp.InZone(zone))} ({Formats.DurationFormat.Format(timeSinceSwitch)} ago)", true) .Build(); } } diff --git a/PluralKit.Core/DataFiles.cs b/PluralKit.Core/DataFiles.cs index 5bcdaf3a..1b314c6b 100644 --- a/PluralKit.Core/DataFiles.cs +++ b/PluralKit.Core/DataFiles.cs @@ -38,7 +38,7 @@ namespace PluralKit.Bot TimeZone = system.UiTz, Members = members, Switches = switches, - Created = system.Created.ToString(Formats.TimestampExportFormat, null), + Created = Formats.TimestampExportFormat.Format(system.Created), LinkedAccounts = (await _systems.GetLinkedAccountIds(system)).ToList() }; } @@ -48,20 +48,20 @@ namespace PluralKit.Bot Id = member.Hid, Name = member.Name, Description = member.Description, - Birthday = member.Birthday?.ToString(Formats.DateExportFormat, null), + Birthday = member.Birthday != null ? Formats.DateExportFormat.Format(member.Birthday.Value) : null, Pronouns = member.Pronouns, Color = member.Color, AvatarUrl = member.AvatarUrl, Prefix = member.Prefix, Suffix = member.Suffix, - Created = member.Created.ToString(Formats.TimestampExportFormat, null), + Created = Formats.TimestampExportFormat.Format(member.Created), MessageCount = await _members.MessageCount(member) }; private async Task ExportSwitch(PKSwitch sw) => new DataFileSwitch { Members = (await _switches.GetSwitchMembers(sw)).Select(m => m.Hid).ToList(), - Timestamp = sw.Timestamp.ToString(Formats.TimestampExportFormat, null) + Timestamp = Formats.TimestampExportFormat.Format(sw.Timestamp) }; public async Task ImportSystem(DataFileSystem data, PKSystem system) @@ -120,8 +120,7 @@ namespace PluralKit.Bot if (dataMember.Birthday != null) { - var birthdayParse = LocalDatePattern.CreateWithInvariantCulture(Formats.DateExportFormat) - .Parse(dataMember.Birthday); + var birthdayParse = Formats.DateExportFormat.Parse(dataMember.Birthday); member.Birthday = birthdayParse.Success ? (LocalDate?) birthdayParse.Value : null; } diff --git a/PluralKit.Core/Models.cs b/PluralKit.Core/Models.cs index e4989b6f..b947d1ce 100644 --- a/PluralKit.Core/Models.cs +++ b/PluralKit.Core/Models.cs @@ -18,6 +18,8 @@ namespace PluralKit public string UiTz { get; set; } public int MaxMemberNameLength => Tag != null ? 32 - Tag.Length - 1 : 32; + + public DateTimeZone Zone => DateTimeZoneProviders.Tzdb.GetZoneOrNull(UiTz); } public class PKMember diff --git a/PluralKit.Core/Utils.cs b/PluralKit.Core/Utils.cs index 35c75b0d..3298a49f 100644 --- a/PluralKit.Core/Utils.cs +++ b/PluralKit.Core/Utils.cs @@ -223,9 +223,11 @@ namespace PluralKit public static class Formats { - public static string DateTimeFormat = "yyyy-MM-dd HH:mm:ss"; - public static string DateExportFormat = "yyyy-MM-dd"; - public static string TimestampExportFormat = "g"; - public static string DurationFormat = "D'd' h'h' m'm' s's'"; + public static InstantPattern InstantDateTimeFormat = InstantPattern.CreateWithInvariantCulture("yyyy-MM-dd HH:mm:ss"); + public static InstantPattern TimestampExportFormat = InstantPattern.CreateWithInvariantCulture("g"); + public static LocalDatePattern DateExportFormat = LocalDatePattern.CreateWithInvariantCulture("yyyy-MM-dd"); + public static DurationPattern DurationFormat = DurationPattern.CreateWithInvariantCulture("D'd' h'h' m'm' s's'"); + public static LocalDateTimePattern LocalDateTimeFormat = LocalDateTimePattern.CreateWithInvariantCulture("yyyy-MM-dd HH:mm:ss"); + public static ZonedDateTimePattern ZonedDateTimeFormat = ZonedDateTimePattern.CreateWithInvariantCulture("yyyy-MM-dd HH:mm:ss x", DateTimeZoneProviders.Tzdb); } } \ No newline at end of file