【问题标题】:How can `DateTime.Now - DateTimeNow.AddSecond(-1)` be zero`DateTime.Now - DateTimeNow.AddSecond(-1)` 怎么可能为零
【发布时间】:2015-04-09 06:05:11
【问题描述】:

我在控制台应用程序中运行以下代码:

while (true)
{
    DateTime dt1 = DateTime.Now;
    DateTime dt2 = DateTime.Now.AddSeconds(-1);

    if ((dt1 - dt2).Seconds != 1)
        Console.Write((dt1 - dt2).Seconds.ToString());
}

我认为(dt1 - dt2).Seconds 始终是1 但我看到它在输出中写了很多0 !!??

为什么(dt1 - dt2).Seconds 变成0?


然后我尝试下面的代码:

if ((dt1.Hour * 3600 - dt2.Hour * 3600 + dt1.Minute * 60 - dt2.Minute * 60 + dt1.Second - dt2.Second) != 1)
    Console.Write((dt1.Second - dt2.Second).ToString());

这个新代码说可能(dt1.Hour * 3600 - dt2.Hour * 3600 + dt1.Minute * 60 - dt2.Minute * 60 + dt1.Second - dt2.Second) 总是1(但是我知道23:59:59 => 00:00:00 它应该写一个值)

【问题讨论】:

  • 我看到你的答案可以从输出中删除那些0,但我想知道为什么下一个代码在使用 dt1 和 dt2 时不会在输出中生成0? ;)。

标签: c# datetime


【解决方案1】:

因为您再次为您的 dt2 变量评估您的 DateTime.Now 值,这就是为什么这个微小的差异是完全可以预料的。这意味着您的第二个 DateTime.Now 在第一个之后计算至少 1 个 Tick 和最多 1000 万个 Ticks(等于 1 秒)。

由于DateTime.Second property 是用InternalTicks 和TicksPerSecond 计算的,所以当InternalTicks 小于TicksPerSecond 的值时,它会在用60 计算余数时返回零。

public int Second
{
     get
     {
        return (int)((InternalTicks / TicksPerSecond) % 60); 
     }
} 

如果您对两个变量使用相同的 DateTime.Now 值,那应该没问题。

DateTime now = DateTime.Now;
DateTime dt1 = now;
DateTime dt2 = now.AddSeconds(-1);

为什么 (dt1.Hour * 3600 - dt2.Hour * 3600 + dt1.Minute * 60 - dt2.Minute * 60 + dt1.Second - dt2.Second) 总是 1?

嗯,不总是1。假设您的第一个DateTime.Now(即dt1)生成00:00:00.00000。第二个DateTime.Now 生成00:00:00.00002(这些是理论值),您的dt2 将是23:59:59.002。

让我们看看Hours、Minute和Second的值;

dt1.Hour = 0;
dt2.Hour = 23;
dt1.Minute = 0;
dt2.Minute = 59;
dt1.Second = 0;
dt2.Second = 59;

dt1.Hour * 3600 - dt2.Hour * 3600 + dt1.Minute * 60 - dt2.Minute * 60 + dt1.Second - dt2.Second) 的结果将是 -86399 而不是 1。

【讨论】:

  • 我看到你的回答可以从输出中删除那些0,但我想知道为什么下一个代码在使用 dt1 和 dt2 时不会在输出中生成0? ;)。
  • 我永远不应该使用if (DateTime.Now - DateTime.Now.AddSeconds(-1)) ;)。
  • @shA.t 添加了更多解释为什么它不会总是返回1。
  • @shA.t 没错。因为即使它们在同一行,DateTime.Now 可能也不会产生相同的结果,因为它们是从左到右计算的,因为- 运算符是左关联的,
【解决方案2】:

尝试这样做

 DateTime dt1 = DateTime.Now;
 DateTime dt2 = dt1.AddSeconds(-1);

当您访问DateTime.Now 时,您已经初始化了 2 个不同的时间戳(它们的时间相差很小)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-08
    • 2022-01-20
    • 1970-01-01
    • 2023-01-08
    • 2019-06-26
    • 1970-01-01
    • 1970-01-01
    • 2012-10-21
    相关资源
    最近更新 更多