将DateTime的Date部分序列化为4个字节的最快方法?

时间:2015-05-14 17:25:39

标签: c# datetime

我想将Date的{​​{1}}部分序列化为4个字节(可能是Int32)。最快的方法是什么?

背景:为了序列化一个完整的DateTime,到目前为止我一直在使用DateTime方法。它返回ToBinary,我将其存储在其他位置。现在,我需要仅使用一半空间来存储Int64 Date部分。所以,我想知道如何以最快的方式实现这一点,因为性能至关重要。

我想到的选项是:

  • 使用一些乘法和属性访问将年,月,日和DateTime编码为YYYYMMDD,这种编码具有人类可读的良好副作用。
  • 继续使用int并仅保留"上半部分或下半部分"返回的ToBinary。不知道这是否可能。
  • 检查内部存储long的方式。也许可以通过其他方式访问日期部分。

你会怎么做?

2 个答案:

答案 0 :(得分:7)

DateTime被存储为自0001年1月1日00:00:00以来的刻度数。因此,如果您使用DateTime的Ticks并将其除以TimeSpan.TicksPerDay,那么结束自0001年1月1日以来的天数。

反向操作(乘以TimeSpan.TicksPerDay)反序列化时。

由于DateTime涵盖范围内“仅”3,652,058天,因此很容易适合Int32

序列化:

System.DateTime toSerialize;
long longDays = toSerialize.Ticks / System.TimeSpan.TicksPerDay;

// Safe since (DateTime.MaxValue - DateTime.MinValue).Days << Int32.MaxValue
int days = (int)longDays; 
// Serializes `days` however you would serialize any other int

反序列化:

int days;
long ticks = days * System.TimeSpan.TicksPerDay;
System.DateTime deserialized = new DateTime(ticks);

答案 1 :(得分:2)

.net Year(0001-9999)支持的任何DateTime都适合short,即2个字节。 <{1}}和Day将分别为Month

因此,您只需创建一个包含所有三个字段的自定义结构。

byte

你可以序列化这个4字节的结构(假设没有填充)。您可以只存储结构的字节表示,因为此结构是blittable。

如果您可以使用不安全的代码,那么转换可以非常快速地进行。否则use one of the .Net'ish way

public struct Date
{
    public readonly short Year;//2 byte
    public readonly byte Month;//1 byte
    public readonly byte Day;  //1 byte
    ...
}

或者你可以使用专为处理这类事情而设计的private unsafe int DateToInt(Date date) { int* d = (int*)&date; return *d; } private unsafe Date IntToDate(int date) { Date* d = (Date*)(&date); return *d; }

BitVector32