Skip to content

Instantly share code, notes, and snippets.

@bjcull
Created November 27, 2017 09:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save bjcull/670fb744c5770dd10639b2f75367ecf0 to your computer and use it in GitHub Desktop.
Save bjcull/670fb744c5770dd10639b2f75367ecf0 to your computer and use it in GitHub Desktop.
The current time service I use to keep track of dates relative to a certain timezone.
public class TimeService : ITimeService
{
private readonly ILogger _logger;
private Instant? _frozenTime;
private Instant _realTimeAtTimeOfFreezing = Instant.MinValue;
private readonly IDateTimeZoneProvider _timeZoneProvider = DateTimeZoneProviders.Tzdb;
private readonly DateTimeZone _timeZone;
public TimeService(ILogger logger, string systemTimeZone, DateTime? setDate = null)
{
_logger = logger;
_timeZone = _timeZoneProvider[systemTimeZone];
if (setDate.HasValue)
{
if (setDate.Value.Kind != DateTimeKind.Utc)
{
throw new ArgumentException("Supplied DateTime must have a Kind of UTC.", nameof(setDate));
}
_frozenTime = Instant.FromDateTimeUtc(setDate.Value);
_logger.Warning("Time has been frozen to {currentTime}", _frozenTime.Value);
}
}
public void SetDateUtc(Instant date)
{
_frozenTime = date;
_realTimeAtTimeOfFreezing = Instant.FromDateTimeUtc(DateTime.UtcNow);
_logger.Warning("Time has been frozen to {currentTime}", _frozenTime.Value);
}
public Instant UtcNow
{
get
{
if (_frozenTime.HasValue)
{
return GetSlidingFrozenTime();
}
return Instant.FromDateTimeUtc(DateTime.UtcNow);
}
}
public ZonedDateTime LocalNow
{
get
{
if (_frozenTime.HasValue)
{
return GetSlidingFrozenTime().InZone(_timeZone);
}
return Instant.FromDateTimeUtc(DateTime.UtcNow).InZone(_timeZone);
}
}
public DateTime UtcNowDT => UtcNow.ToDateTimeUtc();
public DateTime LocalNowDT => LocalNow.ToDateTimeUnspecified();
public DateTime LocalTodayDT => LocalNow.Date.ToDateTimeUnspecified();
public ZonedDateTime ParseAsSystemTimeZone(DateTime date)
{
return _timeZone.AtLeniently(LocalDateTime.FromDateTime(date));
}
public ZonedDateTime AtTime(ZonedDateTime date, LocalTime time)
{
return _timeZone.AtLeniently(date.Date.At(time));
}
public ZonedDateTime InTimezone(LocalDateTime date)
{
return _timeZone.AtLeniently(date);
}
public ZonedDateTime InTimezone(Instant instant)
{
return instant.InZone(_timeZone);
}
public bool IsTimeFrozen => _frozenTime.HasValue;
private Instant GetSlidingFrozenTime()
{
if (!_frozenTime.HasValue)
{
return Instant.MinValue;
}
return _frozenTime.Value.Plus(Instant.FromDateTimeUtc(DateTime.UtcNow) - _realTimeAtTimeOfFreezing);
}
public Instant ParseAsUtc(DateTime date)
{
return Instant.FromDateTimeUtc(date);
}
public ZonedDateTime ParseAsUtcIntoTimezone(DateTime date)
{
return ParseAsUtc(date).InZone(_timeZone);
}
public ZonedDateTime ParseDate(DateTime date)
{
// Logic:
// -> If Kind.Local > ConvertToUtc > ConvertToSystemTimezone
// -> If Kind.Utc > ConvertToSystemTimezone
// -> If Kind.Unspecified (and else) > ParseAsSystemTimezone (sydney)
if (date.Kind == DateTimeKind.Local)
{
return ParseAsUtcIntoTimezone(date.ToUniversalTime());
}
if (date.Kind == DateTimeKind.Utc)
{
return ParseAsUtcIntoTimezone(date);
}
return ParseAsSystemTimeZone(date);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment