序列化日期时间为二进制 [英] Serialize DateTime as binary

查看:350
本文介绍了序列化日期时间为二进制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何正确序列化DateTime对象(例如使用的BinaryWriter),并保持其完整的状态?

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

我的印象是一个日期时间只有在通过内部长整数表示,并认为这是整数的日期时间的属性访问。然而,望着实施,蜱属性返回存储在名为 dateData

I was under the impression that a date time was only represented by an internal long integer, and that this integer was accessible as the Ticks property of the DateTime. However, looking at the implementation, the Ticks property actually returns a subset of the real internal data which is stored in an ulong called dateData

蜱(这只是得到InternalTicks)被实现,像这样:

Ticks (which just gets InternalTicks) is implemented like so:

public long InternalTicks
{
    get { return (long) this.dateData & 4611686018427387903L; }
}



据我可以看到这意味着dateData可能包含的信息不是由属性显露出来。

奇怪的是,日期时间的BinaryFormatter的序列化确实这GetObjectData使用()

Stranger yet, the BinaryFormatter Serialization of a DateTime does this in GetObjectData():

info.AddValue("ticks", this.InternalTicks);
info.AddValue("dateData", this.dateData);

这将输出的流中的两个的多头,其中一人会容易地从其他recovererd!

That will output two longs in the stream, where one of them would be easily recovererd from the other!

我如何可以序列我的DateTime,而不会丢失任何的内部状态的风险,(最好当然,在短短8个字节,且无反射)。我想,也许它可以转换(不安全的),直接到ULONG?

How can I serialize my DateTime without risk of losing any of the internal state, (preferably of course in just 8 bytes, and without reflection). I'm thinking maybe it can be cast (unsafe), directly to an ulong?

还是我担心没有理由,将在属性实际上编码所有必要的状态?

Or am I worrying for no reason, will the Ticks property actually encode all the necessary state?

推荐答案

有两条信息担心:



  • 的DateTimeKind

在内部,这些都是编码到像这样一个长,dateData:

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

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



所以属性将的的编码所有的状态。这将是缺少DateTimeKind信息。

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

dateData 确实的编码的所有数据,所以这是一个奇怪的事情,该串行器同时存储了

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.

修改

有一些陷阱做与本地时间调整。

There are some gotchas to do with local time adjustment.

所以我要建议的是不是与上述所有搞乱,你看看 DateTime.ToBinary() DateTime.FromBinary() 方法其中的将会的允许你作为序列长,受与本地时间调整的注意事项。这些警告是在上面的链接MSDN完全记录。

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.

这篇关于序列化日期时间为二进制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆