Package: aiogram-datepicker
Aiogram datepicker widgetInstallingpip install aiogram-datepicker --upgradeDemo:Simple usageimportloggingimportosfromdatetimeimportdatetimefromaiogramimportBot,Dispatcherfromaiogram.typesimportMessage,CallbackQueryfromaiogram.utilsimportexecutorfromaiogram_datepickerimportDatepicker,DatepickerSettingslogging.basicConfig(level=logging.INFO)bot=Bot(token=os.environ['API_TOKEN'])dp=Dispatcher(bot,run_tasks_by_default=True)def_get_datepicker_settings():returnDatepickerSettings()#some settings@dp.message_handler(state='*')asyncdef_main(message:Message):datepicker=Datepicker(_get_datepicker_settings())markup=datepicker.start_calendar()awaitmessage.answer('Select a date: ',reply_markup=markup)@dp.callback_query_handler(Datepicker.datepicker_callback.filter())asyncdef_process_datepicker(callback_query:CallbackQuery,callback_data:dict):datepicker=Datepicker(_get_datepicker_settings())date=awaitdatepicker.process(callback_query,callback_data)ifdate:awaitcallback_query.message.answer(date.strftime('%d/%m/%Y'))awaitcallback_query.answer()if__name__=='__main__':executor.start_polling(dp,skip_updates=True)SettingsDatepickerSettings(initial_view='day',#available views -> day, month, yearinitial_date=datetime.now().date(),#default dateviews={'day':{'show_weekdays':True,'weekdays_labels':['Mo','Tu','We','Th','Fr','Sa','Su'],'header':['prev-year','days-title','next-year'],'footer':['prev-month','select','next-month'],#if you don't need select action, you can remove it and the date will return automatically without waiting for the button select#available actions -> prev-year, days-title, next-year, prev-month, select, next-month, ignore},'month':{'months_labels':['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],'header':['prev-year',['year','select'],#you can separate buttons into groups'next-year'],'footer':['select'],#available actions -> prev-year, year, next-year, select, ignore},'year':{'header':[],'footer':['prev-years','next-years'],#available actions -> prev-years, ignore, next-years}},labels={'prev-year':'<<','next-year':'>>','prev-years':'<<','next-years':'>>','days-title':'{month}{year}','selected-day':'{day}*','selected-month':'{month}*','present-day':'•{day}•','prev-month':'<','select':'Select','next-month':'>','ignore':''},custom_actions=[]#some custom actions)Custom action examplefromaiogram_datepickerimportDatepicker,DatepickerSettings,DatepickerCustomActionclassTodayAction(DatepickerCustomAction):action:str='today'label:str='Today'defget_action(self,view:str,year:int,month:int,day:int)->InlineKeyboardButton:"""Required function"""returnInlineKeyboardButton(self.label,callback_data=self._get_callback(view,self.action,year,month,day))asyncdefprocess(self,query:CallbackQuery,view:str,_date:date)->bool:"""Required function"""ifview=='day':awaitself.set_view(query,'day',datetime.now().date())returnFalseelifview=='month':awaitself.set_view(query,'month',date(_date.year,datetime.now().date().month,_date.day))returnFalseelifview=='year':awaitself.set_view(query,'month',date(datetime.now().date().year,_date.month,_date.day))returnFalsesettings=DatepickerSettings(views={'day':{'footer':['prev-month','today','next-month',['cancel']],},'month':{'footer':['today']},'year':{'header':['today'],}},custom_actions=[TodayAction])