Daylight puzzle


On last year’s winter solstice, Stephen Turner tweeted:

@sret OK, who can explain (in 140 chars) why shortest day in Cambridge + longest day in Cambridge = 24 hr 30 min, not 24 hr exactly?

Let’s check that. In 2010, according to (and similar sites), the longest and shortest days are:


which add up to 24:28:49. The first question is, can I trust these tables? Short of hanging around with a coelostat in midwinter, hoping for the (rather unlikely in Cambridge) event of a cloudless sunrise, the best I can do is to check them out with some ephemeris software. I picked the Python module ephem, which is a wrapper around the numerical routines from the xephem package.

>>> from ephem import *
>>> cambridge = Observer()
>>> = degrees('52:12:29')
>>> cambridge.long = degrees('00:07:21')
>>> sun = Sun()
>>> cambridge.next_rising(sun, start='2010/06/21')
2010/6/21 03:37:36
>>> cambridge.next_setting(sun, start='2010/06/21')
2010/6/21 20:24:56
>>> cambridge.next_rising(sun, start='2010/12/21')
2010/12/21 08:05:51
>>> cambridge.next_setting(sun, start='2010/12/21')
2010/12/21 15:49:13

That looks close enough. The summer rise and set times differ by an hour between ephem and because the former always reports times in UTC, while the latter uses local time (UTC+1 in summer).

You might well ask, why is this a puzzle at all? Why should the daylight on the longest and shortest days add up to 24 hours? Let’s start with the observation that sunrise and sunset move by less than a second per day at the solstices, so for a day d near the solstices, the length of the day plus night is within a second or so of 24 hours:

day(Cambridge, d) + night(Cambridge, d) ~ 24 hours

Now, suppose that Cambridge had an antipodean partner, Anti-Cambridge. Under the simplifying assumption that the sun always lights up an exact hemisphere, it’s always light in Cambridge when it’s dark in Anti-Cambridge, and vice versa:

On a solstice d,

night(Cambridge, d) ~ day(Anti-Cambridge, d)

and vice versa. Also, as shown in the diagram, a rotation of 180° maps Cambridge to Anti-Cambridge and June to December. So

day(Anti-Cambridge, June 21) ~ day(Cambridge, December 21)

Putting all these together,

day(Cambridge, June 21) + night(Cambridge, June 21) ~ 24 hours
∴ day(Cambridge, June 21) + day(Anti-Cambridge, June 21) ~ 24 hours
∴ day(Cambridge, June 21) + day(Cambridge, December 21) ~ 24 hours

Presented like this, it should be clear that it’s the simplifying assumption that’s faulty: the sun lights up more than a hemisphere, so that sometimes it is day simultaneously at Cambridge and its antipode. There are two reasons why the assumption is faulty, and so I replied to Stephen:

@sret Sun has positive diameter; also refraction advances sunrise and delays sunset.

The point being that “sunrise” and “sunset” are defined as the times when the upper limb (not the centre) of the sun touches the horizon, and the atmosphere bends the sunlight round the earth, so that when the sun appears to touch the horizon, it’s actually well below it. Refraction depends on the temperature, pressure, moisture content, and layer structure of the atmosphere, so it varies from day to day and even hour to hour. But sunrise/sunset tables (necessarily) ignore this complexity by using a nominal value for the refraction, and for a city like Cambridge that’s close to sea level, the nominal value is 34 minutes of arc at the horizon.

When the sun appears to touch the horizon, it’s really around 34′ below the horizon.

So does this explain the half-hour discrepancy? I’ve always believed that you don’t really understand something until you can at least roughly calculate it.

Let’s try a back-of-the-envelope calculation. The sun travels 360° across the sky in 24 hours, so its speed is 15° per hour, or 15′ per minute.* So the extra 50′ are covered in 3:20. Multiply this by the four horizon-crossings we’re accounting for (sunrise and sunset on summer and winter solstices), gives 13:20. But that’s less than half the discrepancy. So what’s wrong with this calculation? Well, the sun does not rise and set vertically, but at an oblique angle.

To find this angle, we need a bit of spherical trigonometry known as the ‘PZS triangle’ (and permutations thereof). Let \(Z\) be the zenith (the position on the celestial sphere vertically above Cambridge), \(P\) be the north celestial pole (the position on the celestial sphere vertically above the north pole), and \(S\) be the position on the celestial sphere of the sun as it rises (or sets).

The path of the sun is always perpendicular to the line between the sun and the celestial pole (the “hour line”), so the angle that the path makes with the horizon is \(∠ZSP\). Now \(ZS\) = 90° by definition of the horizon, \(ZP = 90° − L\), where \(L\) is the latitude of Cambridge (52°12′29″), and \(PS = 90° − D\), where \(D\) is the declination of the sun, which is 23°26′ on June 21 and −23°26′ on December 21. The spherical law of cosines says: $$ \cos(∠ZSP) = {\cos(ZP) − \cos(ZS) \cos(PS) \over \sin(ZS) \sin(PS) }. $$ In this problem, \(ZS = 90°\), so \(\cos(ZS) = 0\) and \(\sin(ZS) = 1\). Also, \(ZP = 90° − L\), so \(\cos(ZP) = \sin(L)\), and \(PS = 90° − D\), so \(\sin(PS) = \cos(D)\). So the formula simplifies to $$ \cos(∠ZSP) = { \sin(L) \over \cos(D) }. $$ Let’s try this in Python. First, for the summer solstice, when the sun is at its highest declination:

>>> from math import cos, sin, acos, asin
>>> L =
>>> D = degrees('23:26')
>>> degrees(acos(sin(L) / cos(D)))

And then for the winter solstice, when the sun is at its lowest declination:

>>> degrees(acos(sin(L) / cos(-D)))

These are the same because cosine is symmetric about 0°. (This surprised me: I had always vaguely imagined that the sun rose more steeply in summer. This suggests I need to get up earlier in the morning!) How long is the oblique path of the sun? It’s the side labelled \(c\) of the right spherical triangle in this figure:

Here \(A = ∠ZSP\), the angle the path of the sun makes with the horizon, and \(a = 50′\) is the displacement of the true (unrefracted) centre of the sun from the horizon at sunrise. Napier’s rules give $$ \sin(c) = { \sin(a) \over \sin(A) }. $$

>>> A = degrees('30:32:23.3')
>>> a = degrees('00:50')
>>> degrees(asin(sin(a) / sin(A)))

In fact, the displacement is so small that a planar approximation would be good enough here:

>>> degrees(a / sin(A))
>>> hours(_) # Time for sun to traverse an arc of this length
>>> hours(_ * 4) # For the four horizon-crossings

Tantalizingly close, but still not there. So clearly I don’t really understand this problem. What have I missed?

* Francis Davey helpfully pointed out that I have been assuming that the sun moves with constant angular velocity of 15° per hour. But that’s only true at the equinoxes: in general the sun’s angular velocity varies like the cosine of the declination. So my calculation should be:

>>> degrees(asin(sin(a) / sin(A)))
>>> hours(_ * 4 / cos(D))

which is within 13 seconds of the value I need. Close enough! How could I state the solution in 140 characters? Perhaps like this: