接續之前"每個月的第幾個星期幾轉DateTime"的介紹,當時是在算特殊的節日或活動日,這裡紀錄如何讀取我國國定假日

參考資料
https://www.twse.com.tw/zh/holidaySchedule/holidaySchedule

這裡以證交所的行事曆檔當範例,不確定有哪些公家單位網站有提供公務機關的行事曆檔,其他機關檔案的格式可能不一樣

holidaySchedule_112_TSE.jpg

//檔名: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號,可能要在程式內寫特例過濾,或是人工微調檔案,把那一天刪掉

Holidays.jpg

這種情況實務上很常見,假日檔/節日檔/活動日檔,或是放在DB上,偶爾需要人工維護,再餵給程式讀取

創作者介紹
創作者 GNAySolution 的頭像
Yang

GNAySolution

Yang 發表在 痞客邦 留言(0) 人氣( 1 )