Python プログラミング

Pythonでカレンダーマスタを生成する

概要

この時期くらいに、様々なシステムに対してカレンダーマスタなるものを設定している作業を
されている方も多いのでは無かろうか?
GUIでぽちぽち設定するマスタもあれば
csv等で一括取込するケースもあるだろう。
この記事は、後者である場合にて
jpholidayさんを用いて、
カレンダーマスタを生成するサンプルである。

日付でループする処理や、曜日の日本語名取得、祝日名取得などが参考になると思う
サンプルコードは、休日のみを登録する仕様に対応したものだが
後半ロジックを少しカスタマイズすれば、全日登録して、営業日flagを持った仕様にも対応できると思う

利用環境

>
Python 3.7.2
Visual Studio Code 1.39.1
>

使用するパッケージ

  • datetime
  • jpholiday

サンプルコード

#とあるシステムのカレンダーマスタを用意する。

import csv
import datetime
import locale
import jpholiday


#指定した日付の範囲を返す関数、ループ処理用
def date_range(start_date: datetime, end_date: datetime):
    diff = (end_date - start_date).days + 1
    return (start_date + datetime.timedelta(i) for i in range(diff))


#指定した日付の曜日(日本語名)を返却
#以下が文字化けするので、仕方なく、get_youbi関数を作った。。。
#locale.setlocale(locale.LC_TIME, 'ja_JP.utf-8')
#print(locale.getlocale(locale.LC_TIME))
#youbi = atday.strftime('%A')
def get_youbi(st_date:datetime)-> str:
    # 曜日情報の文字列表現
    week_name_list='月火水木金土日'
    youbi = '%s曜日' % week_name_list[st_date.weekday()]
    return youbi


#指定したCSVのヘッダーを読み込み関数
def getcsvheader(fname:str)->list:
    #辞書として読み込み
    with open(fname, encoding="cp932") as f:
        reader = csv.DictReader(f)
        ks = reader.fieldnames
        return ks

#カレンダーCSV生成処理
#fname:ファイル名
#smode:1,銀行カレンダーモード , 2:会社営業日カレンダーモード
#sdate:生成開始日付
#edate:生成終了日付
# 土日祝のみのレコードを生成する。
def create_calender_csv(fname:str,smode:int,sdate:datetime,edate:datetime):

    with open(fname, "w", newline="") as f:
        # 要素順を指定します(dictでは順序がわからないため)
        hdlist = getcsvheader(".\\CAL\\_カレンダーマスタヘッダ.csv")

        # writerオブジェクトを作成します.
        writer = csv.DictWriter(f, fieldnames=hdlist, delimiter=",", quotechar='"')

        # writeheaderでヘッダーを出力できます.
        writer.writeheader()

        range_date = date_range(sdate,edate)
        for atday in range_date:
            #出力する対象か判定する
            outflag = False

            #祝日判定
            holiday_name = jpholiday.is_holiday_name(atday)
            if holiday_name is not None:
                outflag = True

            #土日判定
            if atday.weekday() >= 5:
                outflag = True

            if outflag == False:
                #出力せず次の日付へ
                continue

            #曜日(日本語名)を取得
            youbi = get_youbi(atday)

            #休日名称の設定
            if holiday_name is None:
                if smode == 1:
                    #銀行モードは、祝日じゃなければ曜日を設定
                    holiday_name = youbi
                elif smode == 2:
                    #会社モードは、祝日じゃなければ、各社で名付ける休日名を設定
                    if atday.weekday() == 5:
                        holiday_name = "土曜休日"
                    elif atday.weekday() == 6:
                        holiday_name = "普通休日"

            #モードによって、カレンダーコードの指定
            if smode == 1:
                cal_code = "01"
            elif smode == 2:
                cal_code = "0000000001"

            writer.writerow(
                    { 
                        "カレンダコード"  : cal_code,
                        "日付"  : atday.strftime('%Y%m%d') ,
                        "日付名"  : holiday_name,
                        "曜日"  : youbi,
                        "削除フラグ"  : "0",
                    }
            )


def main():

    #生成するカレンダーの範囲
    sdate = datetime.date(2020, 4, 1)
    edate = datetime.date(2021, 3, 31)
    #関数呼び出しとメイン処理
    create_calender_csv("銀行用.csv",1,sdate,edate)
    create_calender_csv("会社カレンダー用.csv",2,sdate,edate)



if __name__ == '__main__': main()

-Python, プログラミング
-,