Skip to content

Commit

Permalink
fix(cs/deserialization): Align date deserialization with other implem…
Browse files Browse the repository at this point in the history
…entations

This commit modifies the date deserialization process in Bebop to ensure
consistency with the other implementations and corrects a type mismatch
issue. This change complements the previous fix for date serialization,
providing a complete and correct solution for date handling across languages.

- Modify `BebopReader.ReadDate()` method to use a more precise algorithm
- Introduce constants for ticks between epochs and date mask
- Update date conversion to use milliseconds since Unix epoch
- Ensure UTC DateTime is always returned
- Fix type mismatch between ulong and long in date calculation
- Use unchecked conversion to handle potential overflow

This change resolves inconsistencies in date representation when
deserializing data.
  • Loading branch information
andrewmd5 committed Aug 9, 2024
1 parent ec6e32c commit 7a2de39
Showing 1 changed file with 10 additions and 3 deletions.
13 changes: 10 additions & 3 deletions Runtime/C#/Runtime/BebopReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ namespace Bebop.Runtime
/// </summary>
public ref struct BebopReader
{
private const long TicksBetweenEpochs = 621355968000000000L;
private const ulong DateMask = 0x3fffffffffffffffUL;

// ReSharper disable once InconsistentNaming
private static readonly UTF8Encoding UTF8 = new();

Expand Down Expand Up @@ -193,9 +196,13 @@ public double ReadFloat64()
/// </summary>
/// <returns>A UTC <see cref="DateTime"/> instance.</returns>
[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);
}

/// <summary>
/// Reads a length prefixed string from the underlying buffer and advances the current position by that many bytes.
Expand Down

0 comments on commit 7a2de39

Please sign in to comment.