Me and my friend were watching the sunset on the same location (at my country the latitude is approximately 40 degrees). I am at sea level and my friend is at an elevation. He observed the sunset with a difference of about 4 minutes than me. He is a physicist so he challenged me to find out his elevation. Any ideas on how to use these information and win the challenge? I found some information on Wikipedia here but cannot understand a lot. Any idea on how to solve this will be appreciated. Thanks in advance for your help.
$\begingroup$ You need to be a bit more precise in where your problem is - especially as you already point to an explanation. We cannot write here an entire book on the issue, guessing where your actual problem in understanding the issue lies. $\endgroup$– planetmakerJun 11, 2020 at 12:38
1$\begingroup$ @uhoh yes, that was my assumption too. As a matter of fact, burj khalifa would be high enough for a 4 min delay. $\endgroup$– Eric DuminilJun 12, 2020 at 14:48
1$\begingroup$ @uhoh okay. I removed the comment since I explain the assumptions in my answer. It would still be nice to have some more information from OP $\endgroup$– Eric DuminilJun 12, 2020 at 15:04
$\begingroup$ @EricDuminil hopefully they will, although they are "just a guest" perhaps they'll stop by again and clarify this and ask another! :-) $\endgroup$– uhohJun 12, 2020 at 15:06
The page you refer to is about sunrise/sunset throughout the year, but what you really care about is differences in the geometry on one day. This is sometimes expressed as different observers seeing the horizon at different distances, or sometimes as an angle, a “dip” of the horizon when seen from higher altitude. Thinking about that geometry should get you started on working out the answer.
Let's assume your friend and yourself are at the exact same coordinates but at different altitudes (e.g. right at the edge of a cliff or in the same building but on different floors).
Both latitude and longitude influence the time of sunset, so if you and your friend are at different locations, you don't have enough information to answer the question.
Astral seems like an interesting library for your task:
Astral is a python package for calculating the times of various aspects of the sun and phases of the moon.
It takes observer's elevation into account :
The times of the sun that you experience depend on what obscurs your view of it. It may either be obscured by the horizon or some other geographical feature (e.g. mountains)
If what obscures you at ground level is the horizon and you are at a elevation above ground level then the times of the sun depends on how far further round the earth you can see due to your elevation (the sun rises earlier and sets later).
After installing the package (version 2.2.), it's an easy task to calculate sunrise time for a given location and date. I chose Barcelona because it's close to 40°N and at sea-level:
# pip install 'astral==2.2' from astral import LocationInfo, sun from astral.location import Location loc = Location(LocationInfo('Barcelona','Spain', 'Europe/Madrid', 41.3851, 2.1734)) loc.sunset(observer_elevation=0) #=> datetime.datetime(2020, 6, 12, 21, 25, 6, 803485, tzinfo=<DstTzInfo 'Europe/Madrid' CEST+2:00:00 DST>)
The last argument is the elevation. After playing with it for a while, it looks like an observer at 715m elevation will see the sunset 4 minutes later than an observer on the beach:
loc.sunset(observer_elevation=715) # => datetime.datetime(2020, 6, 12, 21, 29, 6, 987591, tzinfo=<DstTzInfo 'Europe/Madrid' CEST+2:00:00 DST>)
The algorithm was buggy in previous versions and has been updated.
Time offset vs elevation
Here's a small diagram. I'm not sure why the curve looks like this:
import matplotlib.pyplot as plt import numpy as np elevations = np.linspace(0, 2000, 1000) sunsets = [(loc.sunset(observer_elevation=z) - loc.sunset(observer_elevation=0)).seconds/60 for z in elevations] ax = plt.subplot() plt.plot(elevations, sunsets, label="Sunset time offset") ax.set_title("Sunset in Barcelona") ax.set_xlabel('Elevation [m]') ax.set_ylabel('Offset [minutes]') plt.show()