C# 如何在C中使用DateTime.Now.Ticks保持精度#
我知道当我在C#中使用DateTime.Now.Ticks时,它会返回一个长值,但我需要将它存储在一个int变量中,我不知道是否可以保持该精度。现在我只有一个演员阵容C# 如何在C中使用DateTime.Now.Ticks保持精度#,c#,.net,datetime,timestamp,C#,.net,Datetime,Timestamp,我知道当我在C#中使用DateTime.Now.Ticks时,它会返回一个长值,但我需要将它存储在一个int变量中,我不知道是否可以保持该精度。现在我只有一个演员阵容 int timeStampValue = (int)DateTime.Now.Ticks; 这是一个项目限制,所以我知道会损失很多精度。我想我只是想不出另一种方法来做一个存储在int中的时间戳,然后我可以与其他时间戳进行比较 如有可能,请就如何保持精度提出任何建议或建议 每个人的回答都说明了问题。实际上,我只是设置了一个涉及计数
int timeStampValue = (int)DateTime.Now.Ticks;
这是一个项目限制,所以我知道会损失很多精度。我想我只是想不出另一种方法来做一个存储在int中的时间戳,然后我可以与其他时间戳进行比较
如有可能,请就如何保持精度提出任何建议或建议
每个人的回答都说明了问题。实际上,我只是设置了一个涉及计数器的进程,当使用一个项目时,它的计数器设置为“0”,所有其他计数器都递增1。那么,无论最高的计数器是什么,都是下一个要使用的项目。
DateTime。现在
并不那么精确
话虽如此,如果将值向下转换为较小的类型,默认情况下,在任何情况下都可能丢失数据
考虑这个输出:
int.MaxValue: 2147483647
DateTime.Now.Ticks: 634075598514933010
如何将其转换为整数是一个现实的选择?如果一毫秒的分辨率足够好,您可以在
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);
}
您需要所有最重要的位吗?(例如,哪一年) 您需要所有最低有效位吗?(例如,亚纳秒精度) 你需要测量多长时间间隔 如果您只需要毫秒精度,为什么不丢失最低有效位呢
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
关于我上面的评论。约束究竟是什么?如果约束条件是您不能将数据存储在64位变量中,那么按照以下方式进行操作如何
uint tsLow = (uint)DateTime.Now.Ticks;
uint tsHigh = (uint)(DateTime.Now.Ticks >> 32);
现在您可以将tsLow和tsHigh存储到外部数据中。您还可以实现特殊的函数,使用两个独立的32位数字计算值,以完成您自己的64位数学
这实际上取决于您的实际约束。了解这些将有助于提出更好的解决方案。更多的是为了好玩,而不是什么。。。如果您死心塌地地使用int来存储DateTime并保持精度,那么可以定义自己的结构,其中包含两个int,每个int包含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);
}
}
为什么必须存储在int中?这是一个项目约束,这是我能想到的唯一方法,我过去也没有做过时间戳的事情。你是不允许使用long,还是只用于存储外部数据?例如,如果您可以使用long来获取数据,然后存储两个int?根本不允许使用long,我只能使用int表示您根本不能使用int,这并没有真正给出约束。这是因为嵌入式系统吗?从调用'(int)DateTime.Now.Ticks;'时起,您的使用就会变长看看下面我的解决方案。您可以使用两个uint来表示整个timestamp long值,并为可能需要执行的任何数学创建自己的方法。这将允许您仅使用整数获得完整分辨率。是的,这不是一个现实的选择,虽然我真的没有选择,但这只是我想到的第一个想法。我需要能够跟踪阵列中最近使用最少的项目。