Analemmas
Last week I listened to an episode of The Sceptics' Guide to the Universe where the word of the week was "analemma". An analemma is a diagram showing the position of the Sun in the sky over the course of a year, as viewed at a fixed time of day from the same location on Earth. I once tried to make such a diagram when I was still living in Norway from a series of photos, but the weather wasn't consistent enough to make that work.
But as I am currently starting to update the Guide to Date and Time Programming for a second edition, I was wondering whether I could create an analemma from existing PHP functions. Unfortunately, PHP only provides functionality to calculate when the Sun is at its highest point, through date_sun_info():
<?php
$sunInfo = date_sun_info(
(new DateTimeImmutable())->getTimestamp(), // Unix timestamp
51.53, // latitude
-0.19 // longitude
);
$zenith = new DateTimeImmutable( "@{$sunInfo['transit']}" );
echo $zenith->format( DateTimeImmutable::ISO8601 ), "\n";
?>
Which on February 26th, was at 2018-02-26T12:13:38+0000 in London.
Then I remembered that a few years ago I wrote Where is the Sun?. There I features a new hobby library "astro" that I was working on. This library implements a few astronomical calculations. I wrote a little PHP extension around it too: php-solarsystem. Neither library or extension have really been released.
The php-solarsystem extension implements just one function: earth_sunpos(), which fortunately does exactly what I needed for drawing an analemma: it gives you the position of the Sun in the sky for a specific location on Earth at a specific time.
With this function, all I had to do is calculate the position of the Sun in the sky at the same time-of-day for a whole year. With the DatePeriod class in PHP, I can easily create an iterator that does just that:
<?php
date_default_timezone_set( "UTC" );
$dateStart = new DateTimeImmutable( "2018-01-01 09:00" );
$dateEnd = $dateStart->modify( "+1 year 1 day" );
$dateInterval = new DateInterval( "P1D" );
foreach ( new DatePeriod( $dateStart, $dateInterval, $dateEnd ) as $date )
{
…
}
?>
We don't really want Daylight Saving Time to be in the way, so we set the time zone to just UTC, which works fine for London for which we'll draw the analemma.
We start at the start of the year (2018-01-01 09:00) and iterate for a year and a day (+1 year 1 day) so we can create a closed loop. Each iteration increases the returned DateTimeImmutable by exactly one day (P1D).
After defining the latitude and longitude of London, all we need to do is to use the earth_sunpos() function to calculate the azimuth and altitude inside the loop. Azimuth is the direction of where the Sun is, with 180° being due South. And altitude is the height of the Sun above the horizon.
$lat = 51.53;
$lon = -0.09;
foreach ( new DatePeriod( $dateStart, $dateInterval, $dateEnd ) as $date )
{
$ts = $date->format( 'U' );
$position = earth_sunpos( $ts, $lat, $lon );
echo $ts, "\n";
echo $position['azimuth'], ",";
echo $position['altitude'], "\n";
}
The script outputs the calculation as a "CSV", which we should redirect to a file:
php tests/analemma.php > /tmp/analemma.csv
To plot we use the following gnuplot script:
set style line 1 lt 1 lw 2 pt 0 ps 0 linecolor rgb "orange" set style line 2 lt 1 lw 1 pt 0 ps 0 linecolor rgb "grey" set datafile separator comma set xrange [100:150] set yrange [0:50] set grid linestyle 2 set terminal png size 640,640 enhanced font "Helvetica,12" set output '/tmp/analemma.png' plot "/tmp/analemma.csv" using 2:3 title "London @ 9 am" with linespoints linestyle 1
With this script, we can then draw the analemma:
gnuplot /tmp/analemma.plot
The result:
Credits
Analemma — Derick Rethans
Life Line
In more info innocent times, the hat riots caused some spankings...
100 Years Ago Men and Boys Fought on the Streets of New York Over Wearing Straw Hats Past Summer | The New York Public Library
https://www.nypl.org/blog/2022/09/23/straw-hat-riots-nycI hiked 15.5km in 3h12m14s
📷 Mushroom Village
🚩 Weg van den Prins Willemsberg, Ellecom, Nederland
I walked 2.4km in 59m34s
📷 National Cycle Network 6
🚩 Watford, United Kingdom
I walked 7.6km in 1h54m50s
📷 Tufted Duck Pair
🚩 Outer Circle, City of Westminster, United Kingdom
RE: https://phpc.social/@Xdebug/115662135830755552
I have just released Xdebug 3.5.0!
In the next few weeks I will create some content (text, and perhaps video) highlighting some new features in more detail.
Please share it with the world!
The master branch is now for Xdebug 3.6, targetting PHP 8.6
Back to -dev
Tweak release instructions a little
Go with 3.5.0
Tweak message IDs and severities for control socket log entries
I walked 8.1km in 1h26m40s
I walked 1.1km in 9m28s
I walked 8.5km in 1h30m56s
My whisky of the month for December 2025, is a 15yo Aultmore bottled by Cadenhead's.
Fixed off-by-one error in address length name for control socket on L…
Merged pull request #1050
Fixed control socket name by removing silly trailing things (by not p…




Shortlink
This article has a short URL available: https://drck.me/analemma-dyu