I was testing out the PowerShell cmdlets that ship with Backup and Replication from Veeam Software. I was using the cmdlet to return backup jobs and realized I needed a way to only get those objects where the date was today. Because the property was a complete date time object, I couldn't simply check if A -eq B. I needed something else.
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
I initially thought I could simply check the DayOftheYear property.
PS C:\> $d=Get-Date
PS C:\> $d.DayOfYear
350
PS C:\> $d.DayOfYear -eq $now.DayOfYear
True
But, if the two dates were exactly one year apart, I would get a false positive. Then I thought I would be clever and add the day of year to the year. Kinda like creating a hash.
PS C:\> $yesterday.DayOfYear+$yesterday.year -eq $now.DayOfYear+$now.year
False
However, as someone pointed out to me this logic is flawed.
PS C:\> [datetime]$a="1/1/2011"
PS C:\> [datetime]$b="1/2/2010"
PS C:\> $a.DayOfYear+$a.year -eq $b.DayOfYear+$b.year
True
Oops. There probably is a hash I could create but perhaps the better answer is to simply compare the two DateTime objects. For that we can use the Compare-Object cmdlet, which has an alias of diff.
PS C:\> diff $d $now
InputObject SideIndicator
----------- -------------
12/16/2011 12:32:14 PM =>
12/16/2011 12:26:51 PM <=
As you can see $d and $now are both the same day. But Compare-Object is finding differences. What I can so is instruct the cmdlet to limit its comparison to specific properties.
PS C:\> diff $d $now -Property DayOfYear,Year
Nothing is returned so I can assume the two are identical. Let's check two that are different.
PS C:\> diff $a $b -Property DayOfYear,Year
DayOfYear Year SideIndicator
--------- ---- -------------
2 2010 =>
1 2011 <=
PS C:\> diff $yesterday $now -Property DayOfYear,Year
DayOfYear Year SideIndicator
--------- ---- -------------
350 2011 =>
349 2011 <=
Differences are found so these objects are different. I can take this and turn it into a logic construct.
PS C:\> if (diff $yesterday $now -Property DayOfYear,Year) {$False} else {$True}
False
PS C:\> if (diff $d $now -Property DayOfYear,Year) {$False} else {$True}
True
This seems to get the job done. But since that is a lot to type, and I might want to use this logic again, I'll turn it into a function.
Function Test-IsToday {
Param(
[Parameter(Position=0,Mandatory=$True,HelpMessage="Enter a date time value to compare")]
[ValidateNotNullorEmpty()]
[datetime]$Date
)
$now=Get-Date
Write-Verbose ("Comparing {0} to right now {1}" -f $Date,$Now)
if (Compare-Object -ReferenceObject $Date -DifferenceObject $Now -property dayofyear,year) {
$False
}
else {
$True
}
} #End function
The function simply wraps up the Compare-Object command and makes it easier for me to pass dates.
PS C:\> test-istoday $now
True
PS C:\> test-istoday $d -verbose
VERBOSE: Comparing 12/16/2011 12:26:51 PM to right now 12/16/2011 12:43:25 PM
True
PS C:\> test-istoday $yesterday
False
PS C:\> test-istoday "12/25/2011"
False
PS C:\>
So far I haven't found a case where this won't work correctly. But if there is, most likely all I'll need to do is add another property comparison with Compare-Object.
Download Test-IsToday and try it out for yourself.
You can just use the “Date” property with -eq, it would be faster than calling the cmdlet or testing multipe properties…
$d.Date -eq $now.Date
Isn’t this easier?
$d=Get-Date
(get-date).Date -eq $d.Date
It always only compares the base date and drops the time. If dsisplayed it wil display the time as midnight.
Try this:
PS>$d=Get-Date
Friday, December 16, 2011 1:05:39 PM
PS>$d.Date
Friday, December 16, 2011 12:00:00 AM
I believe that these extras are because the Net Framework designers already realized that we need these things in pieces with datetimes objects in order to do comaprisins. A similar thing has eveolved over time with database datetime fields and the ability to get at all of the pieces.
This is a good demo of how to get the Compare-Object command to work in unusual circumstances. I always have a fight with that CmdLet because it is so counter-intuitive.
Good article Jeff.
I should run my stuff by people before posting. Yes, as you and Joel have pointed out the Date property is all I really needed.
PS C:\> $a,$b,$now,$yesterday,$d | sort date | select Date
Date
—-
1/2/2010 12:00:00 AM
1/1/2011 12:00:00 AM
12/15/2011 12:00:00 AM
12/16/2011 12:00:00 AM
12/16/2011 12:00:00 AM
The function can easily be modified by changing the If line to this:
if ($date.Date -ne $now.date) {
Thanks for the feedback.
Jeff – don’t feel bad. I do the same thing to myself all of the time. I will spend anhour building some code only to stuumble across a refrence to something that already exists.
It was a useful article anyway – hey – its Friday.
Damn, too late, I just wanted to post the same 🙂 Next time I should read the comments before I open the Powershell 🙂
$(Get-Date).Date -eq [datetime]::Today
That’s a good suggestion as well. Thanks.