一年間分の水曜日を指定したい(とか

こんにちは、エス・ワイ・シーの松本です。
新年明けましておめでとうございます。本年も何卒よろしくお願いいたします。

バックアップ・ソリューションや、バッチ処理系などを実装していると、ジョブの実行スケジュールを設定しますね。
これらのスケジュール設定が需要な製品なんかに実装されているスケジュール設定画面では、かなり細かく設定できたりしておおよそ困ることはないと思います。

で、どんなものにもこれらの高度なスケジューラーが実装されていれば問題ないのですが、あるソリューションの主機能がスケジュールジョブ構成に左右されない場合、そのソリューションそのもののバックアップ機能などで設定できるスケジューラーが実にかゆいところに手が届かない時があります。

あるいは、コマンドラインベースでジョブ設定しないといけない時に、毎週金曜日とかにしたいのだけれど指定できるのは日付だけで、曜日指定とかできないとか。

ある日自分が遭遇した製品のスケジューラーは、毎週土曜日、または日曜日 はチェックボックスで指定できるのに、水曜日やら木曜日やら他の曜日は指定できず、その曜日に動かしたい場合に日付を列挙した CSV を差し込むしかない、というちょっと切ない実装でした。

そんな時、皆様どうされておりますでしょうか。
簡易的に思いつくのは、Excel で指定曜日の日付を2・3個書いてオートフィルなんかでずばばーっと1年分準備してみるか、とかですかね。
でもなかなかどうして、自分が操作できるのが構築対象サーバー OS だけだった場合とかに、Excel なんて入ってないわけですよ。
絶望に沈みますよね。

そんな時、もしも該当サーバーがインターネット通信できたりするなら、もしかするとワンチャンあります。

PowerShell を管理者モードで起動し、
Install-Module SHIMSOFT-Holidays
または、
Save-Module SHIMSOFT-Holidays -Path C:\tool\
等として指定パスに保存します。

Install-Module でインストールした場合は
Import-Module SHIMSOFT-Holidays
Save-Module で保存した場合は
Import-Module C:\tool\SHIMSOFT-Holidays\2.2\SHIMSOFT-Holidats.psd1
※ 2.2 のところはモジュールバージョン値になると思いますので、適宜変更してください。

で利用可能になります。

とにかく日付列挙した情報が欲しいときには以下のコマンドを利用します。

Get-NextWeekDay


使用例1 次の金曜日の日付を知りたい。
PS> Get-Date
2020年12月15日 19:10:41

PS> Get-NextWeekDay -NextWeekDay Friday
2020/12/18

2020/12/15 に実行したので、次の金曜日は 18日。

使用例2 2021年1月中の水曜日を列挙したい。

PS> Get-NextWeekDay -From 2021/1/1 -To 2021/1/31 -NextWeekDay Wednesday
2021/01/06
2021/01/13
2021/01/20
2021/01/27

お気づきでしょうか。
1年間分をれきょしたい場合 -To オプションの終了日 12/31 にすればいいのです。
また、この列挙された日付はリダイレクトでテキストファイルに落とし込むことができます。

使用例 3
PS> Get-NextWeekDay -From 2021/1/1 -To 2021/12/31 -NextWeekDay Wednesday > Year2021_Wed.txt


なお、PowerShell ですので、必要な場合テキストファイルに入れず、直接配列変数として代入することもできます。

使用例 4
PS> $wed = Get-NextWeekDay -From 2021/1/1 -To 2021/12/31 -NextWeekDay Wednesday
PS> $wed.count
52
PS> $wed[0]
2021/01/06
PS> $wed[10]
2021/03/17

もしかすると、ジョブが何らかのバックアップ的な動作で、2世代バックアップなので隔週の水曜日(2週間おきの水曜日)が欲しいという気分の時もあるかもしれません。

そんな時、以下のようなオプションを追加します。
-IntervalWeeks 2

使用例 5
PS> $wed = Get-NextWeekDay -From 2021/1/1 -To 2021/12/31 -NextWeekDay Wednesday -IntervalWeeks 2
PS> $wed.count
26
PS> $wed[0..4]
2021/01/06
2021/01/20
2021/02/03
2021/02/17
2021/03/03

一つだけ注意ポイントがあります。
Get-NextWeekDay は「次の○曜日」を得るコマンドですので、2021年1月の金曜日を列挙したい時に以下のようにすると、、、

使用例 6
PS> Get-NextWeekDay -From 2021/1/1 -To 2021/1/31 -NextWeekDay Friday
2021/01/08
2021/01/15
2021/01/22
2021/01/29

2021年1月1日は金曜日なのですが開始日当日なので結果セットに含まれないのです。
そんな懸念がある場合、以下のオプションを追加します。
-AllowSameDate

使用例 7
PS> Get-NextWeekDay -From 2021/1/1 -To 2021/1/31 -NextWeekDay Friday -AllowSameDate
2021/01/01
2021/01/08
2021/01/15
2021/01/22
2021/01/29

2021/1/1 が含まれるようになりました。


それはさておき、モジュール名が SHIMSOFT-Holidays なのに曜日のリスト列挙してるだけなのに何か疑問を持ってしまうかもしれないですね??

そんな時、以下のコマンドを使います。
Get-Holidays

使用例 8
PS> Get-Holidays -Year 2021

HolidayName Holiday Substitute
———– ——- ———-
元日 2021/01/01 2021/01/01
成人の日 2021/01/11 2021/01/11
建国記念の日 2021/02/11 2021/02/11
天皇誕生日(令和) 2021/02/23 2021/02/23
春分の日 2021/03/20 2021/03/20
昭和の日 2021/04/29 2021/04/29
憲法記念日 2021/05/03 2021/05/03
みどりの日 2021/05/04 2021/05/04
こどもの日 2021/05/05 2021/05/05
海の日 2021/07/22 2021/07/22
スポーツの日 2021/07/23 2021/07/23
山の日 2021/08/08 2021/08/09
敬老の日 2021/09/20 2021/09/20
秋分の日 2021/09/23 2021/09/23
スポーツの日 2021/10/11 2021/10/11
文化の日 2021/11/03 2021/11/03
勤労感謝の日 2021/11/23 2021/11/23

日本の祝日だけですが、列挙されます。
Holiday 列の値は「祝日」の日、「Substitute」は振替休日など適用後の実際の休日の日。

2021年の「山の日」は東京オリンピックに合わせて 2021年8月8日に移動することが決定されました。
だがしかし、8月8日は日曜になので、8月9日月曜日が振替休日になります。

そんな感じです。

企業カレンダーを想定した場合に、よくあるのが 5月1日は祝日でもないけれど メーデーという名の休業日、という場合、これをカスタムな休日として定義を足すこともできますが、ちょっと長くなったのでこの辺でやめておきます。