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); } } }