如何使用C#中的DateTime.Now.Ticks保持精度

我知道当我在C#中使用DateTime.Now.Ticks时它返回一个long值,但是我需要将它存储在一个int变量中,我对是否可以保持这种精度感到困惑。 截至目前我只是一个演员

int timeStampValue = (int)DateTime.Now.Ticks; 

这是一个项目约束,所以我知道有很多精度损失。 我想我只是想不出另一种方法来存储一个存储在int中的时间戳,然后我可以将其与其他时间戳进行比较。

如果可能的话,任何关于如何保持精度的建议或建议都将非常感激。

每个人的答案都是说明性的。 我实际上最终只设置了一个涉及计数器的进程,当使用一个项目时,它的计数器设置为’0’,所有其他计数器增加1.然后,最高计数器是下一个要使用的项目。

你需要所有最重要的部分吗? (例如哪一年)

你需要所有最不重要的位吗? (例如亚纳秒精度)

您需要多长时间来衡量一下?

如果只需要毫秒精度,为什么不丢失最低有效位

 int timeStamp = (int)(DateTime.Now.Ticks >> 10) // lose smallest 10 bits 

编辑

OP希望存储最近使用过的项目的时间:如果这是单个用户的用户选择,您可能不希望任何短于一秒的东西! 因为每秒有10 ^ 7个滴答,所以长值中有log(10 ^ 7)/ log(2)= 23个超额位!

那么你需要多少空间? 那么,你的价值观应该指明年,月,日,时,分和秒; 一年大约有3200万秒=大约24位。 如果您想存储最近10年的价值,请添加3位。 因此很容易融入int32。 我建议

 int timeStamp = (int)(DateTime.Now.Ticks >>23) // retain bits 23 to 55 

DateTime.Now并不是那么精确。

http://blogs.msdn.com/ericlippert/archive/2010/04/08/precision-and-accuracy-of-datetime.aspx

话虽如此,如果您将值转换为较小的类型,默认情况下您可以在任何情况下丢失数据。

考虑这个输出:

 int.MaxValue: 2147483647 DateTime.Now.Ticks: 634075598514933010 

如何将这个转换成int是一个现实的选择?

如果毫秒的分辨率足够好,您可以在int字段中存储来自某些基础DataTime偏移量,然后在需要时重建完整的DateTime 。 存储在32位整数中的毫秒数将允许您的应用程序在包装之前运行49天。 这是一个你可以使用的简单助手类:

 public class TimeOffsetManager { public TimeOffsetManager() { InitialDateTime = DateTime.Now; } public DateTime InitialDateTime { get; private set; } public int GetOffset() { TimeSpan elapsed = DateTime.Now - InitialDateTime; return (int)Math.Round(elapsed.TotalMilliseconds); } public DateTime OffsetToDateTime(int offset) { return InitialDateTime + TimeSpan.FromMilliseconds(offset); } } 

它可以像:

 public static void Method() { var offsetManager = new TimeOffsetManager(); int offset = offsetManager.GetOffset(); // ... DateTime realTime = offsetManager.OffsetToDateTime(offset); } 

更多关于踢球的事情……如果你已经设置使用整数来存储你的DateTime并保持精度,你可以定义你自己的包含两个整数的结构,每个包含4个字节,以及一个共享这些字节的DateTime。

 public class Program { public static void Main(string[] args) { DateTime now = DateTime.Now; var myDate = new Int32BackedDate(now.Ticks); Console.WriteLine(now); Console.WriteLine(myDate.Date); } } [StructLayout(LayoutKind.Explicit, Size = 8)] public struct Int32BackedDate { [FieldOffset(4)] private readonly int _high; [FieldOffset(0)] private readonly int _low; [FieldOffset(0)] private readonly DateTime _date; public DateTime Date { get { return _date; } } public Int32BackedDate(long ticks) { _date = default(DateTime); byte[] bytes = BitConverter.GetBytes(ticks); _low = BitConverter.ToInt32(bytes, 0); _high = BitConverter.ToInt32(bytes, 4); } } 

参考我上面的评论。 准确的约束是什么? 如果约束是你不能将数据存储在64位变量中,那么如何做一些事情。

 uint tsLow = (uint)DateTime.Now.Ticks; uint tsHigh = (uint)(DateTime.Now.Ticks >> 32); 

现在,您可以将tsLow和tsHigh存储到外部数据中。 您还可以实现可以使用两个单独的32位数来计算值的特殊函数来执行您自己的64位数学运算。

这实际上取决于您的实际约束。 了解这些将有助于提出更好的解决方案。