【问题标题】:New-TimeSpan of two midnight dates skips every other day两个午夜日期的 New-TimeSpan 每隔一天跳过一次
【发布时间】:2017-05-17 23:39:41
【问题描述】:

我试图简单地计算用户密码到期前的天数。我使用 TimeSpan 来执行此操作。我在实践中的代码如下:

(New-TimeSpan -Start (get-date -hour 0 -minute 0 -second 0) -End (Get-Date $_.PasswordLastSet -hour 0 -minute 0 -second 0).AddDays(90)).Days

因此,如果当前日期是上次设置密码后的 90 天,则密码到期前的天数将为 0。

很遗憾,此代码将连续多天返回相同的结果。出于某种原因,我似乎无法在这里获得完全一致的结果,我认为这取决于一天中的时间,但我不确定为什么。大多数时候,我们每隔一天跳过一次。因此,如果我们一周中的每一天都运行它,我们将返回 4,4,2,2,0,0。

要轻松复制,您可以使用以下内容:

$x = (get-date).AddDays(-90)
(New-TimeSpan -Start (get-date $x -hour 0 -minute 0 -second 0).AddDays(90) -End (get-date -hour 0 -minute 0 -second 0)).Days
(New-TimeSpan -Start (get-date $x -hour 0 -minute 0 -second 0).AddDays(89) -End (get-date -hour 0 -minute 0 -second 0)).Days

【问题讨论】:

  • 对我来说,它返回 0AddDays(90)1AddDays(89)。这是正确的,不是吗?
  • 只是为了确认它可以被复制。我在三个不同的系统上尝试了这段代码。在他们中的第一个上,我连续得到 0,1(如预期的那样)。但在另外两个系统上,我得到了 0,0。在重复测试中,数字是随机的 0,0 或 0,1。

标签: powershell


【解决方案1】:

好的,我找到了。这取决于毫秒。有时差异会是 1 天零几毫秒。有时,那几毫秒会转到另一边,因此差异将是 23 小时 59 分 59 秒 78 毫秒(例如)。这显示为 0 天!

要查看它,只需从您的示例中删除 .Hours 并尝试复制它。

    New-TimeSpan -Start (get-date $x -hour 0 -minute 0 -second 0).AddDays(89) -End (get-date -hour 0 -minute 0 -second 0)

Days              : 0
Hours             : 23
Minutes           : 59
Seconds           : 59
Milliseconds      : 78
Ticks             : 863990781260
TotalDays         : 0.999989330162037
TotalHours        : 23.9997439238889
TotalMinutes      : 1439.98463543333
TotalSeconds      : 86399.078126
TotalMilliseconds : 86399078.126

要解决它,只需在计算中增加一秒,您就会得到正确的天数。

【讨论】:

  • 感谢您的回答,我认为这是由确切的滴答声引起的。使用 Martins 回答的代码,我随机返回 1 和 0.99。这个解决方案应该有效。
  • @MacroPower 如果您检查我编辑的答案,则无需多加一秒。
  • 不幸的是@MartinBrandl,由于我在问题的第一个代码块中的确切用例,我确实需要使用两次 get-date。不过,我相信这会对未来的人们有所帮助。
【解决方案2】:

为什么这么难?您可以从 90 天前的日期中减去当前日期并检索 TotalDays

(Get-Date) - (Get-Date).AddDays(-90) | Select-Object -ExpandProperty TotalDays

现在你只需要检查结果是否为-le 90


注意:由于 Igor 发现 TotalMilliseconds 可能是您问题的根源,我建议只检索日期一次

$date= Get-Date
$date - $date.AddDays(-90) | Select-Object -ExpandProperty TotalDays

那么您就不必处理小时、分钟、秒、毫秒和滴答声了。

【讨论】:

  • 实际上,我认为这暴露了问题。使用 (TimeSpan).Days 返回 int。出于某种原因,如果我使用(Get-Date -hour 0 -minute 0 -second 0) - (Get-Date -hour 0 -minute 0 -second 0).AddDays(-90).AddDays(89) | Select-Object -ExpandProperty TotalDays,我将返回 0.9999999...,而不是 1。这解释了跳过。你知道为什么会返回这个值吗?
  • 奇怪!没有线索。但是您可以简单地将返回值 cast[int]: [int]((Get-Date -hour 0 -minute 0 -second 0) - (Get-Date -hour 0 -minute 0 -second 0).AddDays(-90).AddDays(89) | Select-Object -ExpandProperty TotalDays)
  • 我想我使用 Igor 的提示为您找到了解决方案,请查看我编辑的答案
  • 在原始代码中,Marco 使用了两次 Get-Date,一次是检查当前日期,第二次是检查上次设置密码的日期。
猜你喜欢
  • 1970-01-01
  • 2014-12-06
  • 2011-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多