implement IComparable and comparison operators on Timestamp (#4318)
This commit is contained in:
parent
5524c53e60
commit
96833b8f4b
@ -111,5 +111,106 @@ namespace Google.Protobuf.WellKnownTypes
|
||||
var duration = new Timestamp { Seconds = 1, Nanos = -1 };
|
||||
Assert.AreEqual("{ \"@warning\": \"Invalid Timestamp\", \"seconds\": \"1\", \"nanos\": -1 }", duration.ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Comparability()
|
||||
{
|
||||
Timestamp
|
||||
a = null,
|
||||
b = new Timestamp { Seconds = 1, Nanos = 1 },
|
||||
c = new Timestamp { Seconds = 1, Nanos = 10 },
|
||||
d = new Timestamp { Seconds = 10, Nanos = 1 },
|
||||
e = new Timestamp { Seconds = 10, Nanos = 10 };
|
||||
|
||||
Assert.IsTrue(b.CompareTo(a) > 0); // null is always first (according to default behavior of Array.Sort)
|
||||
Assert.IsTrue(b.CompareTo(b) == 0);
|
||||
Assert.IsTrue(b.CompareTo(b.Clone()) == 0);
|
||||
Assert.IsTrue(b.CompareTo(c) < 0);
|
||||
Assert.IsTrue(b.CompareTo(d) < 0);
|
||||
Assert.IsTrue(b.CompareTo(e) < 0);
|
||||
|
||||
Assert.IsTrue(c.CompareTo(a) > 0);
|
||||
Assert.IsTrue(c.CompareTo(b) > 0);
|
||||
Assert.IsTrue(c.CompareTo(c) == 0);
|
||||
Assert.IsTrue(c.CompareTo(c.Clone()) == 0);
|
||||
Assert.IsTrue(c.CompareTo(d) < 0);
|
||||
Assert.IsTrue(c.CompareTo(e) < 0);
|
||||
|
||||
Assert.IsTrue(d.CompareTo(a) > 0);
|
||||
Assert.IsTrue(d.CompareTo(b) > 0);
|
||||
Assert.IsTrue(d.CompareTo(c) > 0);
|
||||
Assert.IsTrue(d.CompareTo(d) == 0);
|
||||
Assert.IsTrue(d.CompareTo(d.Clone()) == 0);
|
||||
Assert.IsTrue(d.CompareTo(e) < 0);
|
||||
|
||||
Assert.IsTrue(e.CompareTo(a) > 0);
|
||||
Assert.IsTrue(e.CompareTo(b) > 0);
|
||||
Assert.IsTrue(e.CompareTo(c) > 0);
|
||||
Assert.IsTrue(e.CompareTo(d) > 0);
|
||||
Assert.IsTrue(e.CompareTo(e) == 0);
|
||||
Assert.IsTrue(e.CompareTo(e.Clone()) == 0);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void ComparabilityOperators()
|
||||
{
|
||||
Timestamp
|
||||
a = null,
|
||||
b = new Timestamp { Seconds = 1, Nanos = 1 },
|
||||
c = new Timestamp { Seconds = 1, Nanos = 10 },
|
||||
d = new Timestamp { Seconds = 10, Nanos = 1 },
|
||||
e = new Timestamp { Seconds = 10, Nanos = 10 };
|
||||
|
||||
#pragma warning disable CS1718 // Comparison made to same variable
|
||||
Assert.IsTrue(b > a);
|
||||
Assert.IsTrue(b == b);
|
||||
Assert.IsTrue(b == b.Clone());
|
||||
Assert.IsTrue(b < c);
|
||||
Assert.IsTrue(b < d);
|
||||
Assert.IsTrue(b < e);
|
||||
|
||||
Assert.IsTrue(c > a);
|
||||
Assert.IsTrue(c > b);
|
||||
Assert.IsTrue(c == c);
|
||||
Assert.IsTrue(c == c.Clone());
|
||||
Assert.IsTrue(c < d);
|
||||
Assert.IsTrue(c < e);
|
||||
|
||||
Assert.IsTrue(d > a);
|
||||
Assert.IsTrue(d > b);
|
||||
Assert.IsTrue(d > c);
|
||||
Assert.IsTrue(d == d);
|
||||
Assert.IsTrue(d == d.Clone());
|
||||
Assert.IsTrue(d < e);
|
||||
|
||||
Assert.IsTrue(e > a);
|
||||
Assert.IsTrue(e > b);
|
||||
Assert.IsTrue(e > c);
|
||||
Assert.IsTrue(e > d);
|
||||
Assert.IsTrue(e == e);
|
||||
Assert.IsTrue(e == e.Clone());
|
||||
|
||||
Assert.IsTrue(b >= a);
|
||||
Assert.IsTrue(b <= c);
|
||||
Assert.IsTrue(b <= d);
|
||||
Assert.IsTrue(b <= e);
|
||||
|
||||
Assert.IsTrue(c >= a);
|
||||
Assert.IsTrue(c >= b);
|
||||
Assert.IsTrue(c <= d);
|
||||
Assert.IsTrue(c <= e);
|
||||
|
||||
Assert.IsTrue(d >= a);
|
||||
Assert.IsTrue(d >= b);
|
||||
Assert.IsTrue(d >= c);
|
||||
Assert.IsTrue(d <= e);
|
||||
|
||||
Assert.IsTrue(e >= a);
|
||||
Assert.IsTrue(e >= b);
|
||||
Assert.IsTrue(e >= c);
|
||||
Assert.IsTrue(e >= d);
|
||||
#pragma warning restore CS1718 // Comparison made to same variable
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ using System.Text;
|
||||
|
||||
namespace Google.Protobuf.WellKnownTypes
|
||||
{
|
||||
public partial class Timestamp : ICustomDiagnosticMessage
|
||||
public partial class Timestamp : ICustomDiagnosticMessage, IComparable<Timestamp>
|
||||
{
|
||||
private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
// Constants determined programmatically, but then hard-coded so they can be constant expressions.
|
||||
@ -222,6 +222,109 @@ namespace Google.Protobuf.WellKnownTypes
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Given another timestamp, returns 0 if the timestamps are equivalent, -1 if this timestamp precedes the other, and 1 otherwise
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Make sure the timestamps are normalized. Comparing non-normalized timestamps is not specified and may give unexpected results.
|
||||
/// </remarks>
|
||||
/// <param name="other">Timestamp to compare</param>
|
||||
/// <returns>an integer indicating whether this timestamp precedes or follows the other</returns>
|
||||
public int CompareTo(Timestamp other)
|
||||
{
|
||||
return other == null ? 1
|
||||
: Seconds < other.Seconds ? -1
|
||||
: Seconds > other.Seconds ? 1
|
||||
: Nanos < other.Nanos ? -1
|
||||
: Nanos > other.Nanos ? 1
|
||||
: 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two timestamps and returns whether the first is less than (chronologically precedes) the second
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Make sure the timestamps are normalized. Comparing non-normalized timestamps is not specified and may give unexpected results.
|
||||
/// </remarks>
|
||||
/// <param name="a"></param>
|
||||
/// <param name="b"></param>
|
||||
/// <returns>true if a precedes b</returns>
|
||||
public static bool operator <(Timestamp a, Timestamp b)
|
||||
{
|
||||
return a.CompareTo(b) < 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two timestamps and returns whether the first is greater than (chronologically follows) the second
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Make sure the timestamps are normalized. Comparing non-normalized timestamps is not specified and may give unexpected results.
|
||||
/// </remarks>
|
||||
/// <param name="a"></param>
|
||||
/// <param name="b"></param>
|
||||
/// <returns>true if a follows b</returns>
|
||||
public static bool operator >(Timestamp a, Timestamp b)
|
||||
{
|
||||
return a.CompareTo(b) > 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two timestamps and returns whether the first is less than (chronologically precedes) the second
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Make sure the timestamps are normalized. Comparing non-normalized timestamps is not specified and may give unexpected results.
|
||||
/// </remarks>
|
||||
/// <param name="a"></param>
|
||||
/// <param name="b"></param>
|
||||
/// <returns>true if a precedes b</returns>
|
||||
public static bool operator <=(Timestamp a, Timestamp b)
|
||||
{
|
||||
return a.CompareTo(b) <= 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two timestamps and returns whether the first is greater than (chronologically follows) the second
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Make sure the timestamps are normalized. Comparing non-normalized timestamps is not specified and may give unexpected results.
|
||||
/// </remarks>
|
||||
/// <param name="a"></param>
|
||||
/// <param name="b"></param>
|
||||
/// <returns>true if a follows b</returns>
|
||||
public static bool operator >=(Timestamp a, Timestamp b)
|
||||
{
|
||||
return a.CompareTo(b) >= 0;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether two timestamps are equivalent
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Make sure the timestamps are normalized. Comparing non-normalized timestamps is not specified and may give unexpected results.
|
||||
/// </remarks>
|
||||
/// <param name="a"></param>
|
||||
/// <param name="b"></param>
|
||||
/// <returns>true if the two timestamps refer to the same nanosecond</returns>
|
||||
public static bool operator ==(Timestamp a, Timestamp b)
|
||||
{
|
||||
return ReferenceEquals(a, b) || (a is null ? (b is null ? true : false) : a.Equals(b));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether two timestamps differ
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Make sure the timestamps are normalized. Comparing non-normalized timestamps is not specified and may give unexpected results.
|
||||
/// </remarks>
|
||||
/// <param name="a"></param>
|
||||
/// <param name="b"></param>
|
||||
/// <returns>true if the two timestamps differ</returns>
|
||||
public static bool operator !=(Timestamp a, Timestamp b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string representation of this <see cref="Timestamp"/> for diagnostic purposes.
|
||||
/// </summary>
|
||||
|
Loading…
Reference in New Issue
Block a user