Python 3 Tkinter Script to Build TimeZone Converter Based on Country Using pytz Library and Tkinter Calendar GUI Desktop App Full Project For Beginners

 

 

Welcome folks today in this blog post we will be building a timezone converter based on country in python using tkinter framework and pytz library.All the full source code of the application is shown below.

 

 

 

 

Get Started

 

 

 

In order to get started you need to install the below library using the pip command as shown below

 

 

pip install pytz

 

 

pip install tkcalendar

 

 

After installing these libraries make an app.py file and copy paste the following code

 

 

app.py

 

 

from tkinter import *
from tkinter.ttk import *
from tkinter import messagebox as msg
from datetime import datetime
from pytz import timezone
from pytz import all_timezones
import pytz
from tkcalendar import DateEntry
import re

window=Tk()

window.wm_title("Timezone Converter")

photo = PhotoImage(file = 'Time_converter.png')
window.iconphoto(False, photo)
window.configure(background = '#87CEEB')

def clear_all():
    list1.delete(0,END)
    list2.delete(0,END)
    e1.delete(0,END)
    e2.delete(0,END)
    e3.delete(0,END)
    e4.delete(0,END)
    number_min.delete(0,END)
    number_hrs.delete(0,END)

def aboutbox():
    msg.showinfo('Timezone Converter','Timezone Conversion Version 0.1 \n \nCopyright (c) 2019. All Rights Reserved.')

def exitbox():
    answer = msg.askyesnocancel('Timezone Converter Exit','Are you sure you really wish to exit?')
    if answer == True:
        window.destroy()
    elif answer == False:
        window.destroy
    else:
        window.destroy

menu_bar = Menu(window)
window.config(menu=menu_bar)

file_menu = Menu(menu_bar,tearoff=0)
file_menu.add_command(label="New",command=clear_all)
file_menu.add_command(label="Exit",command=exitbox)
menu_bar.add_cascade(label="File",menu=file_menu)

help_menu = Menu(menu_bar,tearoff=0)
menu_bar.add_cascade(label='Help',menu=help_menu)
help_menu.add_command(label='About',command=aboutbox)

style = Style()
style.configure('W.TButton', font = ('calibri', 10, 'bold',), foreground = 'black',background = '#87CEEB')
style.configure('TLabel', font = ('calibri', 10, 'bold',), foreground = 'black',background = '#87CEEB')

def get_selected_row(event):
    global selected_tuple
    index=list2.curselection()
    selected_tuple=list2.get(index)
    if not e1.get():
        e1.insert(END,selected_tuple)
        e4.delete(0,END)
        list2.delete(0,END)
    elif not e2.get():
        e2.insert(END,selected_tuple)
        e4.delete(0,END)
        list2.delete(0,END)

ctry_list2 = {'andorra':'Andorra','united arab emirates':'United Arab Emirates','afghanistan':'Afghanistan','antigua & barbuda':'Antigua & Barbuda','anguilla':'Anguilla',
'albania':'Albania','armenia':'Armenia','angola':'Angola','antarctica':'Antarctica','argentina':'Argentina','samoa (american)':'Samoa (American)',
'austria':'Austria','australia':'Australia','aruba':'Aruba','åland islands':'Åland Islands','azerbaijan':'Azerbaijan','bosnia & herzegovina':'Bosnia & Herzegovina',
'barbados':'Barbados','bangladesh':'Bangladesh','belgium':'Belgium','burkina faso':'Burkina Faso','bulgaria':'Bulgaria','bahrain':'Bahrain','burundi':'Burundi',
'benin':'Benin','st barthelemy':'St Barthelemy','bermuda':'Bermuda','brunei':'Brunei','bolivia':'Bolivia','caribbean nl':'Caribbean NL','brazil':'Brazil',
'bahamas':'Bahamas','bhutan':'Bhutan','bouvet island':'Bouvet Island','botswana':'Botswana','belarus':'Belarus','belize':'Belize','canada':'Canada',
'cocos (keeling) islands':'Cocos (Keeling) Islands','congo (dem. rep.)':'Congo (Dem. Rep.)','central african rep.':'Central African Rep.','congo (rep.)':'Congo (Rep.)',
'switzerland':'Switzerland','côte d\'ivoire':'Côte d\'Ivoire','cook islands':'Cook Islands','chile':'Chile','cameroon':'Cameroon','china':'China','colombia':'Colombia',
'costa rica':'Costa Rica','cuba':'Cuba','cape verde':'Cape Verde','curaçao':'Curaçao','christmas island':'Christmas Island','cyprus':'Cyprus','czech republic':'Czech Republic',
'germany':'Germany','djibouti':'Djibouti','denmark':'Denmark','dominica':'Dominica','dominican republic':'Dominican Republic','algeria':'Algeria','ecuador':'Ecuador',
'estonia':'Estonia','egypt':'Egypt','western sahara':'Western Sahara','eritrea':'Eritrea','spain':'Spain','ethiopia':'Ethiopia','finland':'Finland','fiji':'Fiji',
'falkland islands':'Falkland Islands','micronesia':'Micronesia','faroe islands':'Faroe Islands','france':'France','gabon':'Gabon','britain (uk)':'Britain (UK)',
'grenada':'Grenada','georgia':'Georgia','french guiana':'French Guiana','guernsey':'Guernsey','ghana':'Ghana','gibraltar':'Gibraltar','greenland':'Greenland',
'gambia':'Gambia','guinea':'Guinea','guadeloupe':'Guadeloupe','equatorial guinea':'Equatorial Guinea','greece':'Greece','south georgia & the south sandwich islands':'South Georgia & the South Sandwich Islands',
'guatemala':'Guatemala','guam':'Guam','guinea-bissau':'Guinea-Bissau','guyana':'Guyana','hong kong':'Hong Kong','heard island & mcdonald islands':'Heard Island & McDonald Islands',
'honduras':'Honduras','croatia':'Croatia','haiti':'Haiti','hungary':'Hungary','indonesia':'Indonesia','ireland':'Ireland','israel':'Israel','isle of man':'Isle of Man',
'india':'India','british indian ocean territory':'British Indian Ocean Territory','iraq':'Iraq','iran':'Iran','iceland':'Iceland','italy':'Italy','jersey':'Jersey',
'jamaica':'Jamaica','jordan':'Jordan','japan':'Japan','kenya':'Kenya','kyrgyzstan':'Kyrgyzstan','cambodia':'Cambodia','kiribati':'Kiribati','comoros':'Comoros',
'st kitts & nevis':'St Kitts & Nevis','korea (north)':'Korea (North)','korea (south)':'Korea (South)','kuwait':'Kuwait','cayman islands':'Cayman Islands',
'kazakhstan':'Kazakhstan','laos':'Laos','lebanon':'Lebanon','st lucia':'St Lucia','liechtenstein':'Liechtenstein','sri lanka':'Sri Lanka','liberia':'Liberia',
'lesotho':'Lesotho','lithuania':'Lithuania','luxembourg':'Luxembourg','latvia':'Latvia','libya':'Libya','morocco':'Morocco','monaco':'Monaco','moldova':'Moldova',
'montenegro':'Montenegro','st martin (french)':'St Martin (French)','madagascar':'Madagascar','marshall islands':'Marshall Islands','north macedonia':'North Macedonia',
'mali':'Mali','myanmar (burma)':'Myanmar (Burma)','mongolia':'Mongolia','macau':'Macau','northern mariana islands':'Northern Mariana Islands','martinique':'Martinique',
'mauritania':'Mauritania','montserrat':'Montserrat','malta':'Malta','mauritius':'Mauritius','maldives':'Maldives','malawi':'Malawi','mexico':'Mexico','malaysia':'Malaysia',
'mozambique':'Mozambique','namibia':'Namibia','new caledonia':'New Caledonia','niger':'Niger','norfolk island':'Norfolk Island','nigeria':'Nigeria','nicaragua':'Nicaragua',
'netherlands':'Netherlands','norway':'Norway','nepal':'Nepal','nauru':'Nauru','niue':'Niue','new zealand':'New Zealand','oman':'Oman','panama':'Panama',
'peru':'Peru','french polynesia':'French Polynesia','papua new guinea':'Papua New Guinea','philippines':'Philippines','pakistan':'Pakistan','poland':'Poland',
'st pierre & miquelon':'St Pierre & Miquelon','pitcairn':'Pitcairn','puerto rico':'Puerto Rico','palestine':'Palestine','portugal':'Portugal','palau':'Palau',
'paraguay':'Paraguay','qatar':'Qatar','réunion':'Réunion','romania':'Romania','serbia':'Serbia','russia':'Russia','rwanda':'Rwanda','saudi arabia':'Saudi Arabia',
'solomon islands':'Solomon Islands','seychelles':'Seychelles','sudan':'Sudan','sweden':'Sweden','singapore':'Singapore','st helena':'St Helena','slovenia':'Slovenia',
'svalbard & jan mayen':'Svalbard & Jan Mayen','slovakia':'Slovakia','sierra leone':'Sierra Leone','san marino':'San Marino','senegal':'Senegal','somalia':'Somalia',
'suriname':'Suriname','south sudan':'South Sudan','sao tome & principe':'Sao Tome & Principe','el salvador':'El Salvador','st maarten (dutch)':'St Maarten (Dutch)',
'syria':'Syria','eswatini (swaziland)':'Eswatini (Swaziland)','turks & caicos is':'Turks & Caicos Is','chad':'Chad','french southern & antarctic lands':'French Southern & Antarctic Lands',
'togo':'Togo','thailand':'Thailand','tajikistan':'Tajikistan','tokelau':'Tokelau','east timor':'East Timor','turkmenistan':'Turkmenistan','tunisia':'Tunisia',
'tonga':'Tonga','turkey':'Turkey','trinidad & tobago':'Trinidad & Tobago','tuvalu':'Tuvalu','taiwan':'Taiwan','tanzania':'Tanzania','ukraine':'Ukraine',
'uganda':'Uganda','us minor outlying islands':'US minor outlying islands','united states':'United States','uruguay':'Uruguay','uzbekistan':'Uzbekistan',
'vatican city':'Vatican City','st vincent':'St Vincent','venezuela':'Venezuela','virgin islands (uk)':'Virgin Islands (UK)','virgin islands (us)':'Virgin Islands (US)',
'vietnam':'Vietnam','vanuatu':'Vanuatu','wallis & futuna':'Wallis & Futuna','samoa (western)':'Samoa (western)','yemen':'Yemen','mayotte':'Mayotte',
'south africa':'South Africa','zambia':'Zambia','zimbabwe':'Zimbabwe'}

def search_tz_ctry():
    for i in sorted(pytz.country_names):
        if pytz.country_names[i] in ctry_list2[e4.get()]:
            return pytz.country_timezones(i)

def search_tz():
    list2.delete(0,END)
    for i in search_tz_ctry():
        list2.insert(END,str(i))

def From_To_TS():
    mytime = datetime.strptime(number_hrs.get()+number_min.get(),'%H%M').time()
    date_str = datetime.combine(datetime.strptime(e3.get(),'%d-%m-%Y').date(), mytime)
    datetime_obj_from = timezone(e1.get()).localize(date_str)
    datetime_obj_to = datetime_obj_from.astimezone(timezone(e2.get()))
    return datetime_obj_to.strftime("%d-%m-%Y %H:%M")

def convert_tz():
    list1.delete(0,END)
    to_value = str(From_To_TS())
    list1.insert(END,to_value)

class AutocompleteEntry(Entry):
    def __init__(self, lista, *args, **kwargs):

        Entry.__init__(self, *args, **kwargs)
        self.lista = lista
        self.var = self["textvariable"]
        if self.var == '':
            self.var = self["textvariable"] = StringVar()

        self.var.trace('w', self.changed)
        self.bind("<Right>", self.selection)
        self.bind("<Up>", self.up)
        self.bind("<Down>", self.down)

        self.lb_up = False

    def changed(self, name, index, mode):

        if self.var.get() == '':
            self.lb.destroy()
            self.lb_up = False
        else:
            words = self.comparison()
            if words:
                if not self.lb_up:
                    self.lb = Listbox()
                    self.lb.bind("<Double-Button-1>", self.selection)
                    self.lb.bind("<Right>", self.selection)
                    self.lb.place(x=self.winfo_x(), y=self.winfo_y()+self.winfo_height())
                    self.lb_up = True

                self.lb.delete(0, END)
                for w in words:
                    self.lb.insert(END,w)
            else:
                if self.lb_up:
                    self.lb.destroy()
                    self.lb_up = False

    def selection(self, event):

        if self.lb_up:
            self.var.set(self.lb.get(ACTIVE))
            self.lb.destroy()
            self.lb_up = False
            self.icursor(END)

    def up(self, event):

        if self.lb_up:
            if self.lb.curselection() == ():
                index = '0'
            else:
                index = self.lb.curselection()[0]
            if index != '0':
                self.lb.selection_clear(first=index)
                index = str(int(index)-1)
                self.lb.selection_set(first=index)
                self.lb.activate(index)

    def down(self, event):

        if self.lb_up:
            if self.lb.curselection() == ():
                index = '0'
            else:
                index = self.lb.curselection()[0]
            if index != END:
                self.lb.selection_clear(first=index)
                index = str(int(index)+1)
                self.lb.selection_set(first=index)
                self.lb.activate(index)

    def comparison(self):
        pattern = re.compile('.*' + self.var.get() + '.*')
        return [w for w in self.lista if re.match(pattern, w)]


l1=Label(window,text="From Timestamp  : ")
l1.grid(row=1,column=0,padx=6,pady=8)

l2=Label(window,text="=")
l2.grid(row=1,column=2)

l3=Label(window,text="To Timestamp      : ")
l3.grid(row=2,column=0,padx=6,pady=8)

l4=Label(window,text="=")
l4.grid(row=2,column=2)

l5=Label(window,text="Search by Country : ")
l5.grid(row=3,column=0,padx=6,pady=8)

l6=Label(window,text="Select Date :")
l6.grid(row=0,column=3)

l7=Label(window,text="Hours :")
l7.grid(row=0,column=4)

l8=Label(window,text="Minutes :")
l8.grid(row=0,column=5)

From_text=StringVar()
e1=Entry(window,textvariable=From_text)
e1.grid(row=1,column=1)

to_text=StringVar()
e2=Entry(window,textvariable=to_text)
e2.grid(row=2,column=1)

From_dt_text=StringVar()
e3=DateEntry(window, width=15, date_pattern='dd-mm-yyyy', background='darkblue', foreground='white')
e3.grid(row=1,column=3)
e3.delete(0,END)

From_hrs_text=StringVar()
number_hrs = Combobox(window, width=4, textvariable=From_hrs_text)
number_hrs['values'] = (f"{0:02d}",f"{1:02d}",f"{2:02d}",f"{3:02d}",f"{4:02d}",f"{5:02d}",f"{6:02d}",f"{7:02d}",f"{8:02d}",f"{9:02d}",\
                        10,11,12,13,14,15,16,17,18,19,20,21,22,23)
number_hrs.grid(row=1,column=4)

From_min_text=StringVar()
number_min = Combobox(window, width=4, textvariable=From_min_text)
number_min['values'] = (f"{0:02d}",f"{1:02d}",f"{2:02d}",f"{3:02d}",f"{4:02d}",f"{5:02d}",f"{6:02d}",f"{7:02d}",f"{8:02d}",f"{9:02d}",\
                        10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59)
number_min.grid(row=1,column=5)

e4 = AutocompleteEntry(ctry_list2.keys(), window)
e4.grid(row=3, column=1)

list1=Listbox(window, height=1,width=19,state="normal")
list1.grid(row=2,column=3)

list2=Listbox(window, height=5,width=21)
list2.grid(row=4,column=1,padx=6,pady=8)

sb1=Scrollbar(window,orient='vertical')
sb1.grid(row=4,column=2,padx=6,pady=8,sticky='NS')

sb2=Scrollbar(window,orient='horizontal')
sb2.grid(row=5,column=1,padx=6,pady=8,sticky='NS')

list2.configure(xscrollcommand=sb2.set,yscrollcommand=sb1.set)
sb1.configure(command=list2.yview)
sb2.configure(command=list2.xview)

list2.bind('<<ListboxSelect>>',get_selected_row)

image_search_path = 'Time_converter.png'
Search_logo = PhotoImage(file=image_search_path)
b1=Button(window,image=Search_logo, width=12,style = 'W.TButton',command=search_tz)
b1.grid(row=3,column=2)

b2=Button(window,text="Convert", width=12,style = 'W.TButton',command=convert_tz)
b2.grid(row=3,column=3)

window.mainloop()

 

 

 

 

Leave a Reply