我知道当我在C#中使用DateTime.Now.Ticks时它会返回一个long值,但是我需要将它存储在一个int变量中,我对是否能保持这种精度感到困惑。截至目前我只是有一个演员
int timeStampValue = (int)DateTime.Now.Ticks;
这是一个项目约束,所以我知道有很多精度损失。我想我只是想不出另一种方法来存储一个存储在int中的时间戳,然后我可以将其与其他时间戳进行比较。
如果可能的话,任何关于如何保持精确度的建议或建议将非常感激。
每个人的答案都是说明性的。我实际上最终只设置了一个涉及计数器的进程,当使用一个项目时,它的计数器设置为'0',所有其他计数器增加1.然后,最高计数器是下一个要使用的项目。
答案 0 :(得分:13)
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是一个现实的选择?
答案 1 :(得分:11)
你需要所有最重要的部分吗? (例如哪一年)
你需要所有最不重要的位吗? (例如,亚纳秒精度)
您需要测量多长时间间隔?
如果只需要毫秒精度,为什么不丢失最低有效位
int timeStamp = (int)(DateTime.Now.Ticks >> 10) // lose smallest 10 bits
那么你需要多少空间?那么,你的价值观应该指明年,月,日,时,分和秒;一年大约有3200万秒=大约24位。如果您想存储过去10年的价值,请添加3位。因此很容易融入int32。 我建议
int timeStamp = (int)(DateTime.Now.Ticks >>23) // retain bits 23 to 55
答案 2 :(得分:2)
如果毫秒级的分辨率足够好,您可以在DataTime
字段中存储某些基数int
的偏移量,然后在需要时重建完整的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);
}
答案 3 :(得分:2)
更多关于踢的事情......如果你已经设置了使用整数存储你的DateTime并保持精度,你可以定义你自己的包含两个整数的结构,每个整数包含4个字节,以及一个分享这些整数的日期时间字节。
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);
}
}
答案 4 :(得分:1)
参考上面的评论。准确的约束是什么?如果约束是你不能将数据存储在64位变量中,那么如何做一些事情。
uint tsLow = (uint)DateTime.Now.Ticks;
uint tsHigh = (uint)(DateTime.Now.Ticks >> 32);
现在您可以将tsLow和tsHigh存储到外部数据中。您还可以实现可以使用两个单独的32位数来计算值的特殊函数,以执行您自己的64位数学运算。
这实际上取决于你的实际约束。了解这些将有助于提出更好的解决方案。