New-TimeSpan of two midnight dates is skipped every other day

I am trying to simply calculate the number of days until a user's password expires. I am using TimeSpan for this. My code in practice looks like this:

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

      

So, if the current date is 90 days after the date the password was last set, the days before the password expires will be 0.

Unfortunately, this code will return the same result for many consecutive days. For some reason I can't get quite consistent results here, I suppose it depends on the time of day, but I'm not sure why. We skip most of the time every other day. So if we run this every day of the week, we will return 4,4,2,2,0,0.

To replicate easily, you can use the following:

$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

      

+3


source to share


2 answers


Ok I found it. It depends on milliseconds. Sometimes the difference would be 1 day and a few milliseconds. Sometimes these few milliseconds go to the other side, so the difference will be 23 hours 59 minutes 59 seconds. 78 milliseconds (for example). This displays as 0 days!

To see this, just remove .Hours

from your example and try to replicate it.



    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

      

To fix this problem, just add one second to the calculation and you will get the correct number of days.

+3


source


Why is it so difficult? You can subtract the current date from the date 90 days before and get TotalDays

:

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

      

Now you only need to check if there is a result -le 90

.




Note. Since Igor figured out that TotalMilliseconds might be the root of your problem, I would suggest extracting the date only once :

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

      

Then you don't need to deal with Hours, Minutes, Sedna, Milliseconds and Slander.

+2


source







All Articles