Added additional voice work update logic.
This commit is contained in:
6
JSMR.Infrastructure/Common/Time/Clock.cs
Normal file
6
JSMR.Infrastructure/Common/Time/Clock.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace JSMR.Infrastructure.Common.Time;
|
||||
|
||||
public class Clock : IClock
|
||||
{
|
||||
public DateTimeOffset UtcNow => DateTimeOffset.UtcNow;
|
||||
}
|
||||
6
JSMR.Infrastructure/Common/Time/IClock.cs
Normal file
6
JSMR.Infrastructure/Common/Time/IClock.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace JSMR.Infrastructure.Common.Time;
|
||||
|
||||
public interface IClock
|
||||
{
|
||||
DateTimeOffset UtcNow { get; }
|
||||
}
|
||||
69
JSMR.Infrastructure/Common/Time/TimeProvider.cs
Normal file
69
JSMR.Infrastructure/Common/Time/TimeProvider.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
namespace JSMR.Infrastructure.Common.Time;
|
||||
|
||||
public interface ITimeProvider
|
||||
{
|
||||
DateTimeOffset Now();
|
||||
DateTimeOffset Local(int year, int month, int day, int hour);
|
||||
DateTimeOffset Local(DateTimeOffset offset);
|
||||
}
|
||||
|
||||
public abstract class TimeProvider : ITimeProvider
|
||||
{
|
||||
protected abstract string Id { get; }
|
||||
protected abstract string[] TimeZoneIds { get; }
|
||||
|
||||
private readonly IClock _clock;
|
||||
private readonly TimeZoneInfo _timeZone;
|
||||
|
||||
public TimeProvider(IClock clock)
|
||||
{
|
||||
_clock = clock;
|
||||
_timeZone = ResolveTimeZone();
|
||||
}
|
||||
|
||||
private TimeZoneInfo ResolveTimeZone()
|
||||
{
|
||||
foreach (string timeZoneId in TimeZoneIds)
|
||||
{
|
||||
if (TimeZoneInfo.TryFindSystemTimeZoneById(timeZoneId, out TimeZoneInfo? timeZoneInfo))
|
||||
return timeZoneInfo;
|
||||
}
|
||||
|
||||
throw new TimeZoneNotFoundException($"Unable to resolve time zone for: {Id} ({string.Join(" / ", TimeZoneIds)})");
|
||||
}
|
||||
|
||||
public DateTimeOffset Now() => TimeZoneInfo.ConvertTime(_clock.UtcNow, _timeZone);
|
||||
public DateTimeOffset Local(DateTimeOffset offset) => TimeZoneInfo.ConvertTime(offset, _timeZone);
|
||||
|
||||
public DateTimeOffset Local(int year, int month, int day, int hour)
|
||||
{
|
||||
DateTime local = new(year, month, day, hour, 0, 0, DateTimeKind.Unspecified);
|
||||
TimeSpan offset = _timeZone.GetUtcOffset(local);
|
||||
|
||||
return new DateTimeOffset(local, offset);
|
||||
}
|
||||
|
||||
public DateTimeOffset CurrentScanAnchor()
|
||||
{
|
||||
DateTimeOffset now = Now();
|
||||
DateTimeOffset midnight = Local(now.Year, now.Month, now.Day, 0);
|
||||
DateTimeOffset fourPm = Local(now.Year, now.Month, now.Day, 16);
|
||||
|
||||
return now >= fourPm ? fourPm : midnight;
|
||||
}
|
||||
|
||||
public DateTimeOffset PreviousScanAnchor(DateTimeOffset scanAnchorTokyo)
|
||||
{
|
||||
// Normalize to Tokyo (no-op if already)
|
||||
var a = TimeZoneInfo.ConvertTime(scanAnchorTokyo, _timeZone);
|
||||
return a.Hour == 16
|
||||
? Local(a.Year, a.Month, a.Day, 0)
|
||||
: Local(a.AddDays(-1).Year, a.AddDays(-1).Month, a.AddDays(-1).Day, 16);
|
||||
}
|
||||
}
|
||||
|
||||
public class TokyoTimeProvider(IClock clock) : TimeProvider(clock)
|
||||
{
|
||||
protected override string Id => "Tokyo Standard Time";
|
||||
protected override string[] TimeZoneIds => ["Tokyo Standard Time", "Asia/Tokyo"];
|
||||
}
|
||||
Reference in New Issue
Block a user