commons-suncalc offers six astronomical calculations:


All parameters are passed in a fluent builder-style interface. After retrieving the builder from compute(), you can chain the parameter setters, and finally call execute() to perform the computation.

SunPosition pos = SunPosition.compute().today().at(12.3, 45.6).execute();

It is also possible to collect the parameters first, and execute the computation in a separate step:

SunPosition.Parameters param = SunPosition.compute();, 45.6);;

SunPosition pos = param.execute();

The instance that is returned by execute() is immutable and only holds the result. You can continue modifying the parameters without changing the first result, then call execute() again for a second result., 12, 24);
SunPosition christmas = param.execute();
// pos from above is unchanged

Time-based Parameters

All calculations need a date and time parameter. Some examples:

// August 21st, 2017, local midnight
SunPosition.compute().on(2017, 8, 21);

// Current time, system time zone
Date now = new Date();

// Current time, UTC
Date now = new Date();

// Now (the default)

// Today (midnight), Berlin time zone

All available setters are listed in the JavaDocs. If no time-based parameter is given, the current date and time, and the system’s time zone is used.

NOTE: The accuracy of the results decreases for dates that are far in the future, or far in the past.

Location-based Parameters

Most of the calculations also need a geolocation. Some examples:

// At 20.5°N, 18.3°E
SunPosition.compute().at(20.5, 18.3);

// The same, but more verbose

// Use arrays for coordinate constants
final double[] COLOGNE = new double[] { 50.938056, 6.956944 };

All available setters are listed in the JavaDocs. If no location-based parameter is given, 0° is used for both latitude and longitude, which is not very useful in most cases. However, these parameters are not mandatory.

Time Range

SunTimes and MoonTimes only consider the next 24 hours. If the sun or moon does not rise or set within that time span, the appropriate getters return null. You can check if the sun or moon is always above or below the horizon, by checking isAlwaysUp() and isAlwaysDown().

If you need both the rise and set time, you can set the fullCycle() parameter. The calculation then runs until both times are found, even if several days in the future. However, depending on the date and geolocation, this calculation could take considerably more time and computing power.

Note that fullCycle() only affects the result of getRise() and getSet(). The methods isAlwaysUp(), isAlwaysDown(), getNoon() and getNadir() will still only consider the next 24 hours.

Time Rounding

SunTimes, MoonTimes and MoonPhase return Date objects as result. By default, the result is rounded to the nearest full minute. This is so suncalc does not pretend a higher precision than it can actually deliver.

You can change rounding by adding a truncateTo() parameter. It accepts one of these constants:

Constant Description
SECONDS Return a time including the calculated seconds. Note that due to the simplified formulas, suncalc is never accurate to the second.
MINUTES Round to the nearest full minute. This is the default.
HOURS Round to the nearest full hour.
DAYS Round down to the date. Basically it truncates the time component of the result.

Even though the method is called truncateTo(), the time component is rounded to the nearest full minute or hour. This gives more reasonable results.


By default, SunTimes calculates the time of the visual sunrise and sunset. This means that getRise() returns the instant when the sun just starts to rise above the horizon, and getSet() returns the instant when the sun just disappeared from the horizon. Atmospheric refraction is taken into account.

There are other interesting twilight angles available. You can set them via the twilight() parameter, by using one of the SunTimes.Twilight constants:

Constant Description Angle
ASTRONOMICAL Astronomical twilight -18°
NAUTICAL Nautical twilight -12°
CIVIL Civil twilight -6°
HORIZON The true moment when the center of the sun crosses the horizon.
BLUE_HOUR Blue Hour -4°
VISUAL Default: The moment when the visual upper edge of the sun crosses the horizon.
VISUAL_LOWER The moment when the visual lower edge of the sun crosses the horizon.

Alternatively you can also pass any other angle (in degrees) to twilight().



Note that only VISUAL and VISUAL_LOWER compensate atmospheric refraction. All other twilights do not, and refer to the center of the sun.


By default, MoonPhase calculates the date of the next new moon. If you want to compute the date of another phase, you can set it via the phase() parameter, by using one of the MoonPhase.Phase constants:

Constant Description Angle
NEW_MOON Moon is not illuminated (new moon)
FIRST_QUARTER Half of the waxing moon is illuminated 90°
FULL_MOON Moon is fully illuminated 180°
LAST_QUARTER Half of the waning moon is illuminated 270°

Alternatively you can also pass any other angle (in degrees) to phase().