Message Boards Message Boards


Circular sunset/sunrise calendar

Posted 1 year ago
5 Replies
21 Total Likes

enter image description here

POSTED BY: Sander Huisman
5 Replies

Note that the code will not work for all geolocations; some parts of the world don't have sunsets/sunrise for extended periods of times. For that the code will not work correctly…

POSTED BY: Sander Huisman

I think these other geolocation matters could be managed (up to the error in the model that Mathematica uses to determine sunrise/sunset).

The first change that I'd make would be to my previous suggestion (the second line),

location = $GeoLocationCity; (* set the location*)
tz = location["TimeZone"][[2]]; (* which timezone *)
locationname = location[[2, 1]]; (* name of the location for displaying purposes*)

so that the timezone is determined from the location (which could be provided either via $GeoLocationCity, or otherwise specified (see for Tromso below).

Next, a helper function to "fix" the times for sunrise/sunset for areas outside of the tropics.

fixTropics[raw_] := Module[{dom, sunrise, sunset},
    dom = raw[[1, 3]];(*actual day of month*)
    sunrise = DateList[raw[[2, 1]]][[3]];
    sunset = DateList[raw[[3, 1]]][[3]];
    If[And[dom == sunrise, dom == sunset, sunrise + raw[[2, 2]]/24. < sunset + raw[[3, 2]]/24.],
        raw(*sunrise and sunset on same day, and correct order*),
        ReplacePart[raw, {
            {2, 1, 3} -> dom,
            {2, 2} -> Mod[Round[raw[[2, 2]], 12], 24],
            {3, 1, 3} -> dom,
            {3, 2} -> (Round[raw[[3, 2]],12] /. {0 -> 23 + 59/60. + 59/3600.})

Then, insert this line immediately after your table that creates sunsetrisedata

sunsetrisedata = fixTropics /@ sunsetrisedata;

You should now be able to run your very cool code for almost any geolocation without issues (up to the model Mathematica uses). You could test this, for example, by setting the location to Tromso in Norway, which is well known for hosting the Midnight Sun Marathon each year.

location = Entity["City", {"Tromso", "Troms", "Norway"}];

You will see that the annuli are slightly truncated near the start of intervals of perpetual day or perpetual night, which seems to be due to my coarse fixTropics[] function and the nature of the algorithms that Sunset[] and Sunrise[] use internally (and documented in their help pages). Still, your code works!

Some brief comments on what the helper function tries to do:

  • The dates generated from the Trace line occasionally produces things like {2022,4,0}, for example, instead of {2022,3,31}. This isn't a problem because the rest of your code manages it. However, my plan was to have the helper function "fix" days where the day-of-the-month for the first date in each row of sunsetrisedata was not the same as the day-of-the-month in the sunrise date and the sunset date. This is the reason for the DateList[] in the first few rows of the helper function (which converts {2022,4,30} to {2022,3,31,0,0,0.}, for comparison purposes).
  • The "fix" involves rounding the sunrise and sunset times either to 12 (if perpetual night) or outwards to 0 and 24, respectively (if perpetual day).
POSTED BY: Mark Dowdeswell

Very neat! Thanks for sharing! I use the Trace function to get the non-rounded values for sunset/sunrise. Normally it is rounded to the minute (reflecting the precision you can get because of local elevation, elevation around the horizon where the sun sets, temperature distortions, etc), but it make it very ugly. The Trace is a hack, but the only one that kinda works, I hope it keeps working in future versions… I actually asked for an update to Sunset/Sunrise that would give the precise one, perhaps as an Around value. Future versions might improve on this.

Thanks for the fix!

POSTED BY: Sander Huisman

Fantastic post - thanks!

To make Sander's notebook "standalone", the three lines at the start could be edited to use variable $GeoLocationCity:

    location = $GeoLocationCity; (* set the location*)
    tz = location["TimeZone"][[2]]; (* which timezone *)
    locationname = location[[2, 1]]; (* name of the location for displaying purposes*)
POSTED BY: Mark Dowdeswell

enter image description here -- you have earned Featured Contributor Badge enter image description here Your exceptional post has been selected for our editorial column Staff Picks and Your Profile is now distinguished by a Featured Contributor Badge and is displayed on the Featured Contributor Board. Thank you!

POSTED BY: Moderation Team
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
or Discard

Group Abstract Group Abstract