指定された日が休日かどうかを調べないといけなくなったので、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;
}
}
}