Python

pythonでgoogle calendarの予定【勤怠】をエクセル形式で出力するプログラムを作る(作業時間算出編)

こんにちは Tomoです。

前回に引き続きエクスポートしたカレンダーデータの読み込みと終了時間から開始時間の差分を掲載して勤務時間を出力します。

今回は複数の予定から、「勤怠」と時間「09:30~18:30」を取得してコンソールに取得します

データを変数に格納する

まずはGoogleカレンダーの予定登録をおこないます。

前回と同様に登録します。前回と同じ時間で2件追加登録します。

ちなみに、繰り返しの登録ではなく、1件づつ登録します。

こちらについては前回のブログに記載していますのでそちらを参考にしてください。

データ格納

ダウンロードまで終わたら前回までに作成したテストプログラムを動かしてみます。

    
D:\python_workspace>python testpython.py
BEGIN:VEVENT
2019/12/28 09:30:00
2019/12/28 18:30:00
勤怠
END:VEVENT
BEGIN:VEVENT
2019/12/30 09:30:00
2019/12/30 19:30:00
勤怠
END:VEVENT
BEGIN:VEVENT
2019/12/31 09:30:00
2019/12/31 18:30:00
勤怠
END:VEVENT
    

前回作成したのは、条件文とその内容を出力するコードでした。このため、上記のように1行づつ読み込んで出力されています。

今回はこの出力された内容を変数に格納したいと思います。変数を使う場合はいくつか方法があると思います。

  • ひとつづつ変数を用意する
  • listをつかう
  • classを使う
  • 上記以外

ひとつづつ変数を用意する

ひとつづつ用意する場合

    
start_date_1 = 2019/12/28 09:30:00
end_date_1   = 2019/12/28 18:30:00
summary_1    = 勤怠
start_date_2 = 2019/12/30 09:30:00
・・・
summary_3      = 勤怠
    

このやり方は・・・大変すぎるのとデータが増えたら対応できないですね

listをつかう

今度は、listを使って格納します。

    
start_date_list = []
end_date_list   = []
summary_list    = []

start_date_list.append(2019/12/30 09:30:00)
end_date_list.append(2019/12/28 18:30:00)
end_date_list.append(勤怠)
start_date_list.append(2019/12/30 09:30:00)
・・・
end_date_list.append(2019/12/31 18:30:00)
summary_list .append(勤怠)
    

上記の説明をします。

start_date_list = []

これは「開始時間」、「終了時間」、「タイトル」それぞれをlistとして初期化しています。

「start_date_list.append(2019/12/30 09:30:00)」appendメソッドを使って開始時間を代入してます。

結果としては以下のようなデータの持ち方になります。

「start_date_list ={2019/12/30 09:30:00, 2019/12/30 09:30:00, 2019/12/31 09:30:00}

「end_date_list ={2019/12/30 18:30:00, 2019/12/30 18:30:00, 2019/12/31 18:30:00}

「summary_list ={勤怠, 勤怠, 勤怠}

先ほどよりはわかりやすいですが、値がない時に考慮する必要があります。値がないときにデフォルトの値などを用意し置かないと格納の順番がずれる可能性があります。

classをつかう

最後は専用のクラスを用意して格納します。

ただし、今回説明は省略します。

上記以外

こちらもいろいろあると思いますが、勉強中でいったん説明は省略させていただきます。

今回の結論では、listの変数にいれたいと思います。

前提としては、勤怠、開始時間、終了時間が必ずはいってることになります。

では、実際に変数を用意して、値を格納するコーディングを行います。

    
import zipfile
import datetime
import dateutil.parser

with zipfile.ZipFile('D:\\python_workspace\\imput_data\\{google_account}@gmail.com.ical.zip') as cal_zip:
    with cal_zip.open('50vtb9lj4n2eff1d56e0rf00gg@group.calendar.google.com.ics') as cal_file:

         jst = datetime.timezone(datetime.timedelta(hours=+9), 'JST')

         stat_date_list = []
         end_date_list  = []
         summary_list   = []

         for line in cal_file:

             line_decode = line.decode('utf-8')
             line_decode = line_decode.rstrip('\r\n')

             # イベントの開始(BEGIN:VEVENT)を探す
             if 'BEGIN:VEVENT' in line_decode:
                 print(line_decode)

             # 開始時間(DTSTART)を探す
             if 'DTSTART:' in line_decode:
                 dt_start = line_decode.split(':')
                 dt_start_time = dateutil.parser.parse(dt_start[1]).astimezone(jst)
                 stat_date_list.append(dt_start_time)
                 print(dt_start_time.strftime("%Y/%m/%d %H:%M:%S"))

             # 終了時間(DTEND)を探す
             if 'DTEND:' in line_decode:
                 dt_end = line_decode.split(":")
                 dt_end_time = dateutil.parser.parse(dt_end[1]).astimezone(jst)
                 end_date_list.append(dt_end_time)
                 print(dt_end_time.strftime("%Y/%m/%d %H:%M:%S"))

             # タイトル(SUMMARY)を探す
             if 'SUMMARY:' in line_decode:
                 summary = line_decode.split(':')
                 summary_list.append(summary[1])
                 print(summary[1])

             # イベントの終了(END:VEVENT)
             if 'END:VEVENT' in line_decode:
                 print(line_decode)

         print(stat_date_list)
         print(end_date_list)
         print(summary_list)
    

基本的には先ほどの説明と同じです。開始、終了、SUMMARYのところで追加(append)してます。

なお、開始時間、終了時間は文字列ではなく、時間型の状態で格納しています。

最後にループが終わった後にprintをして出力をしています。(インデントがずれないようにしてください。)

最後の実行の結果だけ表示します(見やすいように改行をしています。)

    
[    datetime.datetime(2019, 12, 28, 9, 30, tzinfo=datetime.timezone(datetime.timedelta(seconds=32400), 'JST')),
     datetime.datetime(2019, 12, 30, 9, 30, tzinfo=datetime.timezone(datetime.timedelta(seconds=32400), 'JST')),
     datetime.datetime(2019, 12, 31, 9, 30, tzinfo=datetime.timezone(datetime.timedelta(seconds=32400), 'JST'))
]
[    datetime.datetime(2019, 12, 28, 18, 30, tzinfo=datetime.timezone(datetime.timedelta(seconds=32400), 'JST')), 
     datetime.datetime(2019, 12, 30, 18, 30, tzinfo=datetime.timezone(datetime.timedelta(seconds=32400), 'JST')), 
     datetime.datetime(2019, 12, 31, 18, 30, tzinfo=datetime.timezone(datetime.timedelta(seconds=32400), 'JST'))
]
[    '勤怠',
     '勤怠',
     '勤怠'
]
    

それぞれのlistに値が格納されていることをが分かります。

作業時間を算出する

終了時間から開始時間を引いて、かつ、休憩時間1時間を差し引きます。

    
         for count, summary in enumerate(summary_list):
             print('----------')
             print(summary)
             print(stat_date_list[count].strftime("%Y/%m/%d"))
             print(stat_date_list[count].strftime("%H:%M"))
             print(end_date_list[count].strftime("%Y/%m/%d"))
             print(end_date_list[count].strftime("%H:%M"))
             print(end_date_list[count] - stat_date_list[count] - datetime.timedelta(hours=1))
    

先ほどの修正でprintのところを変えました。

for count, summary in enumerate(summary_list):繰り返し文は、enumerate(summary_list)enumerate関数を使うとsummary_listの値と要素の番号が返却されます。

これを使って角リストを取得しています。

作業時間は、end_date_list[count] - stat_date_list[count] - datetime.timedelta(hours=1)で取得できます。

実際に実行してみます。

    
----------
勤怠
2019/12/28
09:30
2019/12/28
18:30
8:00:00
----------
勤怠
2019/12/30
09:30
2019/12/30
18:30
8:00:00
----------
勤怠
2019/12/31
09:30
2019/12/31
18:30
8:00:00
    

なんとなくですが出力できました。

まとめ

今回は、カレンダーデータをlistに格納するやり方で格納してみました。

また、作業時間の差分も産出しました。

listの中にlistも入れることが出来そうなのでそちらでの対応の仕方や、Classをつくって格納するやり方も検討したいと思います。

繰り返しの予定登録なども検討は必要ですが、まずは、カレンダーから登録した値をエクセル形式に出力するところまで一度やった後に改善を行いたいと思っています。

最後にソースコードを展開しておきます

    
import zipfile
import datetime
import dateutil.parser

with zipfile.ZipFile('D:\\python_workspace\\imput_data\\m.tomo0912.tm@gmail.com.ical.zip') as cal_zip:
    with cal_zip.open('50vtb9lj4n2eff1d56e0rf00gg@group.calendar.google.com.ics') as cal_file:

         jst = datetime.timezone(datetime.timedelta(hours=+9), 'JST')

         stat_date_list = []
         end_date_list  = []
         summary_list   = []

         for line in cal_file:

             line_decode = line.decode('utf-8')
             line_decode = line_decode.rstrip('\r\n')

             # イベントの開始(BEGIN:VEVENT)を探す
             if 'BEGIN:VEVENT' in line_decode:
                 print(line_decode)

             # 開始時間(DTSTART)を探す
             if 'DTSTART:' in line_decode:
                 dt_start = line_decode.split(':')
                 dt_start_time = dateutil.parser.parse(dt_start[1]).astimezone(jst)
                 stat_date_list.append(dt_start_time)
                 print(dt_start_time.strftime("%Y/%m/%d %H:%M:%S"))

             # 終了時間(DTEND)を探す
             if 'DTEND:' in line_decode:
                 dt_end = line_decode.split(":")
                 dt_end_time = dateutil.parser.parse(dt_end[1]).astimezone(jst)
                 end_date_list.append(dt_end_time)
                 print(dt_end_time.strftime("%Y/%m/%d %H:%M:%S"))

             # タイトル(SUMMARY)を探す
             if 'SUMMARY:' in line_decode:
                 summary = line_decode.split(':')
                 summary_list.append(summary[1])
                 print(summary[1])

             # イベントの終了(END:VEVENT)
             if 'END:VEVENT' in line_decode:
                 print(line_decode)

                 
         for count, summary in enumerate(summary_list):
             print('----------')
             print(summary)
             print(stat_date_list[count].strftime("%Y/%m/%d"))
             print(stat_date_list[count].strftime("%H:%M"))
             print(end_date_list[count].strftime("%Y/%m/%d"))
             print(end_date_list[count].strftime("%H:%M"))
             print(end_date_list[count] - stat_date_list[count] - datetime.timedelta(hours=1))
    

コメント

0 件のコメント:

コメントを投稿

コメントをお待ちしています。