import os
import customtkinter as ctk
import pytz
from skyfield.api import Loader
from skyfield import almanac
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
class Menu17App(ctk.CTk):
def __init__(self):
super().__init__()
self.title("Equinox & Solstice Calculator (Modul 17)")
self.geometry("700x400")
ctk.set_appearance_mode("Dark")
self.load_obj = Loader(BASE_DIR)
self.eph = self.load_obj('de421.bsp')
self.ts = self.load_obj.timescale()
self.setup_ui()
def setup_ui(self):
self.sidebar = ctk.CTkFrame(self, width=200)
self.sidebar.pack(side="left", fill="y", padx=10, pady=10)
self.entry_y = ctk.CTkEntry(self.sidebar, placeholder_text="Tahun (Masehi)")
self.entry_y.insert(0, "2026")
self.entry_y.pack(pady=20, padx=10)
ctk.CTkButton(self.sidebar, text="▶ HITUNG MUSIM", command=self.hitung).pack(pady=10)
self.textbox = ctk.CTkTextbox(self, font=("Consolas", 14))
self.textbox.pack(side="right", fill="both", expand=True, padx=10, pady=10)
def hitung(self):
self.textbox.delete("1.0", "end")
try: y = int(self.entry_y.get())
except ValueError: return
t0 = self.ts.utc(y, 1, 1)
t1 = self.ts.utc(y, 12, 31)
t_seasons, y_seasons = almanac.find_discrete(t0, t1, almanac.seasons(self.eph))
tz_wib = pytz.timezone('Asia/Jakarta')
musim_nama = [
"Vernal Equinox (Musim Semi Utara)",
"Summer Solstice (Musim Panas Utara)",
"Autumnal Equinox (Musim Gugur Utara)",
"Winter Solstice (Musim Dingin Utara)"
]
report = f"[ Equinox & Solstice Calculator ]\n{'='*60}\n"
for t_ev, y_ev in zip(t_seasons, y_seasons):
dt_wib = t_ev.utc_datetime().replace(tzinfo=pytz.utc).astimezone(tz_wib)
report += f">> {musim_nama[y_ev]:<38} : {dt_wib.strftime('%d %B %Y %H:%M:%S WIB')}\n"
self.textbox.insert("end", report)
if __name__ == "__main__":
app = Menu17App()
app.mainloop()