Passover

March 30, 2010

Here is our calculation of the date of Rosh Hashanah:

(define (rosh-hashanah year)
  (let* ((g (+ (remainder year 19) 1))
         (r (remainder (* 12 g) 19))
         (n (+ (- (quotient year 100) (quotient year 400) 2)
               (* 765433 r 1/492480)
               (/ (remainder year 4) 4)
               (- (/ (+ (* 313 year) 89081) 98496))))
         (d (quotient (numerator n) (denominator n)))
         (f (- n d))
         (j (julian year 9 d)))
    (case (modulo j 7)
      ((2 4 6) (+ j 1))
      ((0) (if (and (>= f 23269/25920) (> r 11)) (+ j 1) j))
      ((1) (if (and (>= f 1367/2160) (> r 6)) (+ j 2) j))
      (else j))))

In the let, g is the golden number (the number of the year in the 19-year metonic cycle), n is the calculation given above, d and f are the day and fraction portions of n, respectively, and r and j are temporary variables. The calculation of the date of Passover is simple:

(define (passover year)
  (let-values (((y m d) (gregorian (rosh-hashanah year))))
    (let ((j (julian year 3 21)))
      (if (= m 9) (+ j d) (+ j d 30)))))

For example:

> (gregorian (passover 2010))
2010
3
30

We used julian and gregorian from the Standard Prelude. You can run the program at http://programmingpraxis.codepad.org/dPbrwFze.

Advertisement

Pages: 1 2

3 Responses to “Passover”

  1. […] Praxis – Passover By Remco Niemeijer In today’s Programming Praxis exercise we have to write functions to calculate the dates of the Jewish […]

  2. Remco Niemeijer said

    My Haskell solution (see http://bonsaicode.wordpress.com/2010/03/30/programming-praxis-passover/ for a version with comments):

    import Data.Time.Calendar
    import Data.Time.Calendar.WeekDate
    import Data.Fixed
    
    roshDay :: Integer -> Integer
    roshDay year | elem d [3,5,7] = n + 1
                 | d == 1 && f >= 23269/25920 && r > 11 = n + 1
                 | d == 2 && f >= 1367/2160   && r > 6 = n + 2
                 | otherwise = n
        where
        y = fromIntegral year
        g = mod' y 19 + 1
        r = mod' (12 * g) 19
        a // b = fromIntegral $ floor (a / b)
        (n, f) = properFraction (y // 100 - y // 400 - 2 +
                                 765433/492480 * r + mod' y 4 / 4 -
                                 (313 * y + 89081) / 98496)
        (_,_,d) = toWeekDate . addDays n $ fromGregorian year 8 31
    
    roshHashanah :: Integer -> Day
    roshHashanah year = addDays (roshDay year) (fromGregorian year 8 31)
    
    passover :: Integer -> Day
    passover year = addDays (roshDay year) (fromGregorian year 3 21)
    
  3. Mike said

    Python:

    from math import floor
    from datetime import date, timedelta
    
    def rosh_hashanah(year):
        g = year % 19 + 1
        r = 12*g % 19
    
        v =  ( floor( year / 100.0 ) - floor( year / 400.0 ) - 2 )
        v += 765433.0 * r / 492480
        v += ( year % 4 ) / 4.0
        v -= ( 313.0 * year + 89081 ) / 98496
    
        n = int(v)
        f = v - n
    
        # Monday .. Sunday = 0..6
        dow = ( date( year, 8, 31 ).weekday() + n ) % 7
    
        if dow in (2,4,6):
            n += 1
        elif dow == 0 and f >= 23269.0 / 25920 and r > 11:
            n += 1
        elif dow == 1 and f >= 1367.0 / 2160 and r > 6:
            n += 2
    
        return n
    
    def passover(year):
        return date(year,3,21) + timedelta(rosh_hashanah(year))
    

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: