Python Program
This small Python program displays a clock face that shows both standard time (for the time zone) and local time. To calculate the EOT correctly, you must enter the correct position, including longitude and latitude (see class ClockWidget).
# CHANGE TO YOUR HOME LOCATION
self.latitude = 47.8125
self.longitude = 12.9636
# CHANGE TO YOUR TIME ZONE
self.tz = ZoneInfo("Europe/Berlin")
import sys
import math
from datetime import datetime, timedelta
from PyQt5.QtCore import Qt, QTimer, QPointF
from PyQt5.QtGui import QPainter, QPen, QColor
from PyQt5.QtWidgets import (
QApplication,
QWidget,
QVBoxLayout,
QFormLayout,
QLabel,
)
from zoneinfo import ZoneInfo
def equationOfTime(day_of_year):
# Approximation of the Equation Of Time
B = math.radians((360 / 365) * (day_of_year - 81))
return (
9.87 * math.sin(2 * B)
- 7.53 * math.cos(B)
- 1.5 * math.sin(B)
)
def trueLocalTime(dt, longitude):
# compute local time from time zone
day = dt.timetuple().tm_yday
# compute Equation Of Time
eot = equationOfTime(day)
# fimd the time at the standard - meridian of the time zone
utc_offset_h = dt.utcoffset().total_seconds() / 3600
standard_meridian = utc_offset_h * 15
# correct by 4 minutes per longitude deviation
longitude_correction = 4 * (longitude - standard_meridian)
correction = longitude_correction + eot
return dt + timedelta(minutes=correction)
class ClockWidget(QWidget):
def __init__(self):
super().__init__()
# CHANGE TO YOUR HOME LOCATION
self.latitude = 47.8125
self.longitude = 12.9636
# CHANGE TO YOUR TIME ZONE
self.tz = ZoneInfo("Europe/Berlin")
self.setMinimumSize(600, 600)
self.timer = QTimer(self)
self.timer.timeout.connect(self.update)
self.timer.start(1000)
def draw_hand(self, painter, angle_deg, length, width, color):
angle = math.radians(angle_deg - 90)
x = length * math.cos(angle)
y = length * math.sin(angle)
pen = QPen(color, width)
painter.setPen(pen)
painter.drawLine(
QPointF(0, 0),
QPointF(x, y)
)
def paintEvent(self, event):
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
w = self.width()
h = self.height()
radius = min(w, h) * 0.45
painter.translate(w / 2, h / 2)
# paint the dial
painter.setPen(QPen(Qt.black, 2))
painter.drawEllipse(
QPointF(0, 0),
radius,
radius
)
# marks for hours
for i in range(60):
painter.save()
painter.rotate(i * 6)
if i % 5 == 0:
painter.setPen(QPen(Qt.black, 3))
painter.drawLine(
0,
int(-radius),
0,
int(-radius + 20)
)
else:
painter.setPen(QPen(Qt.black, 1))
painter.drawLine(
0,
int(-radius),
0,
int(-radius + 10)
)
painter.restore()
now = datetime.now(self.tz)
localtime = trueLocalTime(now, self.longitude)
# normal time : black
self.draw_time(
painter,
now,
QColor("black"),
radius
)
# true local time : red
self.draw_time(
painter,
localtime,
QColor("red"),
radius * 0.95
)
painter.setBrush(Qt.black)
painter.drawEllipse(QPointF(0, 0), 5, 5)
def draw_time(self, painter, dt, color, radius):
sec = dt.second + dt.microsecond / 1e6
minute = dt.minute + sec / 60
hour = (dt.hour % 12) + minute / 60
min_angle = minute * 6
hour_angle = hour * 30
self.draw_hand(
painter,
hour_angle,
radius * 0.55,
5,
color
)
self.draw_hand(
painter,
min_angle,
radius * 0.80,
3,
color
)
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle(
"Clock For True Local Time"
)
self.clock = ClockWidget()
form = QFormLayout()
layout = QVBoxLayout()
layout.addLayout(form)
layout.addWidget(QLabel(
"Black = Time In Your Time Zone \nRed = True Local Time"
))
layout.addWidget(self.clock)
self.setLayout(layout)
def apply_settings(self):
try:
self.clock.latitude = float(
self.lat_edit.text().replace(",", ".")
)
self.clock.longitude = float(
self.lon_edit.text().replace(",", ".")
)
self.clock.tz = ZoneInfo(
self.tz_edit.text().strip()
)
self.clock.update()
except Exception as e:
print(e)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.resize(700, 700)
window.show()
sys.exit(app.exec_())
Running the Program
When you start the program, you should see the following clock: