最近,我不得不在Powershell中解决此问题,那里的迭代或简单的复杂解决方案的数量让我感到震惊。这个问题的核心是简单的公式:
所需日历日= 7(周数)+ DOW-DOW(所需月份的第一个月)
正如我在下面说明的那样,然后将这个数字与想要获取日期的年和月一起使用。
简单的解析解决方案比迭代解决方案的执行速度要快得多,并且通常不那么“古怪”,因为您可以完全理解该过程(即在开始编写代码之前公式应该是正确的)。
这是我提供的解决方案。希望对您有所帮助。
<# Find nth instance of a weekday in a given month
* PROJECT ID: WeekdayInstance
* PURPOSE:
This function calculates the dateTime of the nth instance of a given weekday [i.e. in {Sun .. Sat}] in a given month
* FILE: Created: 04 Jun 2019 @ 14:57
*
* author John S. Abraham
* copyright SysBuild Inc. 2019
#>
<#
Parameters:
dow0 "Desired WeekDay": Value in {0..6}
wk0 "Desired Week in Month" : Value in {0..4}
date0 "A date in the desired month": datetime
rValue "Date of desired day": String
Process:
Calculate dow1 "Weekday of the first of the month of date0": Value in {0..6}
Calulate rValue = wk0 * 7 +(dow0 + 1) - dow1
return rValue
#>
<# WORK LOG
[20190704, jsa]: RQ, Design, and Initiate Construction
#>
Function Get-InstanceofDOW{
[CmdletBinding()]
param(
[parameter(Mandatory=$True, ValueFromPipelineByPropertyName, HelpMessage="Enter the desired Day of Week as a number (Sun=0 .. Sat=6)")]
[ValidateRange(0, 6)]
[int] $dow0,
[parameter(Mandatory=$True, ValueFromPipelineByPropertyName, HelpMessage="Enter the ordinal number of the desired week within the month")]
[ValidateRange(0, 4)]
[int]$wk0,
[parameter(Mandatory=$True, ValueFromPipelineByPropertyName, HelpMessage="Enter a date within the desired month")]
[System.DateTime]$date0
)
Process{
$dateFirstofMonth = Get-Date -Year $date0.Year -Month $date0.Month -Day 01
$dow1 = $dateFirstofMonth.DayOfWeek
$dayInstance = 7 * $wk0 + ($dow0+1) -$dow1
$rValue = Get-Date -Year $date0.Year -Month $date0.Month -Day $dayInstance
}
End {
<# Output as a string with no time component, since time is not relavant #>
$culture = Get-Culture
return $rValue.ToString($culture.DateTimeFormat.ShortDatePattern)
}
}
<# TEST: Determine the second Saturday in DEC 2019 #>
Get-InstanceofDOW -dow0 6 -wk0 1 -date0 2019-12-30T13:23:56