feat: Return location info and Hijri date from the prayer times endpoint
parent
07a9703a89
commit
c106d57fe6
@ -0,0 +1,61 @@
|
|||||||
|
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)
|
||||||
|
}
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
package hijricalendar
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestToISODate(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
date time.Time
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "ramadan 3 1447",
|
||||||
|
date: time.Date(2026, 2, 20, 0, 0, 0, 0, time.UTC),
|
||||||
|
want: "1447-09-03",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ramadan 1 1447",
|
||||||
|
date: time.Date(2026, 2, 18, 0, 0, 0, 0, time.UTC),
|
||||||
|
want: "1447-09-01",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := ToISODate(tt.date)
|
||||||
|
require.NotEmpty(t, got)
|
||||||
|
assert.Equal(t, tt.want, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGregorianToIslamicRange(t *testing.T) {
|
||||||
|
y, m, d := GregorianToIslamic(2026, 2, 20)
|
||||||
|
assert.Positive(t, y)
|
||||||
|
assert.GreaterOrEqual(t, m, 1)
|
||||||
|
assert.LessOrEqual(t, m, 12)
|
||||||
|
assert.GreaterOrEqual(t, d, 1)
|
||||||
|
assert.LessOrEqual(t, d, 30)
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue