diff --git a/Runtime/C#/Runtime/BebopReader.cs b/Runtime/C#/Runtime/BebopReader.cs
index e6bff96b..b8630170 100644
--- a/Runtime/C#/Runtime/BebopReader.cs
+++ b/Runtime/C#/Runtime/BebopReader.cs
@@ -14,6 +14,9 @@ namespace Bebop.Runtime
///
public ref struct BebopReader
{
+ private const long TicksBetweenEpochs = 621355968000000000L;
+ private const ulong DateMask = 0x3fffffffffffffffUL;
+
// ReSharper disable once InconsistentNaming
private static readonly UTF8Encoding UTF8 = new();
@@ -193,9 +196,13 @@ public double ReadFloat64()
///
/// A UTC instance.
[MethodImpl(BebopConstants.HotPath)]
- public DateTime ReadDate() =>
- // make sure it always reads it as UTC by setting the first bits to `01`.
- DateTime.FromBinary((ReadInt64() & 0x7fffffffffffffff) | 0x4000000000000000);
+ public DateTime ReadDate()
+ {
+ ulong rawTicks = ReadUInt64() & DateMask;
+ long ticks = unchecked((long)rawTicks);
+ long ms = (ticks - TicksBetweenEpochs) / 10000L;
+ return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(ms);
+ }
///
/// Reads a length prefixed string from the underlying buffer and advances the current position by that many bytes.