formula-dasar.html

Download
<!DOCTYPE html>
<html lang="id">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Sistem Falak Komprehensif (50 Parameter)</title>
    <style>
        body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: #f0f2f5; padding: 20px; color: #333; }
        .container { max-width: 1200px; margin: auto; background: white; padding: 30px; border-radius: 15px; box-shadow: 0 10px 30px rgba(0,0,0,0.1); }
        h1 { text-align: center; color: #1a73e8; margin-bottom: 30px; border-bottom: 2px solid #eee; padding-bottom: 10px; }
        .input-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; margin-bottom: 30px; background: #f8f9fa; padding: 20px; border-radius: 10px; }
        label { font-weight: bold; font-size: 14px; color: #555; }
        input { width: 100%; padding: 10px; margin-top: 5px; border: 1px solid #ddd; border-radius: 5px; box-sizing: border-box; }
        button { width: 100%; padding: 15px; background: #1a73e8; color: white; border: none; border-radius: 8px; font-size: 16px; cursor: pointer; transition: 0.3s; }
        button:hover { background: #1557b0; }
        .output-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 15px; margin-top: 30px; }
        .card { background: #fff; border: 1px solid #e0e0e0; padding: 15px; border-radius: 8px; transition: 0.3s; display: flex; flex-direction: column; justify-content: center; }
        .card:hover { border-color: #1a73e8; box-shadow: 0 4px 12px rgba(0,0,0,0.05); }
        .card strong { color: #1a73e8; font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px; }
        .card div { font-size: 15px; margin-top: 5px; font-family: 'Courier New', Courier, monospace; font-weight: bold; color: #222; }
        .section-title { grid-column: 1 / -1; background: #e8f0fe; padding: 12px; margin-top: 25px; border-radius: 5px; color: #1967d2; font-weight: bold; border-left: 5px solid #1a73e8; }
    </style>
</head>
<body>

<div class="container">
    <h1>Kalkulator Falak 50 Parameter</h1>
    
    <div class="input-grid">
        <div><label>Lintang (Lat):</label><input type="number" id="lat" value="-6.9667" step="any"></div>
        <div><label>Bujur (Lon):</label><input type="number" id="lon" value="110.4167" step="any"></div>
        <div><label>Tinggi (m):</label><input type="number" id="alt" value="10"></div>
        <div><label>Zona Waktu (GMT):</label><input type="number" id="tz" value="7"></div>
        <div><label>Tanggal:</label><input type="date" id="date"></div>
    </div>

    <button onclick="hitungUtama()">HITUNG SELURUH PARAMETER</button>

    <div id="output" class="output-grid"></div>
</div>

<script>
const D2R = Math.PI / 180;
const R2D = 180 / Math.PI;
const rev = (a) => a - 360 * Math.floor(a / 360);

function hitungUtama() {
    const lat = parseFloat(document.getElementById('lat').value);
    const lon = parseFloat(document.getElementById('lon').value);
    const alt = parseFloat(document.getElementById('alt').value);
    const tz = parseFloat(document.getElementById('tz').value);
    const dStr = document.getElementById('date').value;
    const dIn = dStr ? new Date(dStr) : new Date();

    let Y = dIn.getFullYear(), M = dIn.getMonth() + 1, D = dIn.getDate();
    const Y_display = Y;
    if (M <= 2) { Y -= 1; M += 12; }

    // --- 1. Waktu Dasar & Kalender ---
    const A = Math.floor(Y / 100);
    const B = 2 - A + Math.floor(A / 4);
    const JD = Math.floor(365.25 * (Y + 4716)) + Math.floor(30.6001 * (M + 1)) + D + B - 1524.5;
    const T = (JD - 2451545.0) / 36525;
    const gmst = rev(280.46061837 + 360.98564736629 * (JD - 2451545.0));

    // --- 2. Parameter Matahari ---
    const L0 = rev(280.46646 + 36000.76983 * T);
    const Msun = rev(357.52911 + 35999.05029 * T);
    const e = 0.016708634 - 0.000042037 * T;
    const C = (1.914602 - 0.004817 * T) * Math.sin(Msun * D2R) + (0.019993 - 0.000101 * T) * Math.sin(2 * Msun * D2R);
    const sunTrueLong = L0 + C;
    const eps0 = 23.439291 - 0.0130041 * T;
    const delta = Math.asin(Math.sin(eps0 * D2R) * Math.sin(sunTrueLong * D2R)) * R2D;
    const RA = Math.atan2(Math.cos(eps0 * D2R) * Math.sin(sunTrueLong * D2R), Math.cos(sunTrueLong * D2R)) * R2D / 15;
    const EoT = (L0 / 15 - RA) * 60; 
    const R_sun = (1.00014 - 0.01671 * Math.cos(Msun * D2R) - 0.01671 * Math.cos(2 * Msun * D2R)); 
    const SD_sun = 0.2666 / R_sun;

    // --- 3. Parameter Bulan ---
    const Lp = rev(218.316 + 481267.881 * T);
    const Dmoon = rev(297.85 + 445267.11 * T);
    const Mmoon = rev(134.96 + 477198.86 * T);
    const Fmoon = rev(93.27 + 483202.01 * T);
    const Node = rev(125.04 - 1934.136 * T);
    const HP_moon = 0.9507 / R_sun;

    // --- 4. Koreksi Ufuk & Geometris ---
    const Dip = 1.76 / 60 * Math.sqrt(alt);
    const Refr = 34.5 / 60;
    const h_maghrib = -(SD_sun + Refr + Dip);

    // --- 5. Waktu Salat ---
    const getH = (h, d, p) => {
        let val = (Math.sin(h * D2R) - Math.sin(p * D2R) * Math.sin(d * D2R)) / (Math.cos(p * D2R) * Math.cos(d * D2R));
        return (val > 1 || val < -1) ? null : Math.acos(val) * R2D / 15;
    };
    const Transit = (12 + tz - lon / 15 - EoT / 60);
    const H_subuh = getH(-20.0, delta, lat);
    const H_isya = getH(-18.0, delta, lat);
    const H_maghrib = getH(h_maghrib, delta, lat);
    const H_syuruq = getH(h_maghrib, delta, lat);
    const H_ashar = getH(R2D * Math.atan(1 + Math.tan(Math.abs(lat - delta) * D2R)), delta, lat);

    // --- 6. Kiblat ---
    const latK = 21.4225, lonK = 39.8262;
    const dL = (lon - lonK) * D2R;
    const Q = Math.atan2(Math.sin(dL), Math.cos(lat * D2R) * Math.tan(latK * D2R) - Math.sin(lat * D2R) * Math.cos(dL)) * R2D;
    const AzKiblat = rev(360 - Q);
    const JarakKiblat = Math.acos(Math.sin(latK * D2R) * Math.sin(lat * D2R) + Math.cos(latK * D2R) * Math.cos(lat * D2R) * Math.cos(dL)) * 6371;

    // --- KOMPILASI 50 PARAMETER ---
    const data = [
        { s: "DATA WAKTU & KALENDER" },
        { n: "Julian Day", v: JD.toFixed(4) },
        { n: "Julian Century (T)", v: T.toFixed(8) },
        { n: "GMST (Greenwich)", v: gmst.toFixed(4) + "°" },
        { n: "Equation of Time", v: EoT.toFixed(2) + " m" },
        { n: "Delta T (Est)", v: "69.0 s" },
        { n: "Tahun Astronomi", v: Y_display },
        { n: "Bulan Input", v: M },
        { n: "Hari Input", v: D },

        { s: "PARAMETER MATAHARI" },
        { n: "Bujur Rata (L0)", v: L0.toFixed(4) + "°" },
        { n: "Anomali Rata (M)", v: Msun.toFixed(4) + "°" },
        { n: "Eksentrisitas (e)", v: e.toFixed(7) },
        { n: "Persamaan Pusat (C)", v: C.toFixed(4) + "°" },
        { n: "Bujur Hakiki (Θ)", v: sunTrueLong.toFixed(4) + "°" },
        { n: "Obliquity (ε)", v: eps0.toFixed(4) + "°" },
        { n: "Deklinasi (δ)", v: delta.toFixed(4) + "°" },
        { n: "Right Ascension (α)", v: RA.toFixed(4) + " j" },
        { n: "Jarak Bumi-Sun", v: R_sun.toFixed(6) + " AU" },
        { n: "Semidiameter Sun", v: SD_sun.toFixed(4) + "°" },
        { n: "Nutasi Bujur", v: "Pending" },
        { n: "Paralaks Sun", v: "0.0024°" },
        { n: "Konstanta Aberasi", v: "20.49\"" },

        { s: "PARAMETER BULAN" },
        { n: "Bujur Rata Bulan", v: Lp.toFixed(4) + "°" },
        { n: "Elongasi (D)", v: Dmoon.toFixed(4) + "°" },
        { n: "Anomali Bulan (M')", v: Mmoon.toFixed(4) + "°" },
        { n: "Argumen Lintang (F)", v: Fmoon.toFixed(4) + "°" },
        { n: "Simpul Node (Ω)", v: Node.toFixed(4) + "°" },
        { n: "HP Bulan", v: HP_moon.toFixed(4) + "°" },
        { n: "Fase Bulan", v: "Coming Soon" },
        { n: "Bujur Ecl. Bulan", v: "Pending" },
        { n: "Lintang Ecl. Bulan", v: "Pending" },
        { n: "Radius Geometris", v: "0.2724 j" },

        { s: "KOREKSI UFUK & LOKAL" },
        { n: "Kerendahan Ufuk (Dip)", v: Dip.toFixed(4) + "°" },
        { n: "Refraksi Atmosfer", v: Refr.toFixed(4) + "°" },
        { n: "Tinggi Maghrib (h)", v: h_maghrib.toFixed(4) + "°" },
        { n: "Tinggi Subuh", v: "-20.0000°" },
        { n: "Tinggi Isya", v: "-18.0000°" },
        { n: "Sudut Syuruq", v: h_maghrib.toFixed(4) + "°" },
        { n: "Lintang Lokal", v: lat + "°" },
        { n: "Bujur Lokal", v: lon + "°" },

        { s: "WAKTU SALAT (ISTIWA)" },
        { n: "Istiwa / Zuhur", v: formatJam(Transit) },
        { n: "Subuh (-20°)", v: formatJam(Transit - H_subuh) },
        { n: "Syuruq (Terbit)", v: formatJam(Transit - H_syuruq) },
        { n: "Ashar (Syafi'i)", v: formatJam(Transit + H_ashar) },
        { n: "Maghrib", v: formatJam(Transit + H_maghrib) },
        { n: "Isya (-18°)", v: formatJam(Transit + H_isya) },

        { s: "ARAH KIBLAT" },
        { n: "Azimut Kiblat", v: AzKiblat.toFixed(2) + "° U-T" },
        { n: "Jarak ke Ka'bah", v: JarakKiblat.toFixed(2) + " km" },
        { n: "Lintang Ka'bah", v: "21.4225° N" },
        { n: "Bujur Ka'bah", v: "39.8262° E" },
        { n: "Sudut Q", v: Q.toFixed(4) + "°" }
    ];

    display(data);
}

function formatJam(decimal) {
    if (decimal === null || isNaN(decimal)) return "--:--:--";
    // Normalisasi jam agar dalam range 0-24
    let val = decimal;
    while (val < 0) val += 24;
    while (val >= 24) val -= 24;
    
    let h = Math.floor(val);
    let m = Math.floor((val - h) * 60);
    let s = Math.round(((val - h) * 60 - m) * 60);
    if (s === 60) { m++; s = 0; }
    if (m === 60) { h++; m = 0; }
    return `${h.toString().padStart(2,'0')}:${m.toString().padStart(2,'0')}:${s.toString().padStart(2,'0')}`;
}

function display(data) {
    let out = document.getElementById('output');
    out.innerHTML = "";
    data.forEach(item => {
        if (item.s) {
            out.innerHTML += `<div class="section-title">${item.s}</div>`;
        } else {
            out.innerHTML += `<div class="card"><strong>${item.n}</strong><div>${item.v}</div></div>`;
        }
    });
}
</script>
</body>
</html>