日本の祝日というと、成人の日は1月第2月曜日、建国記念日は2月11日と、特定のルールや特定の日で決まります。しかしそういうルールでは決められない祝日が2つあります。それは春分の日と秋分の日です。この2つは国立天文台が毎年2月に暦要覧として官報で告示することで確定する祝日です。

ところで、コンピュータシステムでは祝日や休日、週末に通常とは異なるジョブを実行する場合があります。しかし祝日を自動的にロジックで確定させることはできない。そこで日付に依存する処理が必要なアプリケーションやシステムでは、何らかの形で祝日マスタや休業日マスタを個別に管理するのが一般的な実装です。

では、そこで使用する祝日マスタの更新で参照する一次情報は何を参照していますでしょうか?

通常の年ならば、壁掛けのカレンダーや卓上カレンダー、あるいはオンラインサービスのカレンダー記載の祝日情報を安易に使っても問題はありません。しかし2019年や2020年のように例外的な祝日や休日が存在する場合に、これらの情報はあてにならない場合があります。

たとえば、私のデスクの卓上カレンダーは2019年5月2日が休日として明示されていませんでしたので、マーカーで明示的に塗りつぶしておきました。

さすがに4月末〜5月上旬の10連休は、カレンダーに明示されていなくても10連休と認識しているでしょうけど、では2019年10月22日はどうでしょうか? Google Calendar の「日本の祝日」カレンダーでは、ある時点までは2019年10月22日が祝日として設定されていませんでした。この日は特例法によって今年限りの休日であり祝日であるにもかかわらず、です。(画像は2019年1月6日時点の状態。本記事の公開時点では更新されている)

つまり、参照するカレンダーが不適切だと、誤った情報をマスタに投入してしまう可能性があります。では、適切な一次情報はなにか、そしてその更新作業を省力化するためにシステム側でできることはないか、という観点で少し考えてみます。

一次情報としての祝日の情報はどこを見ればよい?

日本の祝日に関する事務は、内閣府大臣官房総務課が所掌しており、それは下記のページで公開されています。

https://www8.cao.go.jp/chosei/shukujitsu/gaiyou.html

したがって、祝日マスタの管理が必要なアプリケーションでは、このページの情報を利用するのが最適です。

アプリで祝日マスタの管理、どうやっていますか?

祝日マスタの管理は、一般的には「祝日マスタテーブルを作成し、閲覧、編集用のフォームからメンテナンスする」という実装が行われます。

しかし日本の祝日というのは案外多いので、一次情報が掲載されているページの内容をコピー&ペーストするのは、あまり楽しい作業ではありません。

これらを省力化するアイデアとしては、ロジックで決められるものだけは自動的に決定し、そうではない祝日だけを手作業で更新する、という方法が挙げられますが、この試みは例外が発生したときにうまくいきません。例えば2020年の体育の日(スポーツの日)は10月第2月曜日ではなく、7月24日になりますのでロジックで対応しようとすると矛盾が生じます。

ここで内閣府のウェブページをもう一度見返してほしいのですが、じつはこのサイトではCSV形式のファイルとして祝日一覧が公開されていますので、これを活用すれば祝日の日付をロジックで仮決めする必要もなく、もっとも信頼できる祝日マスタの一次情報として活用できます。

Delphi / C++Builder では祝日一覧のCSVをどう扱えばよいでしょうか?

Delphi / C++Builder で文字列処理を行う場合は TStringList を多用することが多く、CSV を扱う実装でもよく見かけます。

しかし、FireDAC でクラウドデータにアクセスできる、Enterprise Connectors を使うと、もっとたやすく扱えるようになるのです。

別のブログ記事でも紹介しているとおり、Enterprise Connectors のドライバの中には CSV ファイルを FireDAC からデータソースとして扱えるドライバがあります。これを用いて、翌年の祝日情報をSQLで絞り込んでみることにしましょう。

まず使うのはTFDConnectionです。TFDConnection は本来ならばRDBMSへの接続に使いますが、Enterprise Connectors をインストールすると、RDBMSではないさまざまなデータソースをTFDConnectionで扱えます。そして設定が必須のパラメータは下記3点です。ドライバIDは設定エディタにプルダウンメニューから選択しますので、実質的にはURIとOtherの2項目を設定すればよいのです。

パラメータ
ドライバID CDataCSV
URI ダウンロードしたCSVファイルのパス
Other charset=Shift-JIS



注意して欲しいのはCSVファイルの文字コードです。日本語環境でExcelなどの表計算ソフトで作成したCSVファイルの文字コードは一般的にShift-JISが用いられています。そして総務省のサイトで公開されているCSVファイルもShift-JISのファイルです。

Enterprise Connectors のCSVドライバはデフォルトの文字コードがUnicodeなのですが、文字コードの指定を Others のパラメータで charset=Shift-JIS と明示することでShift-JISのデータを正しく扱えます。

なお、URIにはURLを直接指定できますので、内閣府のページに掲載のURLを記述すれば、それを直接参照できます。しかし祝日データが意味的には間違いなく正確な一次情報だとしても、カラム名が毎年必ず同じ名称で供給されることが保証されてはいません。したがって、直接参照するのではなく、あくまでローカルファイルを参照するようにした上で、参照でエラーが生じた場合は適切に修正するというフローは必要と思います。

この接続設定でデータを参照するために、TFDQuery で次のようにクエリを記述すると来年(2020年)の祝日データが取得できます。

select * from CData.CSV."syukujitsu.csv"
where "国民の祝日・休日月日" >= '2020/01/01'


あとは、これを祝日マスタに反映させればよいわけです。ただし念のために目視確認は必要ですから、Gridで一旦表示した上で、それを祝日マスタにINSERTするように実装すればよいでしょう。

Google Drive などのクラウドストレージにもアクセスできます

Enterprise Connectors CSVコネクタのオンラインドキュメントhttp://cdn.cdata.com/help/RVD/fire/RSBCSV_p_URI.htm を見ると、接続設定は次のように作成でき、ローカルファイルやHTTP接続以外のさまざまなクラウドストレージがサポートされていることがわかります。

ただしこの接続例は CData 社のオリジナル製品の接続文字列が例示されていることに注意してください。Enterprise Connectors の場合はこのように記述するかわりに対応するパラメータを探して設定します。たとえば Google Drive を利用する場合は URI を gdrive:// と設定の上、さらに InitialOAuth や OAuthClientId、OAuthClientSecret を設定することで利用可能となります。

まとめ

実際に稼働中の業務システムで、こういう対応のためにシステムを改修することはしないかもしれません。しかし、Delphi / C++Buidler で今後開発するアプリケーションでの外部連携の際にCSVの利用が必要な場合は、Enterprise Connectors CSV Driver を利用すると手間なく実装できることが理解いただけたと思います。

今回の例ではWebサーバ上のCSVファイルをダウンロードして利用してみましたが、CSVドライバはデータフォーマットの一意性に問題がなければURLを直接参照できますし、Amazon S3やGoogle Driveなどのクラウドストレージも直接利用できます。

そしてもちろん、その他のクラウドサービスとも連携できる、多くのドライバがあり、これらを組み合わせれば様々な連携のために手間がとられることがなく、本来開発したい機能にリソースを注力できるようになります。

Enterprise Connectors については2019年1月31日に開催されましたクラウド実践対応セミナー」でも説明しております(オンデマンドでご覧頂けます)ので、そちらも合わせてご視聴ください。またEnterprise Connectorsのトライアル版利用をご希望の場合は製品ページよりお申し込みください。

Anonymous