Last active
March 20, 2024 20:31
-
-
Save andyzib/22c4732627ae9a1d3f1776374980ec9c to your computer and use it in GitHub Desktop.
PowerShell function for finding the date of the Second Tuesday of July 2017, or whatever date you may need.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Function Get-XDayOfMonth { | |
<# | |
.SYNOPSIS | |
Returns the date of the requested day of the month. | |
.DESCRIPTION | |
This function will return the date for searches such as the third Tuesday of July 2018 or the Second Friday in August 2002. | |
.PARAMETER Find | |
What day to find: First, Second, Third, Fourth, Last. (Numbers 1-5 are also valid, 1 being First 5 being last.) | |
.PARAMETER Weekday | |
What day of the week to look for: Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday. | |
.PARAMETER Month | |
The month to search. 1-12. | |
.PARAMETER Year | |
The four digit year to search. | |
.INPUTS | |
None | |
.OUTPUTS | |
None, returns a date object. | |
.EXAMPLE | |
Find the second Tuesday of January 2020 | |
Get-XDayOfMonth -Find Second -Weekday Tuesday -Month 1 -Year 2020 | |
.EXAMPLE | |
Find the last Monday of July 2017 | |
Get-XDayOfMonth -Find Last -Weekday Monday -Month 7 -Year 2017 | |
.EXAMPLE | |
Find the first Friday of June 2020 | |
Get-XDayOfMonth -Find First -Weekday Friday -Month 6 -Year 2020 | |
#> | |
Param ( | |
[Parameter(Mandatory=$true)][ValidateSet("First","Second","Third","Fourth","Last","1","2","3","4","5")][string]$Find, | |
[Parameter(Mandatory=$true)][ValidateSet("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday")][string]$Weekday, | |
[Parameter(Mandatory=$true)][ValidateRange(1,12)][int]$Month, | |
[Parameter(Mandatory=$true)][ValidatePattern('^\d{4}$')][int]$Year | |
) | |
# Cast $Find to an integer so it's easy to work with. | |
switch ($Find) | |
{ | |
"First" { $intFind = 1 } | |
"Second" { $intFind = 2 } | |
"Third" { $intFind = 3 } | |
"Fourth" { $intFind = 4 } | |
"Last" { $intFind = 5 } | |
default { $intFind = [int]$Find } | |
} | |
# Find all days in the given month that match $Weekday | |
$allDays = @() | |
# There aren't 32 days in any month so we make sure we iterate through all days in a month | |
0..31 | ForEach-Object -Process { | |
$evaldate = (Get-Date -Year $Year -Month $Month -Day 1).AddDays($_) | |
if ($evaldate.Month -eq $Month) | |
{ | |
if ($evaldate.DayOfWeek -eq $Weekday) { | |
$alldays += $evaldate | |
} | |
} | |
} | |
#$allDays | FT | |
# If we found fewer matching days than we are seeking, subtract 1 from $intFind. | |
# For example, if there are only four Mondays in a month, not Five. | |
# Or for a really odd ready there are only three Fridays... or some other calendar oddity. | |
if ($allDays.Count -lt $intFind) { $intFind = $intFind-1 } | |
#Write-Host "The day you are looking for is $($allDays[$($intFind-1)])." | |
# Put the result on the PowerShell pipeline. | |
$allDays[$($intFind-1)] | |
Return | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you so much for sharing this function. I have some code that writes to a SharePoint site and we have noticed a time shift when writing dates. This Sunday will be the first DST change since implementing my code and I honestly have no idea if it will break, this function will allow me to create a date range that can determine if the offset I use needs to be changed. Living in Arizona we don't change time zones but where the servers are does, so this will be super helpful.
$StartDST = Get-XDayOfMonth -Find Second -Weekday Sunday -Month 3 -Year (get-Date).Year
$EndDST = Get-XDayOfMonth -Find First -Weekday Sunday -Month 11 -Year (get-Date).Year