using System;
namespace Org.BouncyCastle.Utilities.Date
{
public static class DateTimeUtilities
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
public static readonly DateTime UnixEpoch = DateTime.UnixEpoch;
#else
public static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
#endif
public static readonly long MaxUnixMs =
(DateTime.MaxValue.Ticks - UnixEpoch.Ticks) / TimeSpan.TicksPerMillisecond;
public static readonly long MinUnixMs = 0L;
///
/// Return the number of milliseconds since the Unix epoch (1 Jan., 1970 UTC) for a given DateTime value.
///
/// The DateTime value will be converted to UTC (using before
/// conversion.
/// A DateTime value not before the epoch.
/// Number of whole milliseconds after epoch.
/// 'dateTime' is before the epoch.
public static long DateTimeToUnixMs(DateTime dateTime)
{
DateTime utc = dateTime.ToUniversalTime();
if (utc.CompareTo(UnixEpoch) < 0)
throw new ArgumentOutOfRangeException(nameof(dateTime), "DateTime value may not be before the epoch");
return (utc.Ticks - UnixEpoch.Ticks) / TimeSpan.TicksPerMillisecond;
}
///
/// Create a UTC DateTime value from the number of milliseconds since the Unix epoch (1 Jan., 1970 UTC).
///
/// Number of milliseconds since the epoch.
/// A UTC DateTime value
/// 'unixMs' is before 'MinUnixMs' or after 'MaxUnixMs'.
///
public static DateTime UnixMsToDateTime(long unixMs)
{
if (unixMs < MinUnixMs || unixMs > MaxUnixMs)
throw new ArgumentOutOfRangeException(nameof(unixMs));
return new DateTime(unixMs * TimeSpan.TicksPerMillisecond + UnixEpoch.Ticks, DateTimeKind.Utc);
}
///
/// Return the current number of milliseconds since the Unix epoch (1 Jan., 1970 UTC).
///
public static long CurrentUnixMs()
{
return DateTimeToUnixMs(DateTime.UtcNow);
}
public static DateTime WithPrecisionCentisecond(DateTime dateTime)
{
long ticks = dateTime.Ticks - dateTime.Ticks % (TimeSpan.TicksPerMillisecond * 10L);
return new DateTime(ticks, dateTime.Kind);
}
public static DateTime WithPrecisionDecisecond(DateTime dateTime)
{
long ticks = dateTime.Ticks - dateTime.Ticks % (TimeSpan.TicksPerMillisecond * 100L);
return new DateTime(ticks, dateTime.Kind);
}
public static DateTime WithPrecisionMillisecond(DateTime dateTime)
{
long ticks = dateTime.Ticks - dateTime.Ticks % TimeSpan.TicksPerMillisecond;
return new DateTime(ticks, dateTime.Kind);
}
public static DateTime WithPrecisionSecond(DateTime dateTime)
{
long ticks = dateTime.Ticks - dateTime.Ticks % TimeSpan.TicksPerSecond;
return new DateTime(ticks, dateTime.Kind);
}
}
}