Show times in a configurable time zone
SRG sends times with an offset (e.g. 13:55+02:00). They are stored as DateTime, which deserialisation converts to server-local time, and two places then wrote that straight into text: the "[dd.MM HH:mm]" prefix on upcoming livestream names and the timestamp in recording file names (DateTime.Now). On a server running in UTC both were two hours behind Swiss time, e.g. a qualifying starting at 13:55 was listed as 11:55. A new "Display Time Zone" setting (IANA id, e.g. Europe/Zurich) now decides the zone for both; empty keeps the server's zone, and an unknown id falls back to it rather than breaking the listing. Utilities/DisplayTime does the conversion. Also fixes PremiereDate on upcoming livestreams, which was set to that server-local value although Jellyfin expects UTC. It was only correct on UTC servers; it is now converted, like the other channel items. Verified on simulated UTC and Europe/Paris servers: the same instant gives 11:55 / 13:55 / 07:55 for server zone / Europe/Zurich / America/New_York, and PremiereDate is 11:55 UTC on both. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
|
||||
namespace Jellyfin.Plugin.SRFPlay.Utilities;
|
||||
|
||||
/// <summary>
|
||||
/// Converts times into the time zone the plugin writes into text (item names, file names).
|
||||
/// SRG sends times with an offset, and DateTime deserialisation turns them into server-local
|
||||
/// values, so without this the text follows whatever zone the server happens to run in.
|
||||
/// </summary>
|
||||
public static class DisplayTime
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts a time to the configured display time zone (the server's if none is set).
|
||||
/// </summary>
|
||||
/// <param name="value">The time. Unspecified values are treated as server-local, like deserialised ones.</param>
|
||||
/// <returns>The same instant expressed in the display time zone.</returns>
|
||||
public static DateTime From(DateTime value)
|
||||
{
|
||||
return TimeZoneInfo.ConvertTimeFromUtc(value.ToUniversalTime(), GetZone());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current time in the display time zone.
|
||||
/// </summary>
|
||||
/// <returns>The current time in the display time zone.</returns>
|
||||
public static DateTime Now()
|
||||
{
|
||||
return TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, GetZone());
|
||||
}
|
||||
|
||||
private static TimeZoneInfo GetZone()
|
||||
{
|
||||
var id = Plugin.Instance?.Configuration.DisplayTimeZone;
|
||||
if (string.IsNullOrWhiteSpace(id))
|
||||
{
|
||||
return TimeZoneInfo.Local;
|
||||
}
|
||||
|
||||
// An unknown id falls back to the server's zone rather than breaking listings.
|
||||
return TimeZoneInfo.TryFindSystemTimeZoneById(id.Trim(), out var zone) ? zone : TimeZoneInfo.Local;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user