如何查找给定月份中某工作日的第n个实例(Powershell中的解析解决方案)

时间:2019-07-06 15:53:27

标签: powershell dayofweek date-difference

最近,我不得不在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 

0 个答案:

没有答案