-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathFind-Weekday.ps1
119 lines (104 loc) · 3.27 KB
/
Find-Weekday.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<#
.Synopsis
Determines the previous or next date from the current or imported date.
.DESCRIPTION
Calulates a date based on a start date, a day of the week, and an offset in weeks.
.EXAMPLE
Find the next Monday after today.
Find-Weekday -Date (Get-Date) -DayOfWeek Mon
.EXAMPLE
Find the last Monday before today.
Find-Weekday -Date (Get-Date) -DayOfWeek Mon -Backwards
.EXAMPLE
Find the next Friday that isn't a holiday, as defined by an external file.
Find-Weekday -Date (Get-Date) -DayOfWeek Friday -ExcludeHolidays (
Get-Content c:\temp\holidays.txt)
.EXAMPLE
Find the next or last weekday.
PS > $SomeDate
Friday, July 30, 2021 10:48:12 PM
PS > $SomeDate | Find-Weekday -Next
Monday, August 2, 2021 10:48:12 PM
PS > $SomeDate | Find-Weekday -Last
Thursday, July 29, 2021 10:48:12 PM
#>
function Find-Weekday
{
[CmdletBinding(DefaultParameterSetName='AnyWeekday')]
[OutputType([datetime])]
Param
(
# The date from which to start the find
[Parameter(ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true,
ValueFromRemainingArguments=$false,
Position=0)]
[ValidateNotNull()]
[ValidateNotNullOrEmpty()]
[datetime]
[Alias('ReportDate','Last_Start','Next_Start')]
$Date,
# Day of week to find, any in the past or future
[Parameter(Mandatory=$true,
Position=1,
ParameterSetName='AnyWeekday')]
[ValidateSet(
'Sunday', 'Monday', 'Tuesday', 'Wednesday',
'Thursday', 'Friday', 'Saturday','Sun',
'Mon', 'Tue', 'Tues', 'Wed', 'Weds',
'Thu', 'Thur', 'Thurs', 'Fri', 'Sat'
)]
[string]
$DayOfWeek,
# Look in the past (neg) direction
[Parameter(ParameterSetName='AnyWeekday')]
[switch]
$Backwards=$false,
# Find the next weekday in the future
[Parameter(ParameterSetName='NextWeekday')]
[switch]
$Next,
# Find the last weekday in the past
[Parameter(ParameterSetName='LastWeekday')]
[switch]
$Last,
# A collection of more dates of which to exclude
[datetime[]]
$ExcludeHolidays
)
Begin
{
}
Process
{
if($PSCmdlet.ParameterSetName -eq 'AnyWeekday'){
$UpOrDown = if($Backwards){-1}else{1}
Do{
$Date = $Date.AddDays($UpOrDown)
}until(
($DayOfWeek -like
"$(([regex]::Match((($Date).DayOfWeek),'...')).value)*"
) -and
($ExcludeHolidays -notcontains $Date)
)
}elseif($PSCmdlet.ParameterSetName -eq 'NextWeekday'){
Do{
$Date = $Date.AddDays(1)
}until(
($ExcludeHolidays -notcontains $Date) -and
(@('Saturday','Sunday') -notcontains ($Date).DayOfWeek)
)
}elseif($PSCmdlet.ParameterSetName -eq 'LastWeekday'){
Do{
$Date = $Date.AddDays(-1)
}until(
($ExcludeHolidays -notcontains $Date) -and
(@('Saturday','Sunday') -notcontains ($Date).DayOfWeek)
)
}
}
End
{
$Date
}
}