比较 C# 中的日期时间偏移量
本文关键字:时间 偏移量 日期 比较 | 更新日期: 2023-09-27 18:34:53
我正在尝试比较两个DateTimeOffsets,但DateTimeOffset.Compare((函数没有按预期运行。我创建了示例脚本来演示该问题。在此示例中,我期望比较日期 A 和日期 B 的结果为零(相同(。
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");
首先,DateTimeOffset
和DateTime
的精度比毫秒更精细。 它们表示的最小单位是 100ns 的"刻度"。 换句话说,小数秒的小数点有七个位,而不是三个。 (计算机的时钟本身并不那么精确,但这些数据结构仍然可以以这种精度表示值。
最终,您问(在问题评论中(:
。如何比较两个忽略毫秒的日期时间偏移量?
所以要知道我们知道你在问什么,考虑到仅仅忽略秒数并不能解决问题。
-
考虑一下
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
与此几乎相同,所以是的 - 这种方法很好。 尽管您可能更喜欢我的实现以提高可读性,并更好地控制阈值,但如果您决定将其更改为其他内容。
您的时间跨度不同,如果您使用适当的格式说明符(例如往返格式"o"
,则可以看出。
dateA.ToString("o")
下面是有关如何截断毫秒的一些示例。
Sleep(1)
只会休眠 1 毫秒。所以大概dateA
和dateB
只有1或2毫秒的距离。
由于仅将日期/时间值打印为分钟和秒,因此看不到实际差异。如果你使用Console.WriteLine("dateA =" + dateA.ToString("dd/MM/yyyy HH:mm:ss.fff");
你会看到区别。
如果你打算等待1秒钟,你应该做一个Sleep(1000)