Reputation: 425
I'am trying to compare two dates, if they not equals, I write current date to txt file, but I always getting two dates different, even if I wrote new date to file right now.
$lastBackup=Get-Date (Get-Content -Path last_backup.txt)
"First date is: $lastBackup"
write-host
$lastModified = Get-Date ((Get-Item "My folder").LastWriteTime)
"Second date is: $lastModified"
write-host
if ($lastBackup -ne $lastModified)
{
Set-Content -Path .\last_backup.txt -Value $lastModified -NoNewline
"Dates are not equal"
write-host
}
Output:
First date is: 03/13/2019 23:35:17
Second date is: 03/13/2019 23:35:17
Dates are not equal
$lastBackup and $lastModified are both DateTime objects. What's wrong with this script?
Upvotes: 1
Views: 1285
Reputation: 437090
You cannot generally infer from the string representation of [datetime]
(System.DateTime
) instances whether they're exactly equal.
[datetime]
instance is generally not fully reflected in string representations.Two [datetime]
instances are only considered equal if their .Ticks
property values are equal.
.Ticks
property contains a [long]
(System.Int64
) value that expresses a point in time in terms of 100-nanosecond intervals since midnight of January 1st of the year 1 A.D. in the Gregorian Calendar.Therefore, if you want to compare [datetime]
instances (just called dates in the discussion below) at a higher level of granularity, additional work is needed:
Use the appropriate Get-Date
parameters to set all lower levels of granularity to 0
:
For instance, to compare dates at the granularity of seconds (to see if they fall into the same calendar second), set the -MilliSecond
component to 0
:
$dtNow = Get-Date
$dtNowAgain = Get-Date
# This - predictably - returns $false, because the dates aren't exactly equal,
# given that the date values will at least differ by milliseconds, and
# possibly also by the seconds value.
$dtNow -eq $dtNowAgain
# You can abstract away the difference by setting the milliseconds
# component to 0 - this will *typically* return $true
# NOTE: If a new calendar second happened to start between setting $dtNow
# and $dtNowAgain, this will return $false.
(Get-Date $dtNow -MilliSecond 0) -eq (Get-Date $dtNowAgain -MilliSecond 0)
To compare at the level of minutes (to see if they both fall into the same calendar minute), you must set both -Second
and -MilliSecond
to 0
:
# This will *typically* return $true.
# NOTE: If a new calendar minute happened to start between setting $dtNow
# and $dtNowAgain, this will return $false.
(Get-Date $dtNow -Second 0 -MilliSecond 0) -eq (Get-Date $dtNowAgain -Second 0 -MilliSecond 0)
Note: The advantage of the above approach over string-based comparison is that it ultimately still performs numerical comparisons, so that not only equality testing works (-eq
), but also inequality testing (-lt
/ -le
/ -gt
/ -ge
), as well as sorting.
Upvotes: 2
Reputation: 771
Round dates to seconds/minutes/5th minutes, etc before comparsion. You can do either:
$date = Get-Date
$date.ToString("yyyy-MM-dd HH:mm:ss.fff")
$roundedDate = Get-Date -Year $date.Year -Month $date.Month -Day $date.Day -Hour $date.Hour -Minute $date.Minute -Second $date.Second -Millisecond 0
$roundedDate.ToString("yyyy-MM-dd HH:mm:ss.fff")
or see this link https://jrich523.wordpress.com/2011/10/03/rounding-a-date-in-powershell/
Upvotes: 0