接續之前"每個月的第幾個星期幾轉DateTime"的介紹,當時是在算特殊的節日或活動日,這裡紀錄如何讀取我國國定假日
參考資料
這裡以證交所的行事曆檔當範例,不確定有哪些公家單位網站有提供公務機關的行事曆檔,其他機關檔案的格式可能不一樣
//檔名:holidaySchedule_{民國年}.csv
string path=holidaySchedule_112.csv;
//編碼:big5
Encoding encoding=Encoding.GetEncoding(950); //Encoding.GetEncoding("big5");
int yyyy=2023;
IList<string> keywords1=new List<string>() { "月", "日" };
IEnumerable<string> keywords2=new List<string>() { "放假", "無交易", "補假" };
class Separator
{
static readonly string[] CSV = new string[] { "\",\"" };
}
static string[] SplitFromCSV(this string obj)
{
string[] cells = obj.Split(Separator.CSV, StringSplitOptions.None);
if (cells.Length > 0 && cells[0].StartsWith("\""))
{
cells[0] = cells[0].Substring(1);
string last = cells[cells.Length - 1];
cells[cells.Length - 1] = last.Substring(0, last.Length - 1);
}
return cells;
}
static void LoadHolidays(this IDictionary<DateTime, string> obj, in IList<string> lines, in int yyyy, in IList<string> keywords1, in IEnumerable<string> keywords2)
{
string[] separators1 = new string[] { keywords1[0], keywords1[1] };
foreach (string line in lines)
{
string[] cells = line.SplitFromCSV();
if (cells.Length < 4)
{
continue;
}
else if (string.IsNullOrWhiteSpace(keywords2.FirstOrDefault(x => cells[3].LastIndexOf(x) >= 0)))
{
continue;
}
foreach (string cell in cells)
{
if (cell.Contains(keywords1[0]) && cell.EndsWith(keywords1[1]))
{
string[] _MMdd = cell.Split(separators1, StringSplitOptions.RemoveEmptyEntries);
DateTime holiday = new DateTime(yyyy, int.Parse(_MMdd[0]), int.Parse(_MMdd[1]));
obj[holiday] = $"{holiday.DayOfWeek}, {string.Join(", ", cells)}";
}
}
}
}
static void LoadHolidays(this IDictionary<DateTime, string> obj, in string path, in Encoding encoding, in int yyyy, in IList<string> keywords1, in IEnumerable<string> keywords2)
{
obj.LoadHolidays(File.ReadAllLines(path, encoding), yyyy, keywords1, keywords2);
}
static T LoadHolidays<T>(this string obj, in Encoding encoding, in int yyyy, in IList<string> keywords1, in IEnumerable<string> keywords2) where T : IDictionary<DateTime, string>, new()
{
T dic = new T();
dic.LoadHolidays(obj, encoding, yyyy, keywords1, keywords2);
return dic;
}
下載的檔案不一定能直接使用,譬如證交所的會有一個1/17號,可能要在程式內寫特例過濾,或是人工微調檔案,把那一天刪掉
這種情況實務上很常見,假日檔/節日檔/活動日檔,或是放在DB上,偶爾需要人工維護,再餵給程式讀取