Serialize DateTime as binary

前端 未结 2 1405
遥遥无期
遥遥无期 2021-02-09 16:12

How do I properly serialize a DateTime object (e.g. using a BinaryWriter), and preserve its complete state?

I was under the impression that a date time was only represen

相关标签:
2条回答
  • 2021-02-09 16:46

    There are two pieces of information to worry about:

    • The Ticks
    • The DateTimeKind

    Internally these are both encoded into a single long, the dateData like so:

    this.dateData = (ulong) (ticks | (((long) kind) << 62));
    

    So the Ticks property will not encode all the state. It will be missing the DateTimeKind information.

    The dateData does encode all the data, so it is a curious thing that the serialiser stores both that and Ticks!

    So what you could do is this:

    ulong dataToSerialise = (ulong) (date.Ticks | ((long) date.Kind) << 62);
    

    And when deserializing, you can do this:

    long ticks = (long)(deserialisedData & 0x3FFFFFFFFFFFFFFF);
    DateTimeKind kind = (DateTimeKind)(deserialisedData >> 62);
    DateTime date = new DateTime(ticks, kind);
    

    This does make use of knowledge about the internals of DateTime, and it could theoretically change in the future, which could break this kind of serialisation.


    EDIT

    There are some gotchas to do with local time adjustment.

    So I'm going to suggest that instead of messing about with all of the above, you look at the DateTime.ToBinary() and DateTime.FromBinary() methods which will allow you to serialize as a long, subject to the caveats relating to the local time adjustment. These caveats are fully documented in the MSDN links above.

    0 讨论(0)
  • 2021-02-09 16:54

    i have done this with serialization for transmitting date in TCP Sockets

    here is code you can serialize any object like this

    public static byte[] DateToBytes(DateTime _Date)
    {
        using (System.IO.MemoryStream MS = new System.IO.MemoryStream()) {
            BinaryFormatter BF = new BinaryFormatter();
            BF.Serialize(MS, _Date);
            return MS.GetBuffer();
        }
    }
    
    
    public static DateTime BytesToDate(byte[] _Data)
    {
        using (System.IO.MemoryStream MS = new System.IO.MemoryStream(_Data)) {
            MS.Seek(0, SeekOrigin.Begin);
            BinaryFormatter BF = new BinaryFormatter();
            return (DateTime)BF.Deserialize(MS);
        }
    }
    

    EDIT

    without binaryformatter

    //uses 8 byte
    DateTime tDate = DateAndTime.Now;
    long dtVal = tDate.ToBinary();
    //64bit binary
    
    byte[] Bits = BitConverter.GetBytes(tDate.ToBinary());
    //your byte output
    
    //reverse
    long nVal = BitConverter.ToInt64(Bits, 0);
    //get 64bit binary
    DateTime nDate = DateTime.FromBinary(nVal);
    //convert it to date 
    
    0 讨论(0)
提交回复
热议问题