Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to serialize a DateTimeOffset into a binary stream

I'm wondering what would be the best way to serialize a DateTimeOffset into a binary stream (using a BinaryWriter) and deserialize it again (using a BinaryReader).

To serialize a DateTime, I have:

    public void WriteValue(DateTime value)
    {
        _writer.Write(value.ToBinary());
    }

and

    public DateTime ReadDateTime()
    {
        return DateTime.FromBinary(_reader.ReadInt64());
    }

What is the best approach to serialize/deserialize a DateTimeOffset in terms of performance and storage size?

like image 233
Dejan Avatar asked Jul 02 '26 18:07

Dejan


2 Answers

Based on a comment by Hans Passant, I've came up with the following solution. To serialize:

    public void WriteValue(DateTimeOffset value)
    {
        WriteValue(value.DateTime);
        WriteValue((short)value.Offset.TotalMinutes);
    }

And deserialize:

    public DateTimeOffset ReadDateTimeOffset()
    {
        var dateTime = ReadDateTime();
        var minutes = ReadInt16();
        return new DateTimeOffset(dateTime, TimeSpan.FromMinutes(minutes));
    }

So these method call to the existing serialization methods for DateTime as outlined in the question.

I still wonder if this is the most efficient way to do this. How fast is it to call TotalMinutes and TimeSpan.FromMinutes?

like image 136
Dejan Avatar answered Jul 04 '26 09:07

Dejan


Not that my answer adds much but I have written this little utility for packing and unpacking DateTimeOffset:

public static class DateTimeOffsetExtensions
{
    /// <summary>
    /// Packs DateTimeOffset to bytes
    /// </summary>
    /// <param name="dateTimeOffset"></param>
    /// <returns>10 byte packed bytearray</returns>
    public static byte[] GetBytes(this DateTimeOffset dateTimeOffset)
    {
        return BitConverter.GetBytes(dateTimeOffset.Ticks).
           Concat(BitConverter.GetBytes((Int16)dateTimeOffset.Offset.TotalMinutes)).ToArray();
    }
    /// <summary>
    /// Reads 10 bytes from a buffer and turns back to DateTimeOffset
    /// </summary>
    /// <param name="bytes">Buffer</param>
    /// <param name="offset">Offset to read from</param>
    /// <returns></returns>
    public static DateTimeOffset FromBytes(byte[] bytes, int offset)
    {
        var ticks = BitConverter.ToInt64(bytes, offset);
        var offsetMinutes = BitConverter.ToInt16(bytes, offset + 8);
        return new DateTimeOffset(ticks, TimeSpan.FromMinutes(offsetMinutes));
    }
}
like image 27
Aliostad Avatar answered Jul 04 '26 07:07

Aliostad



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!