Advent Calendar 初参加です。
Calendar にかけて、前回書いた記事「日本の祝日を判定するBashスクリプトを書いた件」を PowerShell で焼き直してみました。
日本の祝日情報をどこから貰うか
Bash版同様、内閣府のホームページから持ってきます。
Invoke-WebRequest
がcurl
に相当するコマンドレットですが、PowerShellの入出力はすべて .NET のクラスオブジェクトなので、画面で確認するなら次のようになります。
(Invoke-WebRequest https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv).Content
国民の祝日・休日月日,国民の祝日・休日名称
1955/1/1,元日
1955/1/15,成人の日
1955/3/21,春分の日
1955/4/29,天皇誕生日
:
2020/7/24,スポーツの日
2020/8/10,山の日
2020/9/21,敬老の日
2020/9/22,秋分の日
2020/11/3,文化の日
2020/11/23,勤労感謝の日
PowerShellスクリプト
仕様はBash版を踏襲しています。つまり、祝日ファイルをローカルにキャッシュし、古くなったら内閣府のサーバから取り直します。
確実に祝日と言える場合のみ、終了ステータスに 0 がセットされる点も同様です。
Bash版と比べてみると、言語の特徴が見えて面白いかもしれません。
###############################################################
# 本邦休日判定スクリプト
# @author MindWood
# @param チェック日付を yyyymmdd で指定。省略すると今日を仮定
# @return 0 ... 確実に祝日
# 1 ... おそらく平日
# 上記以外 ... エラー
###############################################################
# 引数チェック
Param($DateStr = (Get-Date).ToString('yyyyMMdd'))
try {
$CheckDate = [DateTime]::ParseExact($DateStr, 'yyyyMMdd', $null)
} catch {
echo 'Invalid argument'
exit 255
}
$CachePath = 'C:\tmp' # 内閣府提供の祝日ファイルをキャッシュするディレクトリ
$HolidayFile = Join-Path $CachePath holiday.csv # 祝日登録ファイル名
$Limit = (Get-Date).AddMonths(-3) # 3ヶ月以上前は古い祝日登録ファイルとする
# 祝日登録ファイルが無い、もしくは祝日登録ファイルの更新日が古くなった場合、再取得する
if (! (Test-Path $HolidayFile) -or $Limit -gt (Get-ItemProperty $HolidayFile).LastWriteTime) {
try {
Invoke-WebRequest https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv -OutFile $HolidayFile
} catch {
echo $_.Exception.Message
exit 250
}
}
# 祝日として登録されていれば 0 を返却して終了(※祝日情報はyyyy/M/d形式で返る)
if (Select-String -Quiet ((Get-Date $CheckDate).ToString('yyyy/M/d') + ',') $HolidayFile) {
exit 0
}
# 土日なら 0 を返却して終了
$DayOfWeek = (Get-Date $CheckDate).DayOfWeek
if ($DayOfWeek -in @('Saturday', 'Sunday')) {
exit 0
}
# 年末年始(12月31日~1月3日)なら 0 を返却して終了
$MMDD = (Get-Date $CheckDate).ToString('MMdd')
if ($MMDD -eq '1231' -or $MMDD -le '0103') {
exit 0
}
# 上記いずれでもなければ平日として終了
exit 1
このスクリプトで、2019年12月26日から2020年1月16日までの平日を表示させると、次のようになります。
for ($date = '20191226'; $date -lt '20200116'; $date = [DateTime]::ParseExact($date, 'yyyyMMdd', $null).AddDays(1).ToString('yyyyMMdd')) {
.\check_holiday.ps1 $date
if (! $?) {
echo "$date は恐らく平日です"
}
}
20191226 は恐らく平日です
20191227 は恐らく平日です
20191230 は恐らく平日です
20200106 は恐らく平日です
20200107 は恐らく平日です
20200108 は恐らく平日です
20200109 は恐らく平日です
20200110 は恐らく平日です
20200114 は恐らく平日です
20200115 は恐らく平日です
なお、PowerShellでも $?
で直前のコマンド終了ステータスを取得できますが、成功したか(0:True)失敗したか(0以外:False)のブール値で返るので注意が必要。失敗した理由まで知るには$LastExitCode
を評価すると良いです。
平日に必ず実行させるジョブがある場合、Falseかどうかだけ見れば良いことになります。