122 lines
3.7 KiB
C#
122 lines
3.7 KiB
C#
using System;
|
|
|
|
using NodaTime;
|
|
using NodaTime.Testing;
|
|
|
|
namespace Nitride.Temporal;
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the clock used to perform time calculations.
|
|
/// </summary>
|
|
public IClock Clock { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the date time zone used for processing.
|
|
/// </summary>
|
|
public DateTimeZone DateTimeZone { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets the instant when the files expire.
|
|
/// </summary>
|
|
public Instant? Expiration => this.Expires.HasValue
|
|
? this.Clock.GetCurrentInstant()
|
|
.Minus(Duration.FromTimeSpan(this.Expires.Value))
|
|
: null;
|
|
|
|
/// <summary>
|
|
/// Gets or sets the expiration time span, which is calculated from the
|
|
/// current time.
|
|
/// </summary>
|
|
public TimeSpan? Expires { get; set; }
|
|
|
|
/// <summary>
|
|
/// Creates an instant from a given year, month, and day.
|
|
/// </summary>
|
|
/// <param name="year">The numerical year.</param>
|
|
/// <param name="month">The numerical month.</param>
|
|
/// <param name="day">The numerical day of month.</param>
|
|
/// <returns>An instant in the clock's time zone.</returns>
|
|
public Instant CreateInstant(
|
|
int year,
|
|
int month,
|
|
int day)
|
|
{
|
|
var date = new LocalDate(year, month, day);
|
|
|
|
return this.CreateInstant(date);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates an instant from the given local date.
|
|
/// </summary>
|
|
/// <param name="date">The date to parse.</param>
|
|
/// <returns>An instant in the clock's time zone.</returns>
|
|
public Instant CreateInstant(LocalDate date)
|
|
{
|
|
ZonedDateTime zoned = date.AtStartOfDayInZone(this.DateTimeZone);
|
|
var instant = zoned.ToInstant();
|
|
|
|
return instant;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates an instant from the given date time zone.
|
|
/// </summary>
|
|
/// <param name="when">The object to convert.</param>
|
|
/// <returns>An instant representing this DateTimeOffset.</returns>
|
|
public Instant CreateInstant(DateTimeOffset when)
|
|
{
|
|
var offset = OffsetDateTime.FromDateTimeOffset(when);
|
|
|
|
return offset.ToInstant();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates an instant from the given date time.
|
|
/// </summary>
|
|
/// <param name="when">The object to convert.</param>
|
|
/// <returns>An instant representing this DateTimeOffset.</returns>
|
|
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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts an instant into a DateTime for the clock's time zone.
|
|
/// </summary>
|
|
/// <param name="instant">The instant to convert.</param>
|
|
/// <returns>A DateTime in the correct date and time.</returns>
|
|
public DateTime ToDateTime(Instant instant)
|
|
{
|
|
return instant.InZone(this.DateTimeZone)
|
|
.ToDateTimeOffset()
|
|
.DateTime;
|
|
}
|
|
}
|