SHIMSOFT-Holidays.psm1
$SupportedDate ="2020 年12月" function Get-NextWeekDay { <# .SYNOPSIS 指定日を基準に次ぎの指定曜日を算出します。 .DESCRIPTION 指定日を基準に次ぎの指定曜日を算出します。 .EXAMPLE Get-NextWeekDay -From (Get-Date -Format "yyyy/MM/dd") -NextWeekDay Monday .EXAMPLE Get-NextWeekDay -From "2018/2/17" -BeforeWeekDay Monday .EXAMPLE Get-NextWeekDay -From "2018/2/17" -NextWeekDay Monday -IntervalWeeks 2 .EXAMPLE Get-NextWeekDay -From "2018/2/17" -NextWeekDay Monday -ListCount 10 .EXAMPLE Get-NextWeekDay -From "2018/2/17" -NextWeekDay Saturday -AllowSameDate .EXAMPLE Get-NextWeekDay -From "2018/2/17" -NextWeekDay Saturday -AllowSameDate -DateTime .LINK .NOTES .INPUTS パイプラインからの入力非対応です。 .OUTPUTS 文字列 #> param( [Parameter(Mandatory=$false,Position=1)] [String]$From=[string](Get-Date -Format "yyyy/MM/dd"), [Parameter(Mandatory=$false,Position=2)] [String]$To=$From, [Parameter(Mandatory=$false,Position=3)] [ValidateSet("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday")] [String]$NextWeekDay, [Parameter(Mandatory=$false,Position=3)] [ValidateSet("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday")] [String]$BeforeWeekDay, [Parameter(Mandatory=$false,Position=3)] [int]$IntervalWeeks=1, [Parameter(Mandatory=$false,Position=4)] [int]$ListCount=1, [Parameter(Mandatory=$false,Position=5)] [Switch]$AllowSameDate, [Parameter(Mandatory=$false,Position=6)] [Switch]$DateTime ) $WeekDays =@("sunday","monday","tuesday","wednesday","thursday","friday","saturday") Write-Debug ("From : {0} NextWeekDay : {1} BefreWeekDay : {2} IntervalWeeks : {3} ListCount : {4}" -f $From, $NextWeekDay, $BeforeWeekDay, $IntervalWeeks, $ListCount) $FromDate = Get-Date -Date $From $ToDate = Get-Date -Date $To Write-Debug ("FromDate {0}" -f $FromDate) $FromWeekDay = $WeekDays.IndexOf(([string]$FromDate.DayOfWeek).ToLower()) Write-Debug ("FromWeekDay {0}" -f $FromWeekDay) $DiffDays =0 $IntervalWeeks = $IntervalWeeks * 7 if ($BeforeWeekDay -ne "") { $BeforeTargetWeekDay = $WeekDays.IndexOf($BeforeWeekDay.ToLower()) $DiffDays = $BeforeTargetWeekDay - $FromWeekDay - [int]($BeforeTargetWeekDay -gt $FromWeekDay) * 7 - [int]($BeforeTargetWeekDay -eq $FromWeekDay) * 7 * [int](-not $AllowSameDate.IsPresent) Write-Debug ("BeforeTargetWeekDay : {0} DiffDays : {1}" -f $BeforeTargetWeekDay, $DiffDays) $IntervalWeeks = -$IntervalWeeks } if ($NextWeekDay -ne "") { $NextTargetWeekDay = $WeekDays.IndexOf($NextWeekDay.ToLower()) $DiffDays = $NextTargetWeekDay - $FromWeekDay + [int]($NextTargetWeekDay -lt $FromWeekDay) * 7 + [int]($NextTargetWeekDay -eq $FromWeekDay) * 7 * [int](-not $AllowSameDate.IsPresent) Write-Debug ("NextTargetWeekDay : {0} DiffDays : {1}" -f $NextTargetWeekDay, $DiffDays) } $DateList = @() if ($From -eq $To) { for ($i=0; $i -lt $ListCount ; $i++) { if ($DateTime -eq $False) { $DateList += Get-Date $FromDate.AddDays($DiffDays + $IntervalWeeks * $i) -Format "yyyy/MM/dd" } else { $DateList += Get-Date $FromDate.AddDays($DiffDays + $IntervalWeeks * $i) } } } else { if ($FromDate -lt $ToDate) { $StartDate = $FromDate; $EndDate= $ToDate } else { $StartDate = $ToDate; $EndDate= $FromDate } $i=0; Do { if ($DateTime -eq $False) { $DateList += Get-Date $FromDate.AddDays($DiffDays + $IntervalWeeks * $i) -Format "yyyy/MM/dd" } else { $DateList += Get-Date $FromDate.AddDays($DiffDays + $IntervalWeeks * $i) } $i++ } until ($StartDate -gt $DateList[($i-1)] -or $EndDate -lt $DateList[($i-1)]) $DateList = $DateList[0..($DateList.Count -2)] } $DateList } function Reset-HolidaysTemplate { <# .SYNOPSIS 祝日テンプレートを初期化します。 .DESCRIPTION 祝日テンプレートを Default に初期化します。 祝日テンプレートに追加設定していた情報は失われます。 -Default オプションを指定し、ハードコードされている祝日テンプレートに初期化する場合、 2020 年12月現在制定されている祝日情報に対応します。対応している祝日は以下の通りです。 元日 成人の日 建国記念の日 春分の日 昭和の日 憲法記念日 みどりの日 こどもの日 海の日 山の日 敬老の日 秋分の日 体育の日/スポーツの日 文化の日 勤労感謝の日 天皇誕生日 ※ 2019年 5月 1日 新天皇即位 ※ 2019年 10月 22日 即位礼正殿の儀 .EXAMPLE Reset-HolidaysTemplate 祝日テンプレートを Default テンプレートに初期化します。 .EXAMPLE Reset-HolidaysTemplate -Default 祝日 Default テンプレートをハードコードされている祝日テンプレートに初期化します。 .LINK .NOTES .INPUTS パイプラインからの入力非対応です。 .OUTPUTS 文字列 #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingWriteHost", "", Justification="I like write-host.")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingInvokeExpression", "", Justification="Requirement this function.")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "", Justification="Affected this module using XML file only.")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseDeclaredVarsMoreThanAssignments", "Year", Justification="Year variable used only object displayed.")] param( [Parameter(Mandatory=$false,Position=1)] [Switch]$Default, [Parameter(Mandatory=$false,Position=1)] [Switch]$PublicHoliday, [Parameter(Mandatory=$false,Position=1)] [Switch]$Custom ) if ($Default -eq $True) { $HolidayNames = @( "元日", "成人の日", "建国記念の日", "春分の日", "昭和の日", "憲法記念日", "みどりの日", "こどもの日", "海の日", "山の日", "敬老の日", "秋分の日", "体育の日", "文化の日", "勤労感謝の日", "天皇誕生日(平成)", "スポーツの日", "スポーツの日", "海の日", "山の日", "天皇誕生日(昭和)", "天皇誕生日(令和)", "成人の日", "海の日", "敬老の日", "体育の日", "新天皇即位(令和)", "即位礼正殿の儀(令和)", "スポーツの日", "海の日", "山の日" ) $StartEndDate = @( # 元日 @("1900/01/01","3000/01/01"), # 成人の日 @("2000/01/01","3000/01/01"), # 建国記念の日 @("1966/01/01","3000/01/01"), # 春分の日 @("1948/01/01","3000/01/01"), # 昭和の日 @("1989/01/01","3000/01/01"), # 憲法記念日 @("1948/01/01","3000/01/01"), # みどりの日 @("2007/01/01","3000/01/01"), # こどもの日 @("1948/01/01","3000/01/01"), # 海の日 @("2003/01/01","3000/01/01"), # 山の日 @("2016/01/01","3000/01/01"), # 敬老の日 @("2003/01/01","3000/01/01"), # 秋分の日 @("1948/01/01","3000/01/01"), # 体育の日 @("2000/01/01","2019/12/31"), # 文化の日 @("1946/11/03","3000/01/01"), # 勤労感謝の日 @("1948/01/01","3000/01/01"), # 天皇誕生日(平成) @("1989/01/01","2019/12/31"), # スポーツの日 / 東京オリンピック2020 @("2020/01/01","2020/12/31"), # スポーツの日 @("2021/01/01","3000/01/01"), # 海の日 / 東京オリンピック2020 @("2020/01/01","2020/12/31"), # 山の日 / 東京オリンピック2020 @("2020/01/01","2020/12/31"), # 天皇誕生日(昭和) @("1949/01/01","1988/12/31"), # 天皇誕生日(令和) @("2020/01/01","3000/01/01"), # 成人の日 @("1948/01/01","1999/12/31"), # 海の日 @("1996/01/01","2002/12/31"), # 敬老の日 @("1948/01/01","2002/12/31"), # 体育の日 @("1966/01/01","1999/12/31"), # 新天皇即位(令和) @("2019/01/01","2019/12/31"), # 即位礼正殿の儀(令和)" @("2019/01/01","2019/12/31"), # スポーツの日 / 東京オリンピック2021 @("2021/01/01","2021/12/31"), # 海の日 / 東京オリンピック2021 @("2021/01/01","2021/12/31"), # 山の日 / 東京オリンピック2021 @("2021/01/01","2021/12/31") ) $HolidayExpressions = @( # 元日 'Get-Date -Date ($Year + "/1/1")', # 成人の日 'Get-Date -Date(Get-NextWeekDay -From ($Year + "/1/14") -BeforeWeekDay Monday -AllowSameDate)', # 建国記念の日 'Get-Date -Date ($Year + "/2/11")', # 春分の日 ('Get-Date -Date (Get-Date -Date ($Year + "/3/23")).AddDays(-(Invoke-Expression ' + "`'" + '$a=@(@(0,1900,1960,2092),@(0,1901,1933),@(0,1902,2026),@(1903,1927,2059))[($Year%4)];$a.IndexOf(($a -le $Year | Sort-Object -Descending)[0])+1' + "`'))"), # 昭和の日 'Get-Date -Date ($Year + "/4/29")', # 憲法記念日 'Get-Date -Date ($Year + "/5/3")', # みどりの日 'Get-Date -Date ($Year + "/5/4")', # こどもの日 'Get-Date -Date ($Year + "/5/5")', # 海の日 'Get-Date -Date (Get-NextWeekDay -From ($Year + "/7/21") -BeforeWeekDay Monday -AllowSameDate)', # 山の日 'Get-Date -Date ($Year + "/8/11")', # 敬老の日 'Get-Date -Date (Get-NextWeekDay -From ($Year + "/9/21") -BeforeWeekDay Monday -AllowSameDate)', # 秋分の日 ('Get-Date -Date (Get-Date -Date ($Year + "/9/25")).AddDays(-(Invoke-Expression ' + "`'" + '$a=@(@(0,1900,2012),@(1901,1921,2045),@(1902,1950,2078),@(1903,1983))[($Year%4)];$a.IndexOf(($a -le $Year | Sort-Object -Descending)[0])+1' + "`'))"), # 体育の日 'Get-Date -Date (Get-NextWeekDay -From ($Year + "/10/14") -BeforeWeekDay Monday -AllowSameDate)', # 文化の日 'Get-Date -Date ($Year + "/11/3")', # 勤労感謝の日 'Get-Date -Date ($Year + "/11/23")', # 天皇誕生日(平成) 'Get-Date -Date ($Year + "/12/23")', # スポーツの日 / 東京オリンピック2020 'Get-Date -Date ($Year + "/7/24")', # スポーツの日 'Get-Date -Date (Get-NextWeekDay -From ($Year + "/10/14") -BeforeWeekDay Monday -AllowSameDate)' # 海の日 / 東京オリンピック2020 'Get-Date -Date ($Year + "/7/23")', # 山の日 / 東京オリンピック2020 'Get-Date -Date ($Year + "/8/10")', # 天皇誕生日(昭和) 'Get-Date -Date ($Year + "/4/29")', # 天皇誕生日(令和) 'Get-Date -Date ($Year + "/2/23")', # 成人の日 'Get-Date -Date ($Year + "/1/15")', # 海の日 'Get-Date -Date ($Year + "/7/20")', # 敬老の日 'Get-Date -Date ($Year + "/9/15")', # 体育の日 'Get-Date -Date ($Year + "/10/10")', # 新天皇即位(令和) 'Get-Date -Date ($Year + "/5/01")', # 即位礼正殿の儀(令和)" 'Get-Date -Date ($Year + "/10/22")', # スポーツの日 / 東京オリンピック2021 'Get-Date -Date ($Year + "/7/23")', # 海の日 / 東京オリンピック2021 'Get-Date -Date ($Year + "/7/22")', # 山の日 / 東京オリンピック2021 'Get-Date -Date ($Year + "/8/8")' ) $HolidaysTemplate = @() for ($i = 0; $i -lt $HolidayNames.Count;$i++) { $Holiday = New-Object PSObject $Holiday | Add-Member -MemberType NoteProperty -Name HolidayName -Value ($HolidayNames[$i]) $Holiday | Add-Member -MemberType NoteProperty -Name HolidayID -Value $i $Holiday | Add-Member -MemberType ScriptProperty -Name Date -Value { $Year = [string](Get-Date).Year; Invoke-Expression ($this.Expression) } $Holiday | Add-Member -MemberType NoteProperty -Name Expression -Value ($HolidayExpressions[$i]) $Holiday | Add-Member -MemberType NoteProperty -Name Type -Value "PublicHoliday" $Holiday | Add-Member -MemberType NoteProperty -Name SubstituteEnable -Value ($True) $Holiday | Add-Member -MemberType NoteProperty -Name IsCustom -Value ($False) $Holiday | Add-Member -MemberType NoteProperty -Name Locale -Value ("Japan") $Holiday | Add-Member -MemberType NoteProperty -Name StartDate -Value (Get-Date ($StartEndDate[$i][0])) $Holiday | Add-Member -MemberType NoteProperty -Name EndDate -Value (Get-Date ($StartEndDate[$i][1])) $HolidaysTemplate += $Holiday } $HolidaysTemplate | Export-CliXml -Path $PSScriptRoot\HolidaysTemplate-Default.xml Write-Host ("HolidaysTemplate-Default.xml を初期値で再生成しました。{0}以降に制定された祝日には対応していません。" -f $SupportedDate) } if ($PublicHoliday -eq $True) { if ((Test-Path -Path $PSScriptRoot\HolidaysTemplate-Default.xml) -eq $False) { Reset-HolidaysTemplate -Default } else { $HolidaysTemplate = Import-CliXml -Path $PSScriptRoot\HolidaysTemplate-Default.xml $HolidaysTemplate | Export-CliXml -Path $PSScriptRoot\HolidaysTemplate.xml Write-Host "HolidaysTemplate.xml を Default で初期化しました。" } } if ($Custom -eq $True) { if ((Test-Path -Path $PSScriptRoot\HolidaysTemplate-Custom.xml) -eq $True) { Copy-Item -Path $PSScriptRoot\HolidaysTemplate-Custom.xml -Destination $PSScriptRoot\HolidaysTemplate-Custom-Backup.xml Remove-Item -Path $PSScriptRoot\HolidaysTemplate-Custom.xml Write-Host "HolidaysTemplate-Custom.xml を 削除しました。" } } } function Get-Holidays { <# .SYNOPSIS 祝日テンプレートから指定年の祝日一覧を算出します。 .DESCRIPTION 祝日テンプレートから指定年の祝日一覧を算出します。 祝日日程が 日曜日 である場合、振り替え休日も算出され ActualDate に出力されます。 Date = 祝日の日 ActualDate = 祝日の日、または振り替え休日 .EXAMPLE Get-Holidays .EXAMPLE Get-Holidays -Year "2018" .EXAMPLE Get-Holidays -Year "2018" -IncludeCustom .EXAMPLE Get-Holidays -Year "2018" -OnlyCustom .LINK .NOTES .INPUTS パイプラインからの入力非対応です。 .OUTPUTS 文字列 #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingInvokeExpression", "", Justification="Requirement this function.")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] param( [Parameter(Mandatory=$false,Position=1)] [String]$Year=[string]((Get-Date).Year), [Parameter(Mandatory=$false,Position=2)] [Switch]$IncludeCustom, [Parameter(Mandatory=$false,Position=1)] [Switch]$OnlyCustom ) if ((Test-Path -Path $PSScriptRoot\HolidaysTemplate.xml) -eq $False) { Reset-HolidaysTemplate -PublicHoliday } $HolidaysTemplate = @(Import-CliXml -Path $PSScriptRoot\HolidaysTemplate.xml) if ($IncludeCustom -and (Test-Path -Path $PSScriptRoot\HolidaysTemplate-Custom.xml) -eq $True) { $HolidaysTemplate += @(Import-CliXml -Path $PSScriptRoot\HolidaysTemplate-Custom.xml) } if ($OnlyCustom) { if ((Test-Path -Path $PSScriptRoot\HolidaysTemplate-Custom.xml) -eq $True) { $HolidaysTemplate = @(Import-CliXml -Path $PSScriptRoot\HolidaysTemplate-Custom.xml) } else { break } } $Work = $HolidaysTemplate | Where-Object {$_.StartDate -le ($Year + "/1/1") -and $_.EndDate -ge ($Year + "/12/31")} | Group-Object -Property HolidayName $HolidaysTemplate = @() foreach ($W in $Work) { if ($W.Count -eq 1) { $HolidaysTemplate += $W.Group[0] } else { $HolidaysTemplate += $W.Group | Where-Object {$_.StartDate -eq ($W.Group | Measure-Object -Property StartDate -Maximum).Maximum } } } $Holidays = @() Foreach ($HT in $HolidaysTemplate) { $Work = New-Object PSObject $Work | Add-Member -MemberType NoteProperty -Name HolidayName -Value $HT.HolidayName $Work | Add-Member -MemberType NoteProperty -Name Date -Value (Invoke-Expression ($HT.Expression)) $Work | Add-Member -MemberType NoteProperty -Name ActualDate -Value (Invoke-Expression ($HT.Expression)) $Work | Add-Member -MemberType NoteProperty -Name IsSubstituted -Value $False $Work | Add-Member -MemberType NoteProperty -Name Type -Value $HT.Type $Work | Add-Member -MemberType NoteProperty -Name SubstituteEnable -Value $HT.SubstituteEnable $Work | Add-Member -MemberType NoteProperty -Name IsCustom -Value $HT.IsCustom $Work | Add-Member -MemberType NoteProperty -Name Locale -Value $HT.Locale $Work | Add-Member -MemberType ScriptProperty -Name Holiday -Value { Get-Date $this.Date -Format "yyyy/MM/dd" } $Work | Add-Member -MemberType ScriptProperty -Name Substitute -Value { Get-Date $this.ActualDate -Format "yyyy/MM/dd" } $defaultProperties = @("HolidayName","Holiday","Substitute") $defaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet("DefaultDisplayPropertySet",[string[]]$defaultProperties) $PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($defaultDisplayPropertySet) $Work | Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $PSStandardMembers $Holidays += $Work } Foreach ($HD in $Holidays) { if ($HD.SubstituteEnable -eq $True -and $HD.ActualDate.DayOfWeek -eq "Sunday") { $Substituted = $False Do { $HD.ActualDate = $HD.ActualDate.AddDays(1) $Work = @($Holidays | Where-Object {$_.ActualDate -eq $HD.AcrualDate -and $_.IsCustom -eq $False }) if ($Work.Count -eq 0 -and $HD.ActualDate.DayOfWeek -ne "Sunday") { $Substituted = $True; $HD.IsSubstituted = $True } } Until ($Substituted -eq $True) } } $Holidays = $Holidays | Sort-Object -Property ActualDate for ($i=1; $i -lt $Holidays.Count; $i++) { if ($Holidays[$i].Type -eq "PublicHoliday" -and $Holidays[($i-1)].Type -eq "PublicHoliday") { if (($Holidays[$i].ActualDate - $Holidays[($i-1)].ActualDate).Days -eq 2) { if ((($Holidays[($i-1)].ActualDate).AddDays(1)).DayOfWeek -ne "Sunday") { $Work = New-Object PSObject $Work | Add-Member -MemberType NoteProperty -Name HolidayName -Value "休日(挟まれた平日)" $Work | Add-Member -MemberType NoteProperty -Name Date -Value (($Holidays[($i-1)].ActualDate).AddDays(1)) $Work | Add-Member -MemberType NoteProperty -Name ActualDate -Value (($Holidays[($i-1)].ActualDate).AddDays(1)) $Work | Add-Member -MemberType NoteProperty -Name IsSubstituted -Value $False $Work | Add-Member -MemberType NoteProperty -Name Type -Value "CatchingHoliday" $Work | Add-Member -MemberType NoteProperty -Name SubstituteEnable -Value $False $Work | Add-Member -MemberType NoteProperty -Name IsCustom -Value $False $Work | Add-Member -MemberType NoteProperty -Name Locale -Value "Japan" $Work | Add-Member -MemberType ScriptProperty -Name Holiday -Value { Get-Date $this.Date -Format "yyyy/MM/dd" } $Work | Add-Member -MemberType ScriptProperty -Name Substitute -Value { Get-Date $this.ActualDate -Format "yyyy/MM/dd" } $defaultProperties = @("HolidayName","Holiday","Substitute") $defaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet("DefaultDisplayPropertySet",[string[]]$defaultProperties) $PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($defaultDisplayPropertySet) $Work | Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $PSStandardMembers $Holidays += $Work } } } } $Holidays | Sort-Object -Property ActualDate } function Add-CustomHoliday { <# .SYNOPSIS 祝日/休日定義を作成し、カスタムテンプレートに追加します。 .DESCRIPTION 祝日/休日定義を作成し、カスタムテンプレートに追加します。 以下に相当する一連の動きを行います。 $CHT = Get-HolidaysTemplate -TemplateType Custom $CHT += New-CustomHoliday -Name "メーデー" -Expression 'Get-Date -Date ($Year + "/5/01")' Update-HolidaysTemplate -CustomTemplate $CHT -TemplateType Custom .EXAMPLE Add-CustomHoliday -Name "メーデー" -Date "5/1" .LINK .NOTES .INPUTS パイプラインからの入力非対応です。 .OUTPUTS 文字列 #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingWriteHost", "", Justification="I like write-host.")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "", Justification="Create variable type of Object of HolidayTemplate style.")] param( [Parameter(Mandatory=$True,Position=1)] [String]$Name, [Parameter(Mandatory=$False,Position=2)] [String]$Date, [Parameter(Mandatory=$False,Position=2)] [String]$Expression, [Parameter(Mandatory=$false,Position=3)] [Switch]$SubstituteEnable, [Parameter(Mandatory=$false,Position=4)] [ValidateSet('Holiday','Anniversary','Event','PublicHoliday')] [String]$Type="Holiday", [Parameter(Mandatory=$false,Position=5)] [String]$Locale="Japan", [Parameter(Mandatory=$false,Position=6)] [String]$StartDate=(Get-Date -Format "yyyy/01/01"), [Parameter(Mandatory=$false,Position=7)] [String]$EndDate=(Get-Date -Format "yyyy/12/31") ) $LastDay = @(0,31.28.31,30,31,30,31,31,30,31,30,31) $Fail = $False $CHT = @(Get-HolidaysTemplate -TemplateType Custom) if ($null -eq $CHT[0]) { $CHT = @() } if ($Date -ne "") { if ($Date -match "^[0-9]+/[0-9]+$") { $Work = $Date.Split("/") if ([int]$Work[0] -ge 1 -and [int]$Work[0] -le 12 -and [int]$Work[1] -ge 1 -and [int]$Work[1] -le $LastDay[($Work[0])]) { $CH = New-CustomHoliday -Name $Name -Date $Date -SubstituteEnable:$SubstituteEnable -Type $Type -Locale $Locale -StartDate $StartDate -EndDate $EndDate } else { Write-Error "日付指定が異常です。 mm/dd で指定してください。" $Fail = $True } } else { Write-Error "日付指定が異常です。 mm/dd で指定してください。" $Fail = $True } } else { if ($Expression -ne "") { $CH = New-CustomHoliday -Name $Name -Expression $Expression -SubstituteEnable:$SubstituteEnable -Type $Type -Locale $Locale -StartDate $StartDate -EndDate $EndDate } else { Write-Error "-Date または -Expression オプションいずれかは必ず指定してください。" $Fail = $True } } # if ($CHT.HolidayName -contains $CH.HolidayName) { # Write-Error "既存の定義名と重複しています。別の名称を指定してください。" # $Fail = $True # } else { $CHT += $CH Update-HolidaysTemplate -CustomTemplate $CHT -TemplateType Custom # } if ($Fail -eq $False) { Write-Host "定義を追加しました。" $CH } } function Remove-CustomHoliday { <# .SYNOPSIS 指定された定義を、カスタムテンプレートから削除します。 .DESCRIPTION 指定された定義を、カスタムテンプレートから削除します。 .EXAMPLE Remove-CustomHoliday -Name "メーデー" .EXAMPLE Remove-CustomHoliday -ID "079621da-bcd3-48fc-ad35-d510d5ddecaa" .LINK .NOTES .INPUTS パイプラインからの入力非対応です。 .OUTPUTS 文字列 #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingWriteHost", "", Justification="I like write-host.")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "", Justification="Create variable type of Object of HolidayTemplate style.")] param( [Parameter(Mandatory=$False,Position=1)] [String]$Name, [Parameter(Mandatory=$False,Position=2)] [String]$ID ) $CHT = Get-HolidaysTemplate -TemplateType Custom $Removed = "" if ($Name -ne "" -and $CHT.HolidayName.IndexOf($Name) -ne -1) { $Removed = $CHT[($CHT.HolidayName.IndexOf($Name))] $CHT = $CHT | Where-Object {$_.HolidayName -ne $Name} if ($null -eq $CHT) { Reset-HolidaysTemplate -Custom } else { Update-HolidaysTemplate -CustomTemplate $CHT -TemplateType Custom } Write-Host "指定された定義をカスタムテンプレートから削除しました。" $Removed } if ($ID -ne "" -and $CHT.HolidayID.IndexOf($ID) -ne -1) { $Removed = $CHT[($CHT.HolidayID.IndexOf($ID))] $CHT = $CHT | Where-Object {$_.HolidayID -ne $ID} if ($null -eq $CHT) { Reset-HolidaysTemplate -Custom } else { Update-HolidaysTemplate -CustomTemplate $CHT -TemplateType Custom } Write-Host "指定された定義をカスタムテンプレートから削除しました。" $Removed } if ($Removed -eq "") { Write-Error ("指定された定義が見つかりませんでした。 {0}{1}" -f $Name,$ID) } } function New-CustomHoliday { <# .SYNOPSIS 祝日/休日定義を作成します。 .DESCRIPTION 祝日/休日定義を作成します。 祝日/休日定義の配列を構成し、Update-HolidaysTemplate のパラメータとしてカスタムな祝日定義テンプレートとして保存することが出来ます。 .EXAMPLE New-CustomHoliday -Name "メーデー" -Date "5/1" .EXAMPLE $CHT = Get-HolidaysTemplate $CHT += New-CustomHoliday -Name "メーデー" -Date "5/1" Update-HolidaysTemplate -CustomTemplate $CHT .LINK .NOTES .INPUTS パイプラインからの入力非対応です。 .OUTPUTS 文字列 #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingInvokeExpression", "", Justification="Requirement this function.")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "", Justification="Create variable type of Object of HolidayTemplate style.")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseDeclaredVarsMoreThanAssignments", "Year", Justification="Year variable used only object displayed.")] param( [Parameter(Mandatory=$True,Position=1)] [String]$Name, [Parameter(Mandatory=$False,Position=2)] [String]$Date, [Parameter(Mandatory=$False,Position=2)] [String]$Expression, [Parameter(Mandatory=$false,Position=3)] [Switch]$SubstituteEnable, [Parameter(Mandatory=$false,Position=4)] [ValidateSet('Holiday','Anniversary','Event','PublicHoliday')] [String]$Type="Holiday", [Parameter(Mandatory=$false,Position=5)] [String]$Locale="Japan", [Parameter(Mandatory=$false,Position=6)] [String]$StartDate=(Get-Date -Format "yyyy/01/01"), [Parameter(Mandatory=$false,Position=7)] [String]$EndDate=(Get-Date -Format "yyyy/12/31") ) $LastDay = @(0,31.28.31,30,31,30,31,31,30,31,30,31) $Fail = $False $Holiday = New-Object PSObject $Holiday | Add-Member -MemberType NoteProperty -Name HolidayName -Value ($Name) $Holiday | Add-Member -MemberType NoteProperty -Name HolidayID -Value ((New-Guid).Guid) $Holiday | Add-Member -MemberType ScriptProperty -Name Date -Value { $Year = [string](Get-Date).Year; Invoke-Expression ($this.Expression) } if ($Date -ne "") { if ($Date -match "^[0-9]+/[0-9]+$") { $Work = $Date.Split("/") if ([int]$Work[0] -ge 1 -and [int]$Work[0] -le 12 -and [int]$Work[1] -ge 1 -and [int]$Work[1] -le $LastDay[($Work[0])]) { $Holiday | Add-Member -MemberType NoteProperty -Name Expression -Value ('Get-Date -Date ($Year + "/{0}/{1}")' -f $Work[0],$Work[1]) } else { Write-Error "日付指定が異常です。 mm/dd で指定してください。" $Fail = $True } } else { Write-Error "日付指定が異常です。 mm/dd で指定してください。" $Fail = $True } } else { if ($Expression -ne "") { $Holiday | Add-Member -MemberType NoteProperty -Name Expression -Value ($Expression) } else { Write-Error "-Date または -Expression オプションいずれかは必ず指定してください。" $Fail = $True } } $Holiday | Add-Member -MemberType NoteProperty -Name Type -Value ($Type) $Holiday | Add-Member -MemberType NoteProperty -Name SubstituteEnable -Value ($SubstituteEnable) $Holiday | Add-Member -MemberType NoteProperty -Name IsCustom -Value ($True) $Holiday | Add-Member -MemberType NoteProperty -Name Locale -Value ($Locale) $Holiday | Add-Member -MemberType NoteProperty -Name StartDate -Value (Get-Date $StartDate) $Holiday | Add-Member -MemberType NoteProperty -Name EndDate -Value (Get-Date $EndDate) if ($Fail -eq $False) { $Holiday } } function Update-HolidaysTemplate { <# .SYNOPSIS 現在保存済みの祝日/休日定義を更新します。 .DESCRIPTION 現在保存済みの祝日/休日定義を更新します。 カスタムな祝日/休日定義を変更する場合に利用します。 -TemplateType "Custom" が既定の動作です。 新設された祝日の追加や、廃止された祝日の削除を反映したい場合は "PublicHolidays" を指定してください。 "Default" を指定することでデフォルトテンプレートを更新することが出来ます。 Reset-HolidaysTemplate では、"Default" テンプレートで "PublicHolidays" を上書きしてリセットします。 Reset-HolidaysTemplate -Default では、"Default" テンプレートを破棄して初期値を再生成し、 "PublicHolidays" を上書きします。 Get-Holidays では "PublicHolidays" テンプレートを使用します。 Get-Holidays -IncludeCustom では "PublicHolidays" と "Custom" テンプレートの複合結果が得られます。 .EXAMPLE Get-HolidaysTemplate .EXAMPLE Get-HolidaysTemplate -Default .EXAMPLE $CHT = Get-HolidaysTemplate $CHT += (New-CustomHoliday -Name "メーデー" -Expression 'Get-Date -Date ($Year + "/5/01")' ) Update-HolidaysTemplate -CustomTemplate $CHT .LINK .NOTES .INPUTS パイプラインからの入力非対応です。 .OUTPUTS 文字列 #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "", Justification="Affected this module using XML file only.")] param( [Parameter(Mandatory=$True,Position=1)] [Array]$CustomTemplate, [Parameter(Mandatory=$false,Position=2)] [ValidateSet('Custom','PublicHolidays','Default')] [String]$TemplateType="Custom" ) switch ($TemplateType) { "Custom" { $CustomTemplate | Export-Clixml -Path $PSScriptRoot\HolidaysTemplate-Custom.xml } "PublicHolidays" { $CustomTemplate | Export-Clixml -Path $PSScriptRoot\HolidaysTemplate.xml } "Default" { $CustomTemplate | Export-Clixml -Path $PSScriptRoot\HolidaysTemplate-Default.xml } } } function Get-HolidaysTemplate { <# .SYNOPSIS 現在保存済みの祝日/休日定義を参照します。 .DESCRIPTION 現在保存済みの祝日/休日定義を参照します。 カスタムな祝日/休日定義を変更する場合に利用します。 -Default オプションを使うとデフォルトテンプレートを参照できます。 .EXAMPLE Get-HolidaysTemplate .EXAMPLE Get-HolidaysTemplate -TemplateType PublicHolidays .EXAMPLE $CHT = Get-HolidaysTemplate $CHT += (New-CustomHoliday -Name "メーデー" -Expression 'Get-Date -Date ($Year + "/5/01")' ) Update-HolidaysTemplate -CustomTemplate $CHT .LINK .NOTES .INPUTS パイプラインからの入力非対応です。 .OUTPUTS 文字列 #> param( [Parameter(Mandatory=$false,Position=2)] [ValidateSet('Custom','PublicHolidays','Default')] [String]$TemplateType="Custom" ) switch ($TemplateType) { "Custom" { if ((Test-Path -Path $PSScriptRoot\HolidaysTemplate-Custom.xml) -eq $true) { $template = @(Import-Clixml -Path $PSScriptRoot\HolidaysTemplate-Custom.xml) } else { $template = $null } } "PublicHolidays" { if ((Test-Path -Path $PSScriptRoot\HolidaysTemplate.xml) -eq $true) { $template = @(Import-Clixml -Path $PSScriptRoot\HolidaysTemplate.xml) } else { Reset-HolidaysTemplate -Default $template = @(Import-Clixml -Path $PSScriptRoot\HolidaysTemplate.xml) } } "Default" { if ((Test-Path -Path $PSScriptRoot\HolidaysTemplate-Default.xml) -eq $true) { $template = @(Import-Clixml -Path $PSScriptRoot\HolidaysTemplate-Default.xml) } else { Reset-HolidaysTemplate -Default $template = @(Import-Clixml -Path $PSScriptRoot\HolidaysTemplate-Default.xml) } } } $template } Export-ModuleMember -Function Get-NextWeekDay, Reset-HolidaysTemplate, Get-Holidays, New-CustomHoliday, Get-HolidaysTemplate, Update-HolidaysTemplate, Add-CustomHoliday, Remove-CustomHoliday |