【问题标题】:Comparing the binary representation of DateTime in C#在 C# 中比较 DateTime 的二进制表示
【发布时间】:2020-11-06 00:51:39
【问题描述】:

我有一个DateTime 表示为长(8 字节),它来自DateTime.ToBinary(),我们称之为dateTimeBin。是否有删除时间信息的最佳方法(我只关心日期),以便我可以将其与一天的开始进行比较?假设我们有这个样本值作为一天的开始。

DateTime startOfDay = new DateTime(2020,3,4,0,0,0);
long startOfDayBin = startOfDay.ToBinary();

我显然知道我总是可以转换为 DateTime 对象然后获取日期组件。但是,此操作将发生数十亿次,每一次性能调整都会有所帮助。

  • 是否有一种有效的方法可以提取dateTimeBin 的日期信息而不将其转换为DateTime?或者对long 进行任何仅返回日期的算术运算?
  • 如果startOfDay(或startOfDayBin)和dateTimeBin具有相同的日期组件,有没有办法匹配它们?
  • 有没有办法看到if (dateTimeBin >= startOfDayBin),我觉得long比较不成立。

注意所有日期均为 UTC

【问题讨论】:

  • 我从未在 c# 中看到 DateTime 上的 GetBinary 方法 - 你确定那不是自定义扩展吗?或者你的意思是ToBinary
  • @Jamiec 好地方,我的意思是ToBinary,我修好了。
  • 好吧好吧。您遇到的问题是二进制不仅仅是一个数字(Ticks),它还对 Kind 属性进行了编码。我怀疑您尝试做的事情可能仅使用Ticks,但二进制表示专门是为了能够正确反序列化/反序列化
  • 您可以随时查看DateTime 的源代码以及ToBinaryDate 之类的操作,其中a) 向您展示了数学,b) 可能会让您想知道JIT 是否会内联所有内容无论如何,您应该只使用这些方法。
  • 没有“日期部分”或“时间部分”,因为它只是从纪元开始以来的一些滴答声。有点抨击在那里没有帮助。您应该首先确定这是一个实际的瓶颈;如果是,请考虑使用不同的在线格式来分割日期和时间。没有理由假设您将编写比 DateTime 自己编写的代码快得多的代码。

标签: c# datetime data-structures


【解决方案1】:

由于您只使用 UTC 日期 - 使用 DateTime.Ticks 而不是 DateTime.ToBinary 是有意义的,因为前者具有相对明确的含义 - 自纪元以来的滴答数,就像 unix 时间一样,唯一的区别是 unix 时间间隔是秒而不是滴答声(其中滴答声是 1/10.000.000 秒),并且纪元是 0001 年的 1 月 1 日午夜,而不是 1970 年。虽然 ToBinary 只承诺您可以恢复原始 DateTime 值就是这样。

使用刻度可以轻松提取时间和日期。要提取时间,您需要用一整天的刻度数除以刻度的余数,所以

long binTicks = myDateTime.Ticks;
long ticksInDay = 24L * 60 * 60 * 10_000_000;
long time = binTicks % ticksInDay;

然后您可以使用将其转换为 TimeSpan:

var ts = TimeSpan.FromTicks(time);

为方便起见,或按原样使用。与仅提取日期相同:只需减去时间

long date = binTicks - (binTicks % ticksInDay);

常规比较 (dateTimeBin >= startOfDayBin) 也适用于刻度值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-15
    • 1970-01-01
    • 2019-03-10
    • 1970-01-01
    • 2016-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多