menu13.py

Download
import os, datetime
import customtkinter as ctk
from skyfield.api import Loader
from skyfield import almanac

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
BULAN_MASEHI = ["Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember"]
BULAN_HIJRIAH = ["Muharam", "Safar", "Rabiulawal", "Rabiulakhir", "Jumadilawal", "Jumadilakhir", "Rajab", "Syakban", "Ramadan", "Syawal", "Zulkaidah", "Zulhijah"]

class Menu13App(ctk.CTk):
    def __init__(self):
        super().__init__()
        self.title("Konversi Kalender KHGT (Modul 13)")
        self.geometry("700x500")
        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=250)
        self.sidebar.pack(side="left", fill="y", padx=10, pady=10)
        
        now = datetime.datetime.now()
        self.radio_var = ctk.StringVar(value="m2h")
        ctk.CTkRadioButton(self.sidebar, text="Masehi -> Hijriah", variable=self.radio_var, value="m2h", command=self.update_ui).pack(pady=5)
        ctk.CTkRadioButton(self.sidebar, text="Hijriah -> Masehi", variable=self.radio_var, value="h2m", command=self.update_ui).pack(pady=5)
        
        self.entry_d = ctk.CTkEntry(self.sidebar); self.entry_d.insert(0, str(now.day)); self.entry_d.pack(pady=5)
        self.combo_m = ctk.CTkOptionMenu(self.sidebar, values=BULAN_MASEHI); self.combo_m.pack(pady=5)
        self.entry_y = ctk.CTkEntry(self.sidebar); self.entry_y.insert(0, str(now.year)); self.entry_y.pack(pady=5)
        self.combo_adj = ctk.CTkOptionMenu(self.sidebar, values=["-2", "-1", "0", "+1", "+2"]); self.combo_adj.set("0"); self.combo_adj.pack(pady=5)
        
        ctk.CTkButton(self.sidebar, text="▶ KONVERSI", command=self.hitung).pack(pady=15)
        self.textbox = ctk.CTkTextbox(self, font=("Consolas", 14))
        self.textbox.pack(side="right", fill="both", expand=True, padx=10, pady=10)

    def update_ui(self):
        if self.radio_var.get() == "m2h": self.combo_m.configure(values=BULAN_MASEHI)
        else: self.combo_m.configure(values=BULAN_HIJRIAH)

    def get_approx_nm_tt(self, y, m):
        abs_month = (y - 1) * 12 + m
        return 2451550.0 + (abs_month - 17038) * 29.530588853

    def get_hijri_month(self, tt_float):
        abs_m = 17038 + round((tt_float - 2451550.0) / 29.530588853)
        return (abs_m - 1) // 12 + 1, (abs_m - 1) % 12 + 1

    def calc_khgt_1st(self, nm_tt):
        t_nm = self.ts.tt_jd(nm_tt)
        y, m, d, h, _, _ = t_nm.utc
        t_mid = self.ts.utc(y, m, d)
        return t_mid.tt + 1.0 if h < 15 else t_mid.tt + 2.0

    def hitung(self):
        self.textbox.delete("1.0", "end")
        mode = self.radio_var.get()
        d, y = int(self.entry_d.get()), int(self.entry_y.get())
        m_str = self.combo_m.get()
        adj = int(self.combo_adj.get())
        
        try:
            if mode == "m2h":
                m = BULAN_MASEHI.index(m_str) + 1
                t_target = self.ts.utc(y, m, d).tt
                
                t0, t1 = self.ts.tt_jd(t_target - 35.0), self.ts.tt_jd(t_target + 2.0)
                t_ph, y_ph = almanac.find_discrete(t0, t1, almanac.moon_phases(self.eph))
                nms = [t.tt for t, p in zip(t_ph, y_ph) if p == 0]
                
                curr_nm = None
                for nm in reversed(nms):
                    if t_target >= self.calc_khgt_1st(nm) - 0.1:
                        curr_nm = nm
                        break
                        
                hy, hm = self.get_hijri_month(curr_nm)
                start_tt = self.calc_khgt_1st(curr_nm)
                hd = int(round(t_target - start_tt)) + 1 + adj
                
                self.textbox.insert("end", f"Hasil Konversi (KHGT):\n>> {hd} {BULAN_HIJRIAH[hm-1]} {hy} H\n")
            else:
                m = BULAN_HIJRIAH.index(m_str) + 1
                approx_tt = self.get_approx_nm_tt(y, m)
                
                t0, t1 = self.ts.tt_jd(approx_tt - 5.0), self.ts.tt_jd(approx_tt + 5.0)
                t_ph, y_ph = almanac.find_discrete(t0, t1, almanac.moon_phases(self.eph))
                nm_tt = [t.tt for t, p in zip(t_ph, y_ph) if p == 0][0]
                
                start_tt = self.calc_khgt_1st(nm_tt)
                t_res = self.ts.tt_jd(start_tt + (d - 1) - adj)
                ry, rm, rd, _, _, _ = t_res.utc
                
                self.textbox.insert("end", f"Hasil Konversi Masehi:\n>> {int(rd)} {BULAN_MASEHI[int(rm)-1]} {int(ry)} M\n")
                
        except Exception as e:
            self.textbox.insert("end", f"Error: {e}")

if __name__ == "__main__":
    app = Menu13App()
    app.mainloop()