譌・譛ャ縺ョ莨第律 ========== Thunderbird縺ェ縺ゥ縺ョ繧ォ繝ャ繝ウ繝繝シ縺ォ譌・譛ャ縺ョ莨第律繧定。ィ遉コ縺励◆縺�→諤昴▲縺溘� `Thunderbird縺ョweb繧オ繧、繝� <https://www.thunderbird.net/ja/calendar/holidays>`__ 縺ォ縺ッ蜷�嵜縺ョ莨第律縺ョ諠��ア縺景Calender繝輔ぃ繧、繝ォ(.ics)縺ョ蠖「蠑上〒蜿弱a繧峨l縺ヲ縺�k縲� 縺励°縺励∵律譛ャ縺ョ諠��ア縺ッ2007蟷エ莉・髯肴峩譁ー縺輔l縺ヲ縺�↑縺�′縲�2020-2021縺ッ譚ア莠ャ繧ェ繝ェ繝ウ繝斐ャ繧ッ縺ョ蠖ア髻ソ縺ァ縲� 莨第律縺瑚�譎ゅ↓螟画峩縺輔l縺ヲ縺�k縲�(縺昴�莉悶�莨第律縺ォ繧�2007莉・髯阪�螟画峩縺後≠繧九ゑシ� 譌・譛ャ縺ョ莨第律縺ォ縺、縺�※縺ッ縲∝�髢」蠎懊′縺昴�\ `繝帙�繝�繝壹�繧ク <https://www8.cao.go.jp/chosei/shukujitsu/gaiyou.html>`__ 縺ァ蜈ャ蠑上↑繧「繝翫え繝ウ繧ケ繧貞�縺励※縺�k縲ら音縺ォ縲≫懈亊蜥�30蟷エ��1955蟷エ�峨°繧我サ、蜥�4蟷エ��2022蟷エ�牙嵜豌代�逾晄律窶昴r\ `csv蠖「蠑上�繝輔ぃ繧、繝ォ <https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv>`__ 縺ィ縺励※蜈ャ髢九@縺ヲ縺�k縲� 縺薙�繝励Ο繧ー繝ゥ繝�縺ョ逶ョ逧��縺薙�csv蠖「蠑上�繝輔ぃ繧、繝ォ縺九iThunderbird縺ェ縺ゥ縺ョCalendar繝励Ο繧ー繝ゥ繝�縺ァ蛻ゥ逕ィ蜿ッ閭ス縺ェiCal蠖「蠑上�繝輔ぃ繧、繝ォ(.ics)繧堤函謌舌☆繧九%縺ィ縺ァ縺吶� 蛻ゥ逕ィ縺吶k繝「繧ク繝・繝シ繝ォ ------------------ 縺薙�繝励Ο繧ー繝ゥ繝�縺ァ縺ッ莉・荳九�繝「繧ク繝・繝シ繝ォ繧剃スソ縺�∪縺吶�\ ``import``\ 縺ォ螟ア謨励☆繧九h縺�〒縺励◆繧峨― ``pip``\ 縺ェ縺ゥ縺ョ繝��繝ォ繧剃スソ縺」縺ヲ貅門y縺励∪縺励g縺�� urllib: 讓呎コ悶�web繧「繧ッ繧サ繧ケ縺ョ縺溘a縺ョ繝「繧ク繝・繝シ繝ォ縲Dsv繝輔ぃ繧、繝ォ繧偵ム繧ヲ繝ウ繝ュ繝シ繝峨☆繧九◆繧√↓菴ソ逕ィ縲� io: 繝��繧ソ繧偵≠縺溘°繧�File(stream)縺ョ繧医≧縺ォ蜿悶j謇ア縺医k繧医≧縺ォ縺吶k繝「繧ク繝・繝シ繝ォ縲ゅム繧ヲ繝ウ繝ュ繝シ繝峨@縺溘ョ繝シ繧ソ繧偵∽クュ髢薙ヵ繧。繧、繝ォ縺ォ菫晏ュ倥@縺ェ縺�〒縲√Γ繝「繝ェ荳翫↓鄂ョ縺�◆縺セ縺セ蛻ゥ逕ィ縺吶k縺溘a縲� pandas: 繝��繧ソ隗」譫舌�縺溘a縺ョ繝「繧ク繝・繝シ繝ォ縲ゅ%縺ョ縺ェ縺九�DataFrame繧貞茜逕ィ縺吶k縲� csv繝輔ぃ繧、繝ォ縺ョ譌・莉倥ョ繝シ繧ソ螟画鋤縺ェ縺ゥ繧貞柑邇�h縺�(遏ュ縺��繝ュ繧ー繝ゥ繝�縺ァ�牙ョ溽樟縺吶k縺溘a縺ォ蛻ゥ逕ィ縲� sqlite: 繝輔ぃ繧、繝ォ繝吶�繧ケ縺ョRDBMS sqlite繧剃スソ縺�◆繧√�繝「繧ク繝・繝シ繝ォ縲ゅョ繝シ繧ソ縺ョ讀懃エ「縺ェ縺ゥ繧堤ー。蜊倥↓陦後≧縺溘a縺ォ蛻ゥ逕ィ縺ァ縺阪k縲よ悽菴薙�繝励Ο繧ー繝ゥ繝�縺ァ縺ッ譛ェ蛻ゥ逕ィ縺ェ縺ョ縺ァ縲√↑縺上※繧り憶縺�� icalendar: iCal繝��繧ソ蜿匁桶縺ョ縺溘a縺ョ繝「繧ク繝・繝シ繝ォ縲Jcs繝輔ぃ繧、繝ォ菴懈�縺ォ菴ソ逕ィ縺吶k縲� .. code:: ipython3 #!/usr/bin/env python # coding: utf-8 """ This program generates ics file for the Japanese Holidays based on the information from Japanese goverment web page. """ import urllib.request from urllib.request import urlopen # macos縺ァ縺ッSSL險シ譏取嶌繧呈ュ」縺励¥縺、縺九∴繧九h縺�↓莉・荳九�譁�′蠢�ヲ� import os, certifi os.environ["SSL_CERT_FILE"]=certifi.where() import io from io import StringIO, BytesIO import pandas import sqlite3 import icalendar, pytz, datetime, uuid from icalendar import vBoolean, vCalAddress, vDate, vDatetime,vDuration,vFloat, vFrequency, vInt, vPeriod, vText, vTime, vUri, vUTCOffset, vWeekday JST = pytz.timezone("Asia/Tokyo") # note: this csv uses shift-jis encoding. JHuri="https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv" # a list of codecs supported by python can be found in https://docs.python.org/ja/3/library/codecs.html 繝��繧ソ縺ョ繝繧ヲ繝ウ繝ュ繝シ繝� -------------------- 繝��繧ソ繧蜘eb繧「繝峨Ξ繧ケ(``cvsuri``)縺九i繝繧ヲ繝ウ繝ュ繝シ繝峨@縺ヲ縲� 1. 謇句�縺ョ繝輔ぃ繧、繝ォ縺ィ縺励※菫晏ュ倥@縺溘j(``load_and_save_cvs``)縲√ 2. pands DataFrame縺ォ螟画鋤縺励※(``load_as_dataframe``)蛻・縺ョ繝励Ο繧ー繝ゥ繝�縺ァ蛻ゥ逕ィ縺励◆繧翫� 3. sqlite3縺ョon memory 繝��繧ソ繝吶せ縺ォ螟画鋤(``load_as db``)縺吶k 髢「謨ー遲峨r縺薙%縺ァ螳夂セゥ縺励※縺�∪縺吶� .. code:: ipython3 def load_and_save_cvs(cvsuri): fn=cvsuri.split("/")[-1] with urlopen(cvsuri) as inf , open(fn,"wb") as outf: print ("downloading :", fn) data=inf.read() outf.write(data) def load_as_dataframe(cvsuri): fn=cvsuri.split("/")[-1] with urlopen(cvsuri) as inf: print ("downloading :", fn) data=inf.read().decode("shift_jis") #file encoding in this csv file is shift JIS. sio=io.StringIO(data) # store data in to StringIO object. # interprete string in '蝗ス豌代�逾晄律繝サ莨第律譛域律'(the first) column as datetime. df=pandas.read_csv(sio, # use StringIO object as if it is a open file object. parse_dates=['蝗ス豌代�逾晄律繝サ莨第律譛域律'], # column 0 shoud be read as date infer_datetime_format=True ) # df=pandas.read_csv(sio, parse_dates=[0], infer_datetime_format=True) print(df.info()) return df def load_as_db(cvsuri): """ download csv file then convert to sqlite3 database on memory. """ df=load_as_dataframe(cvsuri) # create dataframe db=sqlite3.connect(":memory:") # create sqlite3 database on memory. df.to_sql('holidays', db) # write all data to database. return db Calendar 繧ェ繝悶ず繧ァ繧ッ繝� --------------------- iCal縺ョ繝輔ぃ繧、繝ォ繧剃ス懈�縺吶k貅門y縺ィ縺励※縲(calender.Calendar繧ッ繝ゥ繧ケ繧堤カ呎価縺励◆Calendar Class繧貞ョ夂セゥ縺励∪縺吶ゅ%縺ョ繧ッ繝ゥ繧ケ縺ォ縺ッ莨第律(譌・莉倥→莨第律蜷搾シ峨r逋サ骭イ縺吶k縺溘a縺ョ ``add_holiday`` 繝。繧ス繝�ラ繧定ソス蜉�縺励※縺翫″縺セ縺吶ゅCalendear繝輔ぃ繧、繝ォ縺ッicanldear.Calendar繧ッ繝ゥ繧ケ縺梧戟縺、縲― ``to_ical``\ 繧剃スソ縺」縺ヲ譖ク縺榊�縺励∪縺吶� .. code:: ipython3 class Calendar(icalendar.Calendar): """ """ # notify tis event 15 min before event alarm_setting=icalendar.Alarm().from_ical( "BEGIN:VALARM\n" "ACTION:DISPLAY\n" "TRIGGER;VALUE=DURATION:-PT15M\n" "DESCRIPTION:Default Mozilla Description\n" "END:VALARM" ) def __init__(self): """ """ super(icalendar.Calendar,self).__init__() self.add(u"prodid","-//Japanese Holidays/based on Python.iCalendar//") self.add(u"Version",2.0) self.add(u"Category","Japanese Public Holidays") self.add(u"Summary","Official Japanese Public Holidays ") self.add_component(self.alarm_setting) self.add_component(icalendar.Timezone.from_ical( "BEGIN:VTIMEZONE\n" "TZID:/mozilla.org/20070129_1/Asia/Tokyo\n" "X-LIC-LOCATION:Asia/Tokyo\n" "BEGIN:STANDARD\n" "TZOFFSETFROM:+0900\n" "TZOFFSETTO:+0900\n" "TZNAME:JST\n" "DTSTART:19700101T000000\n" "END:STANDARD\n" "END:VTIMEZONE\n") ) def add_holiday(self, date, name): ev=icalendar.Event() ev['uid']=uuid.uuid4() ev["categories"]=vText("Japanese Public Holidays") ev.add( 'dtstart', vDate( datetime.datetime.fromtimestamp( date.timestamp(), tz=JST) ), encode=False ) ev.add( 'dtend', vDate( datetime.datetime.fromtimestamp( (date + datetime.timedelta(days=1)).timestamp(), tz=JST) ), encode=False ) ev.add( 'summary', name ) ev.add( 'description', vText(name, 'utf-8') ) self.add_component(ev) 繝励Ο繧ー繝ゥ繝�縺ョ譛ャ菴� ---------------- 荳翫〒逕ィ諢上@縺滄未謨ー繧�け繝ゥ繧ケ繧剃スソ縺」縺ヲweb縺九i蜿悶j霎シ繧薙□繝��繧ソ繧剃スソ縺」縺ヲ縲(cs繝輔ぃ繧、繝ォ繧剃ス懈�縺励∪縺吶� .. code:: ipython3 def main(): # web荳翫�繝��繧ソ縺九iDataFrame繧剃ス懈�縲� df=load_as_dataframe(JHuri) cal=Calendar() # Calendar 繧ェ繝悶ず繧ァ繧ッ繝医r菴懈�縺励.ataFrame縺ョ莨第律繝��繧ソ繧堤匳骭イ for id, date, name in df.itertuples(): cal.add_holiday(date, name) #.ics繝輔ぃ繧、繝ォ繧剃ス懈�縺励√ョ繝シ繧ソ繧段Calendar蠖「蠑上〒譖ク縺榊�縺励∪縺吶� with open( "JapaneseHolidays.ics", mode="w", encoding="utf-8" # for py2app. you need explicitly specify encoding. ) as f: s=cal.to_ical() # icalendar 蠖「蠑上↓螟画鋤縲� s=s.decode("utf-8", "replace") # unicode縺ォ螟画鋤 f.write(s) #繝輔ぃ繧、繝ォ縺ォ譖ク縺榊�縺吶� 繝励Ο繧ー繝ゥ繝�縺ョ螳溯。� ---------------- 螳梧�縺励◆繝励Ο繧ー繝ゥ繝�繧貞腰迢ャ縺ァ蛻ゥ逕ィ縺吶k縺薙→繧定�∴縺ヲ縲√>縺、繧ゅ�縺翫∪縺倥↑縺�r縺�l縺ヲ縺翫″縺セ縺吶� .. code:: ipython3 if __name__ == "__main__": main() print("Done!") .. parsed-literal:: downloading : syukujitsu.csv <class 'pandas.core.frame.DataFrame'> RangeIndex: 975 entries, 0 to 974 Data columns (total 2 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 蝗ス豌代�逾晄律繝サ莨第律譛域律 975 non-null datetime64[ns] 1 蝗ス豌代�逾晄律繝サ莨第律蜷咲ァー 975 non-null object dtypes: datetime64[ns](1), object(1) memory usage: 15.4+ KB None Done!