package hijricalendar import ( "fmt" "math" "time" ) // JulianToIslamic converts a Julian calendar date to the Islamic (Hijri) calendar. // Algorithm from Jean Meeus, "Astronomical Algorithms", 2nd ed. func JulianToIslamic(year, month, day int) (iYear, iMonth, iDay int) { jdn := julianToJDN(year, month, day) return jdnToIslamic(jdn) } // GregorianToIslamic converts a Gregorian calendar date to the Islamic (Hijri) // calendar. func GregorianToIslamic(year, month, day int) (iYear, iMonth, iDay int) { jdn := gregorianToJDN(year, month, day) return jdnToIslamic(jdn) } // julianToJDN returns the Julian Day Number for a date on the Julian calendar. func julianToJDN(year, month, day int) int { y, m := year, month if m <= 2 { y-- m += 12 } return int(math.Floor(365.25*float64(y+4716))) + int(math.Floor(30.6001*float64(m+1))) + day - 1524 } func gregorianToJDN(year, month, day int) int { a := (14 - month) / 12 y := year + 4800 - a m := month + 12*a - 3 return day + (153*m+2)/5 + 365*y + y/4 - y/100 + y/400 - 32045 } // jdnToIslamic converts a Julian Day Number to an Islamic (Hijri) calendar date. // Source: F. de Moya, as cited in Meeus Ch. 9. func jdnToIslamic(jd int) (year, month, day int) { l := jd - 1948440 + 10632 n := (l - 1) / 10631 l = l - 10631*n + 354 j := (10985-l)/5316*(50*l/17719) + (l/5670)*(43*l/15238) l = l - (30-j)/15*(17719*j/50) - (j/16)*(15238*j/43) + 29 year = 30*n + j - 30 month = (24 * l) / 709 day = l - (709*month)/24 return } func ToISODate(t time.Time) string { year, month, day := t.UTC().Date() hYear, hMonth, hDay := GregorianToIslamic(year, int(month), day) return fmt.Sprintf("%04d-%02d-%02d", hYear, hMonth, hDay) }