指定された日が休日かどうかを調べないといけなくなったので、C#でクラスを作った。
土日かどうかはDateTime型に.DayOfWeekをつけて判定でくるのだが、日本の祝日を調べる方法はどうもないらしい。
C#で出来ないなら、カレンダーの祝日情報を引っ張ってきて判定したらいいじゃない?と思って調べたらGoogleが提供しているけどAPI keyが…とか言ってるらしくめんどくさい。
個人が提供しているweb serviceもあるけど、いつ辞めるかわかないのでちょっと使いにくい。
日本政府が翌年までの祝日のCSVを提供しているので、それを定期的に取得して、それをもとに判定することにした。
使い方
Holiday hday = new Holiday(); string sDateTime = "2020-09-22"; //秋分の日 if (hday.isHoliday(DateTime.Parse(sDateTime))) { Debug.WriteLine($"○ 日本の休日 {DateTime.Parse(sDateTime).ToString("yyyy-MM-dd (ddd)")}"); } else { Debug.WriteLine($"× 日本の休日 {DateTime.Parse(sDateTime).ToString("yyyy-MM-dd (ddd)")}"); }
Holidayクラス本体
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using Microsoft.VisualBasic.FileIO; using System.Net; using System.Diagnostics; using System.Collections.Specialized; using Microsoft.VisualBasic.ApplicationServices; namespace HolidayApp { //休業日かどうかを調べるクラス // 日付を指定されたら、その日が休業日かどうか調べる class Holiday { private readonly string sSyukujitsuCSV = @"syukujitsu.csv"; private readonly Dictionary<string, string> dicSyukujitsuCSV; private const string csDateFormat = "yyyy-MM-dd"; public Holiday() //コンストラクタ { Debug.WriteLine("Holiday(): START----------"); if (!File.Exists(sSyukujitsuCSV) //ファイル不存在 || this.Days(File.GetCreationTime(sSyukujitsuCSV)) > 30) //30日以上経過 { if (this.DownloadHolidayList()) { Debug.WriteLine("Holiday(): Success to download Syukujitsu CSV file."); File.SetCreationTime(sSyukujitsuCSV, DateTime.Now); //上書きダウンロードになって作成日が更新されないので、強制する } else { Debug.WriteLine("Holiday(): Can not get Syukujitsu CSV file."); throw new FileNotFoundException("can not get Syukujitsu CSV file."); } } //syukujitsu.csvを配列に取り込む dicSyukujitsuCSV = makeDicSyukujitsu(); //syukujitsu.csvを取り込む Debug.WriteLine("Holiday(): END----------"); } public bool isHoliday(DateTime pDT) { //休業日 = 日本の祝日 + 土日 return isSyukujitsu(pDT) || isSatSun(pDT); } //DateTime を渡されたら、その日が休日かどうか判定する public bool isSyukujitsu(DateTime pDT) { Debug.WriteLine($"isSyukujitsu(): parameter=[{pDT}]"); Debug.WriteLine($"isSyukujitsu(): key=[{pDT.ToString(csDateFormat)}]"); return dicSyukujitsuCSV.ContainsKey(pDT.ToString(csDateFormat)); } //今日が日本の祝日かどうか調べる。 public bool isSyukujitsu() { return isSyukujitsu(DateTime.Now); } public bool isSatSun(DateTime pDT) { DayOfWeek dow = pDT.DayOfWeek; switch (dow) { case DayOfWeek.Saturday: //土曜日 return true; case DayOfWeek.Sunday: //日曜日 return true; default: return false; } #pragma warning disable CS0162 return false; //到達しないがお守りとしてout of order #pragma warning restore CS0162 } //syukujitsu.csvを読み込んで<日付, 祝日名>のDictionaryを作る //当日と同年以降のデータのみ収容する。 //日付は yyyy-mm-dd 形式の文字列で格納する。 private Dictionary<string, string> makeDicSyukujitsu() { Dictionary<string, string> CsvData = new Dictionary<string, string>(); TextFieldParser tfparser = new TextFieldParser(sSyukujitsuCSV, System.Text.Encoding.GetEncoding("Shift_JIS"), true); Debug.WriteLine("makeDicSyukujitsu(): START------------"); using (tfparser) { tfparser.TextFieldType = FieldType.Delimited; //区切り形式 tfparser.SetDelimiters(","); tfparser.HasFieldsEnclosedInQuotes = false; //引用符なしとする tfparser.TrimWhiteSpace = true; //空白文字を取り除く。(現状必要ないが念の為) //DateTime.Nowの年を取り出して、その年以降のものだけ格納しておきたい。 DateTime dtDate; string sDate; while (!tfparser.EndOfData) { string[] row = tfparser.ReadFields(); if (DateTime.TryParse(row[0], out dtDate)) { if (dtDate.Year < DateTime.Now.Year) // 今年より前のデータは無視。今年以降を格納する { continue; } sDate = dtDate.ToString(csDateFormat); } else { continue; } // CsvData.Add(row[0], row[1]); //コレクションに追加する CsvData.Add(sDate, row[1]); //コレクションに追加する } foreach (KeyValuePair<string, string> pair in CsvData) { Debug.WriteLine($">> {pair.Key} : {pair.Value}"); } } Debug.WriteLine("makeDicSyukujitsu(): START------------"); return CsvData; } private int Days(DateTime pDateCreation) { TimeSpan ts = DateTime.Now - pDateCreation; Debug.WriteLine($"days(): Now - CreationDate (in days) = [{ts.Days}]."); return ts.Days; } //日本政府が提供する休日リストを取得するメソッド public bool DownloadHolidayList() { string sURL = "https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv"; var client = new WebClient(); try { client.DownloadFile(sURL, sSyukujitsuCSV); } catch (WebException e) { Debug.WriteLine($"DownloadHolidayList(): Exception Message[{e.Message}]"); return false; } return true; } } }