比较C#中的DateTimeOffset' s

时间:2016-02-17 09:51:05

标签: c# datetimeoffset

我试图比较两个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");

3 个答案:

答案 0 :(得分:0)

您的时间跨度不一样,如果使用适当的格式说明符,可以看到,例如,往返格式"o"

dateA.ToString("o")

以下是how to truncate the milliseconds的一些示例。

答案 1 :(得分:0)

Sleep(1)只能睡1毫秒。因此,假设dateAdateB相距仅1或2毫秒。

由于您只将日期/时间值打印到分钟和秒,因此您看不到实际差异。如果您使用Console.WriteLine("dateA =" + dateA.ToString("dd/MM/yyyy HH:mm:ss.fff");,您会看到差异。

如果您打算等待1秒钟,则应该执行Sleep(1000)

答案 2 :(得分:0)

首先,DateTimeOffsetDateTime具有比毫秒更精细的精度。它们代表的最小单位是“刻度”,即100ns。换句话说,七个小数秒的小数位,而不是三个。 (计算机的时钟本身并不精确,但这些数据结构仍然可以用这种精度表示。)

最后,你问(在问题评论中):

  

...如何比较两个datetimeoffset忽略毫秒?

所以知道我们知道你在问什么,考虑只是忽略小数秒不会解决问题。

  • 考虑A是否有3.9999999秒,B是否有4.0000001。 截断小数将提供A == 3B == 4,因此A != B

  • 考虑A是否有3.4999999秒,B是否有3.5000001。
    舍入小数将提供A == 3B == 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与此基本相同,所以是的 - 这种方法很好。虽然您可能更喜欢我的实现以实现可读性,并且为了更好地控制阈值,您是否应该决定将其更改为其他内容。