我试图比较两个DateTimeOffsets,但DateTimeOffset.Compare()函数没有按预期运行。我已经创建了示例脚本来演示该问题。在这个例子中,我期望将dateA和dateB的结果比较为零(相同)。
using System;
namespace ComparingDateTimeOffset
{
class Program
{
static void Main(string[] args)
{
DateTimeOffset dateA = DateTimeOffset.Now;
Thread.Sleep(1);
DateTimeOffset dateB = DateTimeOffset.Now;
Console.WriteLine("dateA =" + dateA);
Console.WriteLine("dateB =" + dateB);
Console.WriteLine(DateTimeOffset.Compare(dateA, dateB) == 0
? "dateA and dateB are the same"
: "dateA and dateB are NOT the same");
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
}
}
上述计划的结果是
dateA =17/02/2016 09:09:21 +00:00
dateB =17/02/2016 09:09:21 +00:00
dateA and dateB are NOT the same
Press any key to exit
在控制台输出中,看起来两个日期相同。但比较函数说两个日期不同。以下代码显示两个日期之间存在几毫秒的差异。
long diff = (long) (dateB - dateA).TotalMilliseconds;
Console.WriteLine("Time differance in milliseconds =" + diff);
避免使用DateTimeOffset.Compare函数。我决定以秒为单位计算日期之间的差异,然后舍入到最接近的整数。这种缝合起作用。任何人都可以看到使用这种方法的缺点吗?
Console.WriteLine((int)(dateB - dateA).TotalSeconds == 0
? "dateA and dateB are the same"
: "dateA and dateB are NOT the same");
答案 0 :(得分:0)
您的时间跨度不一样,如果使用适当的格式说明符,可以看到,例如,往返格式"o"
。
dateA.ToString("o")
以下是how to truncate the milliseconds的一些示例。
答案 1 :(得分:0)
Sleep(1)
只能睡1毫秒。因此,假设dateA
和dateB
相距仅1或2毫秒。
由于您只将日期/时间值打印到分钟和秒,因此您看不到实际差异。如果您使用Console.WriteLine("dateA =" + dateA.ToString("dd/MM/yyyy HH:mm:ss.fff");
,您会看到差异。
如果您打算等待1秒钟,则应该执行Sleep(1000)
答案 2 :(得分:0)
首先,DateTimeOffset
和DateTime
具有比毫秒更精细的精度。它们代表的最小单位是“刻度”,即100ns。换句话说,七个小数秒的小数位,而不是三个。 (计算机的时钟本身并不精确,但这些数据结构仍然可以用这种精度表示值。)
最后,你问(在问题评论中):
...如何比较两个datetimeoffset忽略毫秒?
所以知道我们知道你在问什么,考虑只是忽略小数秒不会解决问题。
考虑A
是否有3.9999999秒,B
是否有4.0000001。
截断小数将提供A == 3
,B == 4
,因此A != B
。
考虑A
是否有3.4999999秒,B
是否有3.5000001。
舍入小数将提供A == 3
,B == 4
,因此A != B
。
所以 截断或舍入都不会解决所有用例。您不能保证两个连续时钟读数之间的值将被截断或舍入为相同的值。
相反,正如您所建议的那样,确定两个值之间的最小差异,您可以将它们视为相同。例如,如果您认为不到一秒的任何事情都是无关紧要的,那么:
if ((dateB - dateA) < TimeSpan.FromSeconds(1))
{
// equivalent, within 1s threshold
}
else
{
// not equivalent or within threshold.
// you could continue with normal comparison to determine < or > if desired
}
你的实现:(int)(dateB - dateA).TotalSeconds == 0
与此基本相同,所以是的 - 这种方法很好。虽然您可能更喜欢我的实现以实现可读性,并且为了更好地控制阈值,您是否应该决定将其更改为其他内容。