using System; using NodaTime; using NodaTime.Testing; namespace MfGames.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 TimeService { public TimeService() { // 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; } }