DotNext by .NET Foundation and Contributors

<PackageReference Include="DotNext" Version="4.3.0" />

 Timestamp

Represents timestamp.
using DotNext.Threading; using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; namespace DotNext.Diagnostics { public readonly struct Timestamp : IEquatable<Timestamp>, IComparable<Timestamp> { private static readonly double TickFrequency = 10000000 / (double)Stopwatch.Frequency; private readonly long ticks; public bool IsEmpty => ticks == 0; public bool IsFuture => ticks > Stopwatch.GetTimestamp(); public bool IsPast => ticks < Stopwatch.GetTimestamp(); [Obsolete("Use public parameterless constructor instead")] public static Timestamp Current { get { return new Timestamp(Stopwatch.GetTimestamp()); } } public TimeSpan Value => new TimeSpan(ToTicks((double)ticks)); public TimeSpan Elapsed => new TimeSpan(ToTicks((double)Math.Max(0, Stopwatch.GetTimestamp() - ticks))); private Timestamp(long ticks) { this.ticks = Math.Max(ticks, 1); } public Timestamp() { this = new Timestamp(Stopwatch.GetTimestamp()); } private static long ToTicks(double duration) { return (long)(TickFrequency * duration); } private static long FromTimeSpan(TimeSpan value) { return (long)((double)value.Ticks / TickFrequency); } public static implicit operator TimeSpan(Timestamp stamp) { return stamp.Value; } public bool Equals(Timestamp other) { return ticks == other.ticks; } public int CompareTo(Timestamp other) { return ticks.CompareTo(other.ticks); } [System.Runtime.CompilerServices.NullableContext(2)] public override bool Equals([NotNullWhen(true)] object other) { if (other is Timestamp) { Timestamp other2 = (Timestamp)other; return Equals(other2); } return false; } public override int GetHashCode() { return ticks.GetHashCode(); } [System.Runtime.CompilerServices.NullableContext(1)] public override string ToString() { return Value.ToString(); } public static bool operator ==(Timestamp first, Timestamp second) { return first.ticks == second.ticks; } public static bool operator !=(Timestamp first, Timestamp second) { return first.ticks != second.ticks; } public static bool operator >(Timestamp first, Timestamp second) { return first.ticks > second.ticks; } public static bool operator <(Timestamp first, Timestamp second) { return first.ticks < second.ticks; } public static bool operator >=(Timestamp first, Timestamp second) { return first.ticks >= second.ticks; } public static bool operator <=(Timestamp first, Timestamp second) { return first.ticks <= second.ticks; } public static Timestamp operator +(Timestamp x, TimeSpan y) { long num = checked(x.ticks + FromTimeSpan(y)); if (num < 0) throw new OverflowException(); return new Timestamp(num); } public static Timestamp operator -(Timestamp x, TimeSpan y) { long num = checked(x.ticks - FromTimeSpan(y)); if (num < 0) throw new OverflowException(); return new Timestamp(num); } public static Timestamp VolatileRead(ref Timestamp location) { return new Timestamp(ref location.ticks.VolatileRead()); } public static void VolatileWrite(ref Timestamp location, Timestamp newValue) { ref Unsafe.AsRef(ref location.ticks).VolatileWrite(newValue.ticks); } public static void Refresh(ref Timestamp location) { ref Unsafe.AsRef(ref location.ticks).VolatileWrite(Math.Max(1, Stopwatch.GetTimestamp())); } } }