Skip to content

Instantly share code, notes, and snippets.

@soleshka
Last active June 8, 2021 20:16
Show Gist options
  • Select an option

  • Save soleshka/1f4e8540d2fb534fcad0593d822bf413 to your computer and use it in GitHub Desktop.

Select an option

Save soleshka/1f4e8540d2fb534fcad0593d822bf413 to your computer and use it in GitHub Desktop.
Different timezones time on an analog clock. Requires a local clock image
"""
Descript :
This file contains implementation of the different timezones
wall clocks.To add a new time zone update the TIMEZONES list.
Additional timezones maybe printed using : printtimezones()
Date : 01/03/2017
Implementor : Oleg Greenberg
Python version : 3
"""
from datetime import datetime
import tkinter as tk
from PIL import Image , ImageTk
import math
import pytz
import time
#TIMEZONES = {"local-CET":0,"Israel":+1,"Russia":+2,"PST":-10}
TIMEZONES = ['US/Pacific','Europe/Moscow','Israel','Europe/Zurich','US/Mountain','Etc/GMT-5']
WIDTH = 900
HEIGHT = WIDTH//len(TIMEZONES)+10
FONT_SIZE = 20-2*len(TIMEZONES)
#clock image is a square covering the width
IMG_SIZE = (WIDTH//len(TIMEZONES),HEIGHT-10)
ARROW_MIN_SIZE = IMG_SIZE[1] - IMG_SIZE[1]*0.6
ARROW_HOUR_SIZE = IMG_SIZE[1] - IMG_SIZE[1]*0.8
image = Image.open("clock4.png")
end_prog = False
class ClocksGrid:
def __init__(self,x=0,y=0):
"""
x,y is the starting point on the canvas for the grid
the left up point for the image
"""
self.grid = []
self.grid_ids = []
self.x = x
self.y = y
def add_clock(self,region,indx):
pos = [0,0]
pos[0] = self.x+IMG_SIZE[0]*indx
pos[1] = self.y
clk = Clock(region,pos)
self.grid.append(clk)
def draw_clocks(self,canvas):
for clk in self.grid:
clk.draw_me(canvas)
def update_clocks(self,canvas):
for clk in self.grid:
if not (clk.seconds()%60):
clk.draw_minutes(canvas)
clk.draw_hours(canvas)
clk.draw_seconds(canvas)
class Clock:
"""
Clock class implementation
Draws a clock with hour & minute arrows
acording to self timezone
"""
def __init__(self,region='US/Pacific',pos=[0,0]):
self.region = region
self.line_sec_id=0
self.line_min_id=0
self.line_hour_id=0
self.pos = list(pos)
def __str__(self):
return "Region: "+ self.region
def my_time(self):
return self.region+": "\
+str(self.hours())\
+":"\
+str(self.minutes())
def seconds(self):
"""Returns the minutes from the current time zone"""
return datetime.now(pytz.timezone(self.region)).second
def minutes(self):
"""Returns the minutes from the current time zone"""
return datetime.now(pytz.timezone(self.region)).minute
def hours(self):
"""Returns the hours from the current time zone"""
return datetime.now(pytz.timezone(self.region)).hour
def draw_seconds(self,canvas):
if canvas:
canvas.delete(self.line_sec_id)
x0 = self.pos[0]+IMG_SIZE[0]//2
y0 = self.pos[1]+IMG_SIZE[1]//2
s = self.seconds()
angle = -math.pi/2 + 2*math.pi*s/60
x1 = x0 +ARROW_MIN_SIZE*math.cos(angle)
y1 = y0 +ARROW_MIN_SIZE*math.sin(angle)
self.line_sec_id=canvas.create_line(x0,y0,x1,y1)
canvas.pack()
def draw_minutes(self,canvas):
""" draw the minutes arrows"""
if canvas:
canvas.delete(self.line_min_id)
#get minutes arrow angle
m = self.minutes()
#-pi/2 is 12 oclock angle
angle = -math.pi/2 + 2*math.pi*m/60
x0 = self.pos[0]+IMG_SIZE[0]//2
y0 = self.pos[1]+IMG_SIZE[1]//2
x1 = x0 +ARROW_MIN_SIZE*math.cos(angle)
y1 = y0 +ARROW_MIN_SIZE*math.sin(angle)
#draw minutes arrow
self.line_min_id = canvas.create_line(x0,y0,x1,y1, arrow=tk.LAST,arrowshape=(20,10,2))
canvas.pack()
def draw_hours(self,canvas):
""" draw the hours arrows"""
if canvas:
canvas.delete(self.line_hour_id)
#get hours arrow angle
m = self.minutes()
h = self.hours()
#add minutes factor influance on the hour angle
angle = -math.pi/2 + 2*math.pi*(h%12)/12 + 2*math.pi*m/12/60
x0 = self.pos[0]+IMG_SIZE[0]//2
y0 = self.pos[1]+IMG_SIZE[1]//2
x1 = x0 +ARROW_HOUR_SIZE*math.cos(angle)
y1 = y0 +ARROW_HOUR_SIZE*math.sin(angle)
#draw hours arow
self.line_hour_id = canvas.create_line(x0,y0,x1,y1, arrow=tk.LAST,arrowshape=(20,10,2))
canvas.pack()
def digital_time_str(self):
""" returns hours & minutesstring hh:mm """
m = self.minutes()
h = self.hours()
m_str = str(m)
h_str = str(h)
if m < 10:
m_str = "0" + str(m)
if h < 10:
h_str = "0" + str(h)
return h_str + ":" + m_str
def draw_me(self,canvas):
canvas.create_image(self.pos[0], self.pos[1], image=photo, anchor='nw')
self.draw_minutes(canvas)
self.draw_hours(canvas)
self.draw_seconds(canvas)
m = self.minutes()
h = self.hours()
x0 = self.pos[0]+IMG_SIZE[0]//2
y0 = self.pos[1]+IMG_SIZE[1]//2
#draw info : region am/pm
canvas.create_text(x0,y0-20,fill="Orange",font="Times " + str(FONT_SIZE)+" italic bold",text=self.region)
digtime = self.digital_time_str()
canvas.create_text(x0,y0+20,fill="Green",font="Times 20 italic bold",text=digtime)
canvas.pack()
def print_timezones():
"""Print all the available identifiers for timezones"""
#pip install pitz
for tz in pytz.all_timezones:
print (tz)
#def click_hl():
global end_prog
end_prog = True
quit()
def main():
global image,photo,end_prog
try :
clk_grid = ClocksGrid()
i = 0
for val in TIMEZONES:
clk_grid.add_clock(val,i)
i +=1
top = tk.Tk()
top.title("World clock (c)Oleg Greenberg")
canvas = tk.Canvas(top, bg="silver", height=HEIGHT, width=WIDTH)
#B = tk.Button(top, text ="Close", command = click_hl)
#B.pack()
image = image.resize((IMG_SIZE[0],IMG_SIZE[1]+10))
photo = ImageTk.PhotoImage(image)
clk_grid.draw_clocks(canvas)
while not end_prog:
#top.update_idletasks()
top.update()
clk_grid.update_clocks(canvas)
time.sleep(1)
top.mainloop()
finally:
end_prog = True
print("I am in finally")
if __name__=='__main__':
main()
#print_timezones()
#uncomment this to have additional timezones
#print_timezones()
@Poikilos
Copy link

Poikilos commented Jun 8, 2021

Hi, please add a license because: https://choosealicense.com/no-permission/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment