I counted the number of visible sunsets with Ruby
Tags: ruby, webdev, astronomy
Published: 2024-04-02 12:30:24

I live in a flat in the city. There are buildings around me, so I'm not exposed to direct Sunlight all day long.

My living room is West-facing, but when I moved there I quickly discovered that I wasn't able to enjoy and beautiful sunset every day (if you exclude the fact that the weather in Paris is 💩). This could look counter-intuitive. We learn in school that the Sun rises in the East and sets in the West. So first, let's have a quick recap about the apparent motion of the Sun in the sky.

## Axis tilt and seasons

<small>Credit: [timeanddate.com](https://www.timeanddate.com/astronomy/axial-tilt-obliquity.html)</small>
![Earth obliquity represented on the globe with the equator and the ecliptic plane](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2akkezwsgyk2o8tkpliy.png)

The Earth orbits around the Sun. But the Earth's rotation axis is not perpendicular to the orbits' plane, we call this angle the **axial tilt**, or **obliquity**.

The axial tilt is approximately 23.44°. It slightly changes throughout millennials, but this has no impact on the rest of this article.

This angle is responsible for the seasons we encounter on Earth, especially in temperate regions. One hemisphere is always more exposed to the rays of the Sun than the other one, except for the two equinoxes.

The other consequence is the apparent motion of the Sun in the sky. The duration of sunlight exposure is higher in the summer than in the winter, but the Earth always rotates at the same speed: this means **the Sun appears higher in the sky during the summer than in the winter**.

## Evolution of the Sun's azimuth

<small>Credit: [Between Solstices by György Soponyaim](https://www.rmg.co.uk/stories/topics/summer-winter-solstices-explained-how-sun-determines-longest-shortest-days-year)</small>
![Different locations of the Sun in the sky during both solstices and both equinoxes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9p2a4m9qb6n4zfhxgeq3.png)

The Sun rises almost exactly in the East and almost exactly in the West only during the days of equinoxes. The rest of the year, the **azimuth** of these phenomena changes over time.

The azimuth is the angle with the North direction on the horizontal plane, or more simply the horizon for an observer. So, the Sun's azimuth is its **location on the horizontal axis**.

During the summer, the Sun rises and sets more in the North direction. For example, from Paris, during the June solstice, the Sun rises at 51° (or North-East) and sets at 308° (or North-West). During the December solstice, it rises at 126° (or South-East) and sets at 233° (or South-West).

This difference in time is highly influenced by the observer's latitude. At the equator, the azimuth difference between the two solstices is less than 50°, while it's more than 100° in northern locations like Oslo.

## Observing the sunset from my living room

After all this explanation, let's get back to business.

From my living room, the South direction is obstructed by a large building. For a significant part of the year, the Sun sets behind it. To be more precise, as long as the sunset azimuth is too much in the South, the Sun is hidden.

As you might know, I am building a Ruby gem called [`astronoby`] to compute astronomical phenomena. I recently released a new version that includes information about the Sun, and the sunset azimuth is part of it.

[`astronoby`]: https://github.com/rhannequin/astronoby

I approximately estimated the border of the building to be 273° on the horizon, when I sit on my couch. In theory, as long as the sunset azimuth is greater than 273°, it should not be hidden by the building.

With `astronoby`, I can compute the sunset azimuth of each day of the year and select only those within the limit of visibility for me.

```rb
require "astronoby"

# Actual coordinates hidden for privacy reasons
observer = Astronoby::Observer.new(
  latitude: Astronoby::Angle.from_degrees(2),
  longitude: Astronoby::Angle.from_degrees(48),
  elevation: 40
)

azimuth_limit = Astronoby::Angle.from_degrees(273)
range = (Date.new(2024, 1, 1)..Date.new(2024, 12, 31))

visible_dates = range.to_a.select do |date|
  noon = Time.utc(date.year, date.month, date.day, 12, 0, 0)
  epoch = Astronoby::Epoch.from_time(noon)
  sun = Astronoby::Sun.new(epoch: epoch)
  setting_azimuth = sun.setting_azimuth(observer: observer)

  setting_azimuth > azimuth_limit
end

dates.first.to_s
# => "2024-03-26"

dates.last.to_s
# => "2024-09-16"
```

## Final results

In theory, if the weather is fine, I should be able to enjoy a nice sunset from my living room couch from the 26th of March to the 16th of September.

The Ruby part of this article might feel a bit disappointing, we spent two sections talking about astronomy while the dates can be computed in barely 10 lines of code. This is however an opportunity for me to brag and share that the `astronoby` library is powerful.

Knowing the location of the Sun in the sky at any time as an observer anywhere in the world has many applications. From the Sun's exposure to the quantity of energy received from the sky, the `astronoby` gem opens new doors to Ruby developers.

---

<small>Cover picture credits: [_Dramatic City Sunset Sky Pro Vector by John Alberton_](https://www.vecteezy.com/vector-art/2042714-dramatic-city-sunset-sky)</small>