func bigD(y int) int { C := base.FloorDiv(y, 100) var S int if y >= 1583 { S = base.FloorDiv(3*C-5, 4) } a := (12*y + 12) % 19 b := y % 4 Q := -1.904412361576 + 1.554241796621*float64(a) + .25*float64(b) - .003177794022*float64(y) + float64(S) fq := math.Floor(Q) iq := int(fq) j := (iq + 3*y + 5*b + 2 - S) % 7 r := Q - fq var D int switch { case j == 2 || j == 4 || j == 6: D = iq + 23 case j == 1 && a > 6 && r >= .63287037: D = iq + 24 case j == 0 && a > 11 && r >= .897723765: D = iq + 23 default: D = iq + 22 } return D }
// JulianToGregorian converts a Julian calendar year and day number to a year, month, and day in the Gregorian calendar. func JulianToGregorian(y, dn int) (gY, gM, gD int) { JD := base.FloorDiv(36525*(y-1), 100) + 1721423 + dn α := base.FloorDiv(JD*100-186721625, 3652425) β := JD if JD >= 2299161 { β += 1 + α - base.FloorDiv(α, 4) } b := β + 1524 return ymd(b) }
// GregorianToJulian takes a year, month, and day of the Gregorian calendar and returns the equivalent year, month, and day of the Julian calendar. func GregorianToJulian(y, m, d int) (jy, jm, jd int) { if m < 3 { y-- m += 12 } α := base.FloorDiv(y, 100) β := 2 - α + base.FloorDiv(α, 4) b := base.FloorDiv(36525*y, 100) + base.FloorDiv(306001*(m+1), 10000) + d + 1722519 + β return ymd(b) }
// CalendarGregorianToJD converts a Gregorian year, month, and day of month // to Julian day. // // Negative years are valid, back to JD 0. The result is not valid for // dates before JD 0. func CalendarGregorianToJD(y, m int, d float64) float64 { switch m { case 1, 2: y-- m += 12 } a := base.FloorDiv(y, 100) b := 2 - a + base.FloorDiv(a, 4) // (7.1) p. 61 return float64(base.FloorDiv64(36525*(int64(y+4716)), 100)) + float64(base.FloorDiv(306*(m+1), 10)+b) + d - 1524.5 }
// JDToCalendar returns the calendar date for the given jd. // // Note that this function returns a date in either the Julian or Gregorian // Calendar, as appropriate. func JDToCalendar(jd float64) (year, month int, day float64) { zf, f := math.Modf(jd + .5) z := int64(zf) a := z if z >= 2299151 { α := base.FloorDiv64(z*100-186721625, 3652425) a = z + 1 + α - base.FloorDiv64(α, 4) } b := a + 1524 c := base.FloorDiv64(b*100-12210, 36525) d := base.FloorDiv64(36525*c, 100) e := int(base.FloorDiv64((b-d)*1e4, 306001)) // compute return values day = float64(int(b-d)-base.FloorDiv(306001*e, 1e4)) + f switch e { default: month = e - 1 case 14, 15: month = e - 13 } switch month { default: year = int(c) - 4716 case 1, 2: year = int(c) - 4715 } return }
func ymd(b int) (y, m, d int) { c := base.FloorDiv(b*100-12210, 36525) d = base.FloorDiv(36525*c, 100) // borrow the variable e := base.FloorDiv((b-d)*10000, 306001) // compute named return values d = b - d - base.FloorDiv(306001*e, 10000) if e < 14 { m = e - 1 } else { m = e - 13 } if m > 2 { y = c - 4716 } else { y = c - 4715 } return }
// CalendarJulianToJD converts a Julian year, month, and day of month to Julian day. // // Negative years are valid, back to JD 0. The result is not valid for // dates before JD 0. func CalendarJulianToJD(y, m int, d float64) float64 { switch m { case 1, 2: y-- m += 12 } return float64(base.FloorDiv64(36525*(int64(y+4716)), 100)) + float64(base.FloorDiv(306*(m+1), 10)) + d - 1524.5 }
// JulianToMoslem takes a year, month, and day of the Julian calendar and returns the equivalent year, month, and day of the Moslem calendar. func JulianToMoslem(y, m, d int) (my, mm, md int) { W := 2 if y%4 == 0 { W = 1 } N := base.FloorDiv(275*m, 9) - W*base.FloorDiv(m+9, 12) + d - 30 A := y - 623 B := base.FloorDiv(A, 4) C2 := func(A int) int { C := A % 4 C1 := 365.25001 * float64(C) C2 := math.Floor(C1) if C1-C2 > .5 { return int(C2) + 1 } return int(C2) }(A) Dp := 1461*B + 170 + C2 Q := base.FloorDiv(Dp, 10631) R := Dp % 10631 J := base.FloorDiv(R, 354) K := R % 354 O := base.FloorDiv(11*J+14, 30) H := 30*Q + J + 1 JJ := K - O + N - 1 days := 354 if MoslemLeapYear(y) { days++ } if JJ > days { JJ -= days H++ } if JJ == 355 { mm = 12 md = 30 } else { S := base.FloorDiv((JJ-1)*10, 295) mm = 1 + S md = base.FloorDiv(10*JJ-295*S, 10) } return H, mm, md }
func ExampleFloorDiv() { // compare to / operator examples in Go spec at // https://golang.org/ref/spec#Arithmetic_operators fmt.Println(base.FloorDiv(+5, +3)) fmt.Println(base.FloorDiv(-5, +3)) fmt.Println(base.FloorDiv(+5, -3)) fmt.Println(base.FloorDiv(-5, -3)) fmt.Println() // exact divisors, no remainders fmt.Println(base.FloorDiv(+6, +3)) fmt.Println(base.FloorDiv(-6, +3)) fmt.Println(base.FloorDiv(+6, -3)) fmt.Println(base.FloorDiv(-6, -3)) // Output: // 1 // -2 // -2 // 1 // // 2 // -2 // -2 // 2 }
// MoslemToJulian converts a Moslem calandar date to a Julian year and day number. func MoslemToJulian(y, m, d int) (jY, jDN int) { N := d + base.FloorDiv(295001*(m-1)+9900, 10000) Q := base.FloorDiv(y, 30) R := y % 30 A := base.FloorDiv(11*R+3, 30) W := 404*Q + 354*R + 208 + A Q1 := base.FloorDiv(W, 1461) Q2 := W % 1461 G := 621 + 28*Q + 4*Q1 K := base.FloorDiv(Q2*10000, 3652422) E := base.FloorDiv(3652422*K, 10000) J := Q2 - E + N - 1 X := G + K switch { case J > 366 && X%4 == 0: J -= 366 X++ case J > 365 && X%4 > 0: J -= 365 X++ } return X, J }