using System;
using NodaTime;
using NodaTime.Testing;
namespace Nitride.Temporal;
///
/// A class that handles date and time processing. This provides identifying
/// the desire time zone along with various methods for processing parsed
/// DateTime objects into NodaTime.Instant.
///
public class Timekeeper
{
public Timekeeper()
{
// We use FakeClock because we don't want time to advance in the
// middle of running, just in case we are just a few seconds before
// rollover.
Instant instant = SystemClock.Instance.GetCurrentInstant();
this.DateTimeZone = DateTimeZoneProviders.Bcl.GetSystemDefault();
this.Clock = new FakeClock(instant);
}
///
/// Gets or sets the clock used to perform time calculations.
///
public IClock Clock { get; set; }
///
/// Gets or sets the date time zone used for processing.
///
public DateTimeZone DateTimeZone { get; set; }
///
/// Gets the instant when the files expire.
///
public Instant? Expiration => this.Expires.HasValue
? this.Clock.GetCurrentInstant().Minus(Duration.FromTimeSpan(this.Expires.Value))
: null;
///
/// Gets or sets the expiration time span, which is calculated from the
/// current time.
///
public TimeSpan? Expires { get; set; }
///
/// Creates an instant from a given year, month, and day.
///
/// The numerical year.
/// The numerical month.
/// The numerical day of month.
/// An instant in the clock's time zone.
public Instant CreateInstant(int year, int month, int day)
{
var date = new LocalDate(year, month, day);
return this.CreateInstant(date);
}
///
/// Creates an instant from the given local date.
///
/// The date to parse.
/// An instant in the clock's time zone.
public Instant CreateInstant(LocalDate date)
{
ZonedDateTime zoned = date.AtStartOfDayInZone(this.DateTimeZone);
var instant = zoned.ToInstant();
return instant;
}
///
/// Creates an instant from the given date time zone.
///
/// The object to convert.
/// An instant representing this DateTimeOffset.
public Instant CreateInstant(DateTimeOffset when)
{
var offset = OffsetDateTime.FromDateTimeOffset(when);
return offset.ToInstant();
}
///
/// Creates an instant from the given date time.
///
/// The object to convert.
/// An instant representing this DateTimeOffset.
public Instant CreateInstant(DateTime when)
{
if (when.Kind == DateTimeKind.Unspecified)
{
var localDate = LocalDate.FromDateTime(when);
return this.CreateInstant(localDate);
}
var offset = new DateTimeOffset(when);
return this.CreateInstant(offset);
}
///
/// Converts an instant into a DateTime for the clock's time zone.
///
/// The instant to convert.
/// A DateTime in the correct date and time.
public DateTime ToDateTime(Instant instant)
{
return instant.InZone(this.DateTimeZone).ToDateTimeOffset().DateTime;
}
}