SunTimes class and command-line client

(c)2000 Kevin Boone/Web-Tomorrow

This package provides a class SunTimes that can calculate sunrise and sunset times, and various types of twilight, anywhere on Earth on any date. It also includes a command-line client and the necessary helper classes.

SunTimes class

This is the main class in the package; although it only exposes two methods (getSunriseTimeUTC and getSunsetTimeUTC) they can be used in a variety of ways.

Usage

Here is an example of the use of getSunriseTimeUTC to determine the time of true sunrise, that is, the time at which the upper extreme of the disk of the Sun just breaks over the horizon, assuming `average' atmospheric conditions (see definitions of sunrise, twilight, etc., below). getSunsetTimeUTC is used similarly.
import com.web_tomorrow.util.suntimes.*;
Time t = getSunriseTimeUTC
  (year, month, day, longitude, lattitude, SunTimes.ZENITH);
System.out.println ("Sunrise is at " + t + " UTC");
This displays the UTC sunrise time at the specified location in hours, minutes and seconds. If a local time is required, the caller will need to convert the UTC time as appropriate; it is not the job of this package to do time conversions.

Note that to calculate the sunrise or sunset time we need the exact date and the latitude and longitude.

Parameters

The date is specified as follows. The location is specified as follows. The final parameter, zenith, determines the type of result required. If set to SunTimes.ZENITH it indicates true sunrise/sunset. If set to SunTimes.CIVIL_ZENITH, SunTimes.NAUTICAL_ZENITH, or SunTimes.ASTRONOMICAL_ZENITH it indicates civil twilight, nautical twilight, or astronomical twilight respoectively. For an explanation of these terms, see below.

Algorithm

The algorithm implemented in this class is based on that described in the US Naval Observatory's Almanac for Computers, (1990; Nautical Almanac Office, United States Naval Observatory, Washington, DC 20392), and has been tested extensively against the tables provided on this organization's Web site (aa.usno.navy.mil).

True sunrise and true sunset conventionally refer to the times when the upper edge of the disk of the Sun appears on the horizon at the location of interest. Atmospheric conditions are assumed to be average, and the location is level.

`Zenith' is the angle that the centre of the Sun makes to a line perpendicular to the Earth's surface. If the Sun were a point and the Earth were without an atmosphere, true sunset and sunrise would correspond to a 90-degree zenith. Because the Sun is not a point, and because the atmosphere refracts light, this 90-degree zenith does not, in fact, correspond to true sunset or sunrise; instead the centre of the Sun's disk must lie just below the horizon for the upper edge to be obscured. This means that a zenith of just above 90 degrees must be used. The Sun subtends an angle of 16 minutes of arc, and atmospheric refraction accounts for 34 minutes or so, giving a total of 50 arcminutes. So the best overall figure for zenith is 90+(50/60) degrees for true sunrise/sunset, which is the value assigned to the constant SunTimes.ZENITH

Even when the Sun is slightly below the horizon, a small amout of light is reflected from dust particles in the atmosphere, and it is not quite dark; this is twilight. The duration of twilight is more difficult to define than the times of sunrise and sunset, because light fades gradually as the sun sets. Conventionally we take a zenith of 96 degrees to signify twilight; this figure is usually called the civil zenith. This period of twilight is the time in which it is possible to carry out some forms of outdoor activities, even with no other source of light. Two other twilight zeniths are recognized: nautical zenith at 102 degrees and astronomical zenith at 108 degrees. Nautical twilight is the point at which the horizon stops being visible at sea. Astronical twilight is the point at which the Sun really stops being a source of any illumination.

Clearly the rise and set times will depend on the date. In theory there are also year-to-year variations in sunset/rise times, but they are incredibly tiny. This SunTimes methods require a year to be specified only to account for whether it is a leap year or not. For example, March 1st is one day later on a leap year, compared to non-leap years. In practice this is unlikely to be affect the result by more than a few seconds.

Supporting classes

SunTimes requires two supporting classes: com.web_tomorrow.utils.SunTimesException and com.web_tomorrow.utils.Time. SunTimesException is thrown to indicate that the calculation could not be carried out for some reason. For example, some northerly regions are in daylight for long stretches of time; an attempt to calculate a sunset time for such a location at such a time will result in an exception.

The Time class provides a simple model of time-of-day, which avoids the system-dependent features of the standard Java Calendar class. All the public methods in SunTimes return an object of class Time. In simple cases the application can just call toString() on it to get a displayable (24-hour clock) time.

Command-line client

Running the command-line client

The following command will run the command-line client, if suitably modified for the file locations on your system.
java -classpath $CLASSPATH:suntimes.jar:javapopt.jar com.web_tomorrow.utils.suntimes.SunTimesClient 
  [options] latitude longitude [day] [month] [year]
To get a full list of options, use the --help switch. This package includes a shell script that can be used to run the client and avoid typing the class and classpath every time, but this will need to be modified to suit the location in which you install the SunTimes JAR file.

Any of the day, month and year can be omitted, and current values will be assumed. At least one option must be specified, to indicate how to convert the calculated UTC time to a local time, if at all. The switch --utc indicates that a UTC time is acceptable and does not need to be converted. Alternatively an offset in hours from GMT can be supplied with the --offset switch, or a timezone with the --zone switch.

The results displayed are 24-hour clock times.

Note that the program does not check that the arguments make sense, beyond being numbers. So it won't complain if you specify Feb 31st, year -20.

Here are some examples.

Finally, here are a few general notes about the client.

Disclaimer and legal info

This package has been made available in the hope that it will be useful. There is no warranty, and the author accepts no responsibility for any adverse consequences of its use. Please feel free to use this code in any way you see fit, except to claim it as your own work. For a more detailed licensing statement see the file COPYING.txt in this package.