Files
Elternbeirat/Elternbeirat.Web/Features/Events/EventDateFormat.cs
T

84 lines
3.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Elternbeirat.Contracts;
using Elternbeirat.Web.Shared;
namespace Elternbeirat.Web.Features.Events;
/// <summary>
/// Formats the date range of an <see cref="Event"/> for display in German.
/// </summary>
/// <remarks>
/// Shared by the full event list and the home-page events embed, so both render
/// dates the same way.
/// <para>
/// This is the event counterpart to
/// <see cref="Posts.PostDateFormat"/>, which formats a plain
/// <see cref="DateOnly"/> day instead of a point-in-time range.
/// </para>
/// </remarks>
public static class EventDateFormat
{
/// <summary>
/// Date format for the start, and for a single-day event.
/// </summary>
private const string LongDate = "dddd, d. MMMM yyyy";
/// <summary>
/// Date format for the end of a multi-day event; the weekday is omitted.
/// </summary>
private const string ShortDate = "d. MMMM yyyy";
/// <summary>
/// Formats the date range of an event.
/// </summary>
/// <param name="event">
/// The event to format.
/// </param>
/// <returns>
/// The formatted range, depending on <see cref="Event.End"/> and <see cref="Event.HasTime"/>:
/// <list type="bullet">
/// <item>
/// <description>No end: <c>Donnerstag, 8. Oktober 2026, 19:30 Uhr</c></description>
/// </item>
/// <item>
/// <description>Same day: <c>Donnerstag, 8. Oktober 2026, 19:30–21:00 Uhr</c></description>
/// </item>
/// <item>
/// <description>Several days: <c>Freitag, 9. Oktober 2026 – 11. Oktober 2026</c></description>
/// </item>
/// </list>
/// Without a time, the time parts are omitted.
/// </returns>
public static string Range(Event @event)
=> (@event.Start, @event.End, @event.HasTime) switch
{
(var start, null, var hasTime)
=> Stamp(start, LongDate, hasTime),
(var start, { } end, true) when end.Date == start.Date
=> $"{start.ToString(LongDate, Cultures.German)}, {start.ToString("HH:mm", Cultures.German)}–{end.ToString("HH:mm", Cultures.German)} Uhr",
(var start, { } end, false) when end.Date == start.Date
=> Stamp(start, LongDate, withTime: false),
(var start, { } end, var hasTime)
=> $"{Stamp(start, LongDate, hasTime)} – {Stamp(end, ShortDate, hasTime)}",
};
/// <summary>
/// Formats a single point in time as a date with an optional time.
/// </summary>
/// <param name="value">
/// The date and time to format.
/// </param>
/// <param name="dateFormat">
/// The date format, e.g. <see cref="LongDate"/>.
/// </param>
/// <param name="withTime">
/// <see langword="true"/> to append the time, e.g. <c>, 19:30 Uhr</c>.
/// </param>
/// <returns>
/// The formatted date, with the time if requested.
/// </returns>
private static string Stamp(DateTime value, string dateFormat, bool withTime)
=> withTime
? value.ToString(dateFormat + ", HH:mm", Cultures.German) + " Uhr"
: value.ToString(dateFormat, Cultures.German);
}