Usage¶
commons-suncalc
offers six astronomical calculations:
- SunTimes: Sunrise, sunset, noon and nadir times.
- MoonTimes: Moonrise and moonset times.
- MoonPhase: Date and time of new moon, full moon and half moons.
- SunPosition: Position of the sun.
- MoonPosition: Position of the moon.
- MoonIllumination: Moon phase and angle.
Quick Start¶
All of the calculations mentioned above are invoked in the same way:
Date date = // date of calculation
double lat, lng = // geolocation
SunTimes times = SunTimes.compute()
.on(date) // set a date
.at(lat, lng) // set a location
.execute(); // get the results
System.out.println("Sunrise: " + times.getRise());
System.out.println("Sunset: " + times.getSet());
You invoke compute()
, set your parameters, invoke execute()
, and then get the result of the calculation as an object.
All parameters are passed in by 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();
param.today();
param.at(12.3, 45.6);
SunPosition pos = param.execute();
The instance that is returned by execute()
is immutable and only holds the calculation result of the current set of parameters. You can modify the parameters without changing the first result, then call execute()
again for a second result.
param.on(2016, 12, 24); // modify the param from above
SunPosition posAtChristmas = 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();
SunPosition.compute().on(now);
// Current time, UTC
Date now = new Date();
SunPosition.compute().on(now).utc();
// Now (the default)
SunPosition.compute().now();
// Today (midnight), Berlin time zone
SunPosition.compute().today().timezone("Europe/Berlin");
The available time-based parameters are:
on(int year, int month, int date)
: Midnight of the given date. Note thatmonth
is counted from 1 (1 = January, 2 = February, …).on(int year, int month, int date, int hour, int minute, int second)
: Given date and time.on(Calendar cal)
: Date, time and timezone as given in theCalendar
. TheCalender
is copied and can safely be modified after that.on(Date date)
: Date and time as given in theDate
.plusDays(int days)
: Adds the given number of days to the current date.days
can also be negative, of course.now()
: The current system date and time. This is the default.midnight()
: Past midnight of the current date. It just truncates the time.today()
: Identical to.now().midnight()
.tomorrow()
: Identical totoday().plusDays(1)
.timezone(TimeZone tz)
: Use the given timezone.timezone(String id)
: Same as above, but accepts aString
for your convenience.localTime()
: The system's timezone. This is the default.utc()
: UTC timezone. Identical totimezone("UTC")
.sameTimeAs(TimeParameter<?> t)
: Copies the current date, time, and timezone from any other parameter object. Note that subsequent changes to the other object are not adopted.
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 is decreasing for dates that are far in the future, or far in the past.
Location-based Parameters¶
Except of MoonPhase
and MoonIllumination
, all calculations require a geolocation as parameter. Some examples:
// At 20.5°N, 18.3°E
SunPosition.compute().at(20.5, 18.3);
// The same, but more verbose
SunPosition.compute().latitude(20.5).longitude(18.3);
// Use arrays for coordinate constants
final double[] COLOGNE = new double[] { 50.938056, 6.956944 };
SunPosition.compute().at(COLOGNE);
The available location-based parameters are:
at(double lat, double lng)
: Latitude and longitude to be used for computation.at(double[] coords)
: Accepts an array of 2 values (latitude, longitude) or 3 values (latitude, longitude, height).latitude(double lat)
: Verbose way to set the latitude only.longitude(double lng)
: Verbose way to set the longitude only.latitude(int d, int m, double s)
: Set the latitude in degrees, minutes, seconds and fraction of seconds.longitude(int d, int m, double s)
: Set the longitude in degrees, minutes, seconds and fraction of seconds.height(double h)
: Height above sea level, in meters. Sea level is used by default.sameLocationAs(LocationParameter<?> l)
: Copies the current location and height from any other parameter object. Note that subsequent changes to the other object are not adoped.
Warning
The location parameters are not mandatory. However, if they are not given, 0° is assumed as latitude and longitude, which is not very useful in most cases. Do not forget to set the parameters!
Note
height
cannot be negative. If you pass in a negative height, it is silently changed to the accepted minimum of 0 meters. For this reason, it is safe to pass coordinates from satellite-based navigation systems without range checking.
Time Range¶
By default, SunTimes
and MoonTimes
only consider the next 24 hours of the given start time. 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
fullCycle()
only affects the result of getRise()
and getSet()
. The methods isAlwaysUp()
, isAlwaysDown()
, getNoon()
and getNadir()
will always only consider the next 24 hours.
Result 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 |
Include 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. |
Note
Even though the method is called truncateTo()
, the time component is rounded to the nearest full minute or hour. This gives more reasonable results.
Twilight¶
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 of the Sun | Topocentric |
---|---|---|---|
VISUAL |
The moment when the visual upper edge of the sun crosses the horizon. This is the default. | yes | |
VISUAL_LOWER |
The moment when the visual lower edge of the sun crosses the horizon. | yes | |
ASTRONOMICAL |
Astronomical twilight | -18° | no |
NAUTICAL |
Nautical twilight | -12° | no |
CIVIL |
Civil twilight | -6° | no |
HORIZON |
The moment when the center of the sun crosses the horizon. | 0° | no |
GOLDEN_HOUR |
Transition from daylight to Golden Hour | 6° | no |
BLUE_HOUR |
Transition from Golden Hour to Blue Hour | -4° | no |
NIGHT_HOUR |
Transition from Blue Hour to night | -8° | no |
The illustration shows the transitions of each twilight constant. If you want to get the duration of a twilight, you need to calculate the times of both transitions of the twilight. For example, to get the beginning and ending of the civil twilight, you need to calculate both the VISUAL
and the CIVIL
twilight transition times.
Alternatively you can also pass any other angle (in degrees) to twilight()
.
Note
Only VISUAL
and VISUAL_LOWER
are topocentric. They refer to the visual edge of the sun, take account of the height
parameter, and compensate atmospheric refraction.
All other twilights are geocentric and heliocentric. The height
parameter is then ignored, and atmospheric refraction is not compensated.
Example:
SunTimes.compute().twilight(SunTimes.Twilight.GOLDEN_HOUR);
Phase¶
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). This is the default. | 0° |
WAXING_CRESCENT |
Waxing crescent moon. | 45° |
FIRST_QUARTER |
Half of the waxing moon is illuminated. | 90° |
WAXING_GIBBOUS |
Waxing gibbous moon. | 135° |
FULL_MOON |
Moon is fully illuminated. | 180° |
WANING_GIBBOUS |
Waning gibbous moon. | 225° |
LAST_QUARTER |
Half of the waning moon is illuminated. | 270° |
WANING_CRESCENT |
Waning crescent moon. | 315° |
Alternatively you can also pass any other angle (in degrees) to phase()
.
Example:
MoonPhase.compute().phase(MoonPhase.Phase.FULL_MOON);