## Autumn Equinox

### September 21, 2012

We already have most of what we need: a previous exercise provides functions to calculate sunrise and sunset times, and the Standard Prelude provides functions that translate dates to integers. All we need to do is extend the functions from the Standard Prelude to handle times, which we do by adding fractions of the 24 × 60 × 60 = 86400 seconds in a day:

```(define (julian year month day hour minute second)   (let* ((a (quotient (- 14 month) 12))          (y (+ year 4800 (- a)))          (m (+ month (* 12 a) -3)))     (+ day (/ hour 24) (/ minute 24 60) (/ second 24 60 60)        (quotient (+ (* 153 m) 2) 5)        (* 365 y)        (quotient y 4)        (- (quotient y 100))        (quotient y 400)        (- 32045))))```

```(define (gregorian julian)   (let* ((j (floor julian))          (hms (* (- julian j) 24 60 60))          (hour (floor (/ hms 60 60)))          (hms (- hms (* hour 60 60)))          (minute (floor (/ hms 60)))          (second (- hms (* minute 60)))          (j (+ j 32044))          (g (quotient j 146097))          (dg (modulo j 146097))          (c (quotient (* (+ (quotient dg 36524) 1) 3) 4))          (dc (- dg (* c 36524)))          (b (quotient dc 1461))          (db (modulo dc 1461))          (a (quotient (* (+ (quotient db 365) 1) 3) 4))          (da (- db (* a 365)))          (y (+ (* g 400) (* c 100) (* b 4) a))          (m (- (quotient (+ (* da 5) 308) 153) 2))          (d (+ da (- (quotient (* (+ m 4) 153) 5)) 122))          (year (+ y (- 4800) (quotient (+ m 2) 12)))          (month (+ (modulo (+ m 2) 12) 1))          (day (+ d 1)))     (values year month day hour minute second)))```

```(define (duration j-start j-finish)   (if (< j-finish j-start) (duration j-finish j-start)     (let* ((diff (- j-finish j-start))            (days (floor diff))            (hms (* (- diff days) 24 60 60))            (hours (floor (/ hms 60 60)))            (hms (- hms (* hours 60 60)))            (minutes (floor (/ hms 60)))            (seconds (- hms (* minutes 60))))       (values days hours minutes seconds))))```

To be complete, we wrote the `gregorian` function of the Standard Prelude, even though it is not necessary for today’s exercise. Then it is easy to calculate the length of the day:

```> (call-with-values     (lambda () (solar 0 0 2012 9 21 0))     (lambda (set rise)       (let* ((start-hour (string->number (car (string-split #\: rise))))              (finish-hour (string->number (car (string-split #\: set))))              (start-minute (string->number (cadr (string-split #\: rise))))              (finish-minute (string->number (cadr (string-split #\: set)))))         (duration (julian 2012 9 21 start-hour start-minute 0)                   (julian 2012 9 21 finish-hour finish-minute 0))))) 0 11 53 0```

That’s 0 days, 11 hours, 53 minutes, and 0 seconds. Oops. Our sunrise/sunset calculation is imprecise. But at least we can now handle times as well as dates in our standard library functions.

You can run the program at http://programmingpraxis.codepad.org/lb9mRWuW.

Pages: 1 2

### 4 Responses to “Autumn Equinox”

1. Mike said

Day and night are (more or less) equal length at the equator all year round. I think you mean day and night are also equal everywhere else!

2. programmingpraxis said

Hmmm. You’re right.

I just looked at the morning newspaper. Where I am, in St Louis, Missouri, USA, today will be 12:10 of sunlight.

Am I getting my astronomy wrong?

I just sent an email to the local weatherman. We’ll see what he has to say.

3. programmingpraxis said