Random calendar generation from planet orbital parameters

In this article I want to show you a small proof of concept where we generate from scratch an alien calendar. The difference from other random calendar generators that just put random days and random month is that, in this tool, we can specify as input the orbital parameters of the planet and satellite and generate a calendar that makes sense.  How could be the calendar for that planet orbiting a super-massive star? How could be the calendar for Mars or Venus? Every time I try to sketch a Sci-Fi world, I want to try thinking to a calendar that make sense for that particular planet. Because the calculations are long and boring, I built for myself this little tool. However, before going to the tool, I want to provide a small introduction to the problem.


Among the many things I am fascinated about, I like to imagine imaginary calendars for the inhabitants of distant worlds. A different year duration, a different moon (if any), different history, every small details can change completely the structure and the rule of an alien calendar.

After all, our calendar is just a messy result of centuries of corrections and arbitrary changes. There are so many things we give for granted but, in reality, they are just arbitrary decisions.

  • Why the year start in the middle of the Winter?
  • Why we use a 7 days week?
  • Why we use 12 months? And why are they of 30/31 days?
  • Why February is 28 days long?
  • Why a leap year every 4 years (approximately)?

Looking at different calendars developed in other cultures, such as the Chinese Calendar and the Persian Calendar, we can learn that these and many other properties are just convention.

A Calendar: the Important Parts

What we really care about a calendar is keeping track of seasons and help the people to keep track of time in their daily life. These things depend directly on the  movement of the Earth and the other celestial bodies. This is the reason this generator uses orbital parameters as a starting point for calendar generation. I want to be sure that the generated calendar is aligned on “the real world”. But let’s see which calendar aspect is connected to which orbital information.

  • Year: as we all know, the year depends on the orbital period of the Earth around its star (the Sun).
  • Day: the day is the time the Earth do a full rotation around itself (let’s ignore the difference between solar day and astral day).
  • Month: months are borderline between convention and “real thing”. Here on earth, we have this big satellite (the Moon) and we decided to align the month duration to the revolution of the Moon around the Earth.
  • Leap Years: this is a way to fix the decimal part of the ration between the year and the day duration. We will see this better later.

Then there are seasons. Seasons depend on the eccentricity of the Earth orbit but, for now, we ignore them.

Cool. We have a nice correspondence between year/month/day duration and the orbits of the Earth around the Sun and the Moon around the Earth. Therefore, we need just to compute this values.

Computing the Orbital Periods from the Orbital Parameters

The semi-major axis (in red) and the semi-minor axis (in blue) on an ellipse.

With orbital parameters  we refer to all the information about two celestial object that define how the smaller object orbits around the other. Fortunately for us, there are just three parameters:

  • Mass M of the bigger object (e.g., the Sun)
  • Mass m of the smaller object (e.g., the Earth)
  • Semi-axis major of the orbit a. That is half the value of the greater diameter of the ellipse (the major axis). For the orbits, it is convenient to compute this value with the average of the minimum distance between the Earth and the Sun (perihelion) and the maximum distance (aphelion).

With these three piece of data, we can compute everything about the orbit of the celestial objects. To do that, we will use the Kepler’s Third Law:

\frac{P^2}{a^3} = \frac{4 \pi^2}{G(M+m)}

Solving this equation for P give us the orbital period. If we want to know the position of the planet on the orbit in a specific day, the formula get much more complicated. We will talk about that when we will try to add to our calendar season and lunar phases. For now, more information on this task can be found in this PDF (they are just my notes on the topic).

For now, we only need the orbital period. Using this formula we can get the periods defining the year duration (Sun-Earth system) and the month duration (Earth-Moon system).

Computing the relevant calendar information from Orbital Periods

Now, we can compute the important aspect of a calendar.

For the year, we use the integer part of the orbital period between the planet and the star (e.g., the Earth and the Sun).

For the average month duration we use the integer part of the orbital period between the satellite and the planet (e.g., the Moon and the Sun).

Leap years  are a bit more complicated. First we need to divide the year duration (in seconds) for the day duration (in seconds). For example, on Earth, each day is composed by 86400  seconds. If we get the orbital period of earth and we divide it by this value, we get the well-known value of  365.242190402. Now, we take the decimal part, 0.242190402, and we look for a function that approximates well enough this number. Suppose for instance 0.25 = \frac{1}{4} as a good approximation. This tell us that we need to add 1 day every 4 years. If the fraction we chose is \frac{97}{400} (as it is the one we use nowadays), this means that we need to add 97 days every 400 years.

Note that this does not tell us how to do this. We can choose to add 1 day every a certain amount of years, or add a week in some special years, and so on. We will talk more about this in another time.

How can you compute this fraction? In my code I use the convergents of the continued fraction of that decimal number. You can use any other technique. It does not matter.

At this point we have all the data we need to generate any random calendar. We know how many days there are in a year, how many months, how many days there are, on average, in a month and a basic idea on how the “leap year” will work. Now, we only need to apply some randomization to these values, for instance by moving days from a month to another, and we will get a calendar structure for our planet.

The Calendar Generator

The Calendar Generator interface in the demo project.

Now that we have the basic idea of how the various concepts are connected with each other, we can start looking at the code.

The actual implementation of the calendar is hosted here. In the demo you can insert all the orbital parameters and the duration in seconds of the day of your planet, and generate a possible calendar for that configuration. The source code is hosted on GitHub.

An example output for version 0.1 of the calendar generator.

Obviously this is an early proof of concept and there are still many things I can improve. First, I still use a weekly structure for the calendar. Weeks are a convenient way for the inhabitants of the planet to divide the months, but the 7 days of our calendar does not come from any orbital parameter.  I would like to make the number 7 a user parameter and, in the future, provide alternatives to the concept of week.

Second, many other calendars on Earth have multi-year structures such as cycles or eras. A common example is represented by the 60-year-long cycle in the Chinese Calendar (and other eastern calendars). I would like to add the possibility to generate this kind of structures as well.

Finally, I assume a planet with a moon. But what if there is none? What if there are two, three, ten satellites? How would be a calendar for such exotic places? The seam reasoning could be done also for multiple stars. This multi-object system are so different that is not easy to develop a calendar for them. It is a much challenging problem that I think it is worth exploring.

And then seasons, events, and much, much more. Playing with a calendar of a distant world tell us a lot of the life of its inhabitants before we even start thinking about them.

I hope you have found this article interesting. If you want, we can continue improving this on GitHub. Follow me on Twitter and ask me anything!