export type JulianMonth = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12; export type JulianDay = | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31; export type JulianDate = [number, JulianMonth, JulianDay]; const monthNames: { [key in JulianMonth]: string } = { 1: 'January', 2: 'February', 3: 'March', 4: 'April', 5: 'May', 6: 'June', 7: 'July', 8: 'August', 9: 'September', 10: 'October', 11: 'November', 12: 'December', }; export const weekdayNames = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', ]; export function gregorianJDN(year: number, month: number, day: number, julian_before?: number): number { const g = year + 4716 - (month <= 2 ? 1 : 0); const f = (month + 9) % 12; const e = Math.floor(1461 * g / 4) + day - 1402; const J = e + Math.floor((153 * f + 2) / 5); if (julian_before != null && J < julian_before) return J; const dg = 38 - Math.floor(Math.floor((g + 184) / 100) * 3 / 4); return J + dg; } export function dateJDN(date: Date, julian_before?: number) { return gregorianJDN(date.getFullYear(), date.getMonth() + 1, date.getDate(), julian_before); } export function jdnGregorian(jdn: number, julian_before?: number): JulianDate { const dg = julian_before == null || jdn >= julian_before ? Math.floor(Math.floor((4 * jdn + 274277) / 146097) * 3 / 4) - 38 : 0; const e = 4 * (jdn + 1401 + dg) + 3; const h = 5 * Math.floor((e % 1461 + 1461) % 1461 / 4) + 2; const day = Math.floor((h % 153 + 153) % 153 / 5) + 1; const month = (Math.floor(h / 153) + 2) % 12 + 1; const year = Math.floor(e / 1461) - 4716 + Math.floor((14 - month) / 12); return [year, month as JulianMonth, day as JulianDay]; } export function jdnDate(jdn: number, julian_before?: number): Date { const [year, month, day] = jdnGregorian(jdn, julian_before); return new Date(year, month - 1, day); } export function monthName(month: JulianMonth): string { return monthNames[month]; } export function gregorianMonthDays(year: number, month: JulianMonth, julian = false): 28 | 29 | 30 | 31 { switch (month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: return 31; case 4: case 6: case 9: case 11: return 30; case 2: if (year % 4 !== 0) return 28; if (!julian && (year % 100 === 0 && year % 400 !== 0)) return 28; return 29; } } export function formatJG([year, month, day]: [number, JulianMonth, JulianDay]): string { const m = monthNames[month].substring(0, 3); return `${m} ${day} ${year}`; }