aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/csharp/Grpc.Core.Tests/Internal/TimespecTest.cs15
-rw-r--r--src/csharp/Grpc.Core/Internal/Timespec.cs35
2 files changed, 49 insertions, 1 deletions
diff --git a/src/csharp/Grpc.Core.Tests/Internal/TimespecTest.cs b/src/csharp/Grpc.Core.Tests/Internal/TimespecTest.cs
index 69b94bb393..8469a9e3da 100644
--- a/src/csharp/Grpc.Core.Tests/Internal/TimespecTest.cs
+++ b/src/csharp/Grpc.Core.Tests/Internal/TimespecTest.cs
@@ -41,9 +41,22 @@ namespace Grpc.Core.Internal.Tests
public class TimespecTest
{
[Test]
- public void Now()
+ public void Now_IsInUtc()
+ {
+ Assert.AreEqual(DateTimeKind.Utc, Timespec.Now.ToDateTime().Kind);
+ }
+
+ [Test]
+ public void Now_AgreesWithUtcNow()
{
var timespec = Timespec.Now;
+ var utcNow = DateTime.UtcNow;
+
+ TimeSpan difference = utcNow - timespec.ToDateTime();
+
+ // This test is inherently a race - but the two timestamps
+ // should really be way less that a minute apart.
+ Assert.IsTrue(difference.TotalSeconds < 60);
}
[Test]
diff --git a/src/csharp/Grpc.Core/Internal/Timespec.cs b/src/csharp/Grpc.Core/Internal/Timespec.cs
index 32a9c93f77..887eae5dd7 100644
--- a/src/csharp/Grpc.Core/Internal/Timespec.cs
+++ b/src/csharp/Grpc.Core/Internal/Timespec.cs
@@ -179,6 +179,41 @@ namespace Grpc.Core.Internal
return tv_sec.ToInt64() > 0 ? DateTime.MaxValue : DateTime.MinValue;
}
}
+
+ public static Timespec FromDateTime(DateTime dateTime)
+ {
+ if (dateTime == DateTime.MaxValue)
+ {
+ return Timespec.InfFuture;
+ }
+
+ if (dateTime == DateTime.MinValue)
+ {
+ return Timespec.InfPast;
+ }
+
+ Preconditions.CheckArgument(dateTime.Kind == DateTimeKind.Utc, "dateTime");
+
+ try
+ {
+ TimeSpan timeSpan = dateTime - UnixEpoch;
+ long ticks = timeSpan.Ticks;
+
+ IntPtr seconds = new IntPtr(ticks / TicksPerSecond); // possible OverflowException
+ // (x % m + m) % m is workaround for modulo semantics with negative numbers.
+ int nanos = (int)(((ticks % TicksPerSecond + TicksPerSecond) % TicksPerSecond) * NanosPerTick);
+
+ return new Timespec(seconds, nanos);
+ }
+ catch (OverflowException)
+ {
+ return dateTime > UnixEpoch ? Timespec.InfFuture : Timespec.InfPast;
+ }
+ catch (ArgumentOutOfRangeException)
+ {
+ return dateTime > UnixEpoch ? Timespec.InfFuture : Timespec.InfPast;
+ }
+ }
internal static int NativeSize
{