You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

62 lines
1.7 KiB
Go

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)
}