Class CalendarAstronomer


  • public class CalendarAstronomer
    extends java.lang.Object
    CalendarAstronomer is a class that can perform the calculations to determine the positions of the sun and moon, the time of sunrise and sunset, and other astronomy-related data. The calculations it performs are in some cases quite complicated, and this utility class saves you the trouble of worrying about them.

    The measurement of time is a very important part of astronomy. Because astronomical bodies are constantly in motion, observations are only valid at a given moment in time. Accordingly, each CalendarAstronomer object has a time property that determines the date and time for which its calculations are performed. You can set and retrieve this property with setDate, getDate and related methods.

    Almost all of the calculations performed by this class, or by any astronomer, are approximations to various degrees of accuracy. The calculations in this class are mostly modelled after those described in the book Practical Astronomy With Your Calculator, by Peter J. Duffett-Smith, Cambridge University Press, 1990. This is an excellent book, and if you want a greater understanding of how these calculations are performed it a very good, readable starting point.

    WARNING: This class is very early in its development, and it is highly likely that its API will change to some degree in the future. At the moment, it basically does just enough to support IslamicCalendar and ChineseCalendar.

    • Field Summary

      Fields 
      Modifier and Type Field Description
      static long DAY_MS
      The number of milliseconds in one day.
      private static double DEG_RAD  
      (package private) static long EPOCH_2000_MS
      Milliseconds value for 0.0 January 2000 AD.
      static int HOUR_MS
      The number of milliseconds in one hour.
      private static double INVALID  
      (package private) static double JD_EPOCH  
      static long JULIAN_EPOCH_MS
      The start of the julian day numbering scheme used by astronomers, which is 1/1/4713 BC (Julian), 12:00 GMT.
      private double julianDay  
      private double meanAnomalySun  
      static int MINUTE_MS
      The number of milliseconds in one minute.
      (package private) static double moonA  
      (package private) static double moonE  
      private double moonEclipLong  
      (package private) static double moonI  
      (package private) static double moonL0  
      (package private) static double moonN0  
      (package private) static double moonP0  
      (package private) static double moonPi  
      private CalendarAstronomer.Equatorial moonPosition  
      (package private) static double moonT0  
      static CalendarAstronomer.MoonAge NEW_MOON
      Constant representing a new moon.
      private static double PI  
      private static double PI2  
      private static double RAD_DEG  
      private static double RAD_HOUR  
      static int SECOND_MS
      The number of milliseconds in one second.
      static double SIDEREAL_DAY
      The number of standard hours in one sidereal day.
      static double SIDEREAL_MONTH
      The average number of days it takes for the moon to return to the same ecliptic longitude relative to the stellar background.
      static double SIDEREAL_YEAR
      The average number of days it takes for the sun to return to the same position against the fixed stellar background.
      static double SOLAR_DAY
      The number of sidereal hours in one mean solar day.
      (package private) static double SUN_E  
      (package private) static double SUN_ETA_G  
      (package private) static double SUN_OMEGA_G  
      private double sunLongitude  
      static double SYNODIC_MONTH
      The average number of solar days from one new moon to the next.
      private long time
      Current time in milliseconds since 1/1/1970 AD
      static double TROPICAL_YEAR
      The average number number of days between successive vernal equinoxes.
      static CalendarAstronomer.SolarLongitude WINTER_SOLSTICE
      Constant representing the winter solstice.
    • Constructor Summary

      Constructors 
      Constructor Description
      CalendarAstronomer()
      Construct a new CalendarAstronomer object that is initialized to the current date and time.
      CalendarAstronomer​(long aTime)
      Construct a new CalendarAstronomer object that is initialized to the specified time.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      private void clearCache()  
      private double eclipticObliquity()
      Return the obliquity of the ecliptic (the angle between the ecliptic and the earth's equator) at the current time.
      CalendarAstronomer.Equatorial eclipticToEquatorial​(double eclipLong, double eclipLat)
      Convert from ecliptic to equatorial coordinates.
      java.util.Date getDate()
      Get the current time of this CalendarAstronomer object, represented as a Date object.
      double getJulianDay()
      Get the current time of this CalendarAstronomer object, expressed as a "julian day number", which is the number of elapsed days since 1/1/4713 BC (Julian), 12:00 GMT.
      double getMoonAge()
      The "age" of the moon at the time specified in this object.
      CalendarAstronomer.Equatorial getMoonPosition()
      The position of the moon at the time set on this object, in equatorial coordinates.
      long getMoonTime​(double desired, boolean next)
      Find the next or previous time at which the Moon's ecliptic longitude will have the desired value.
      long getMoonTime​(CalendarAstronomer.MoonAge desired, boolean next)
      Find the next or previous time at which the moon will be in the desired phase.
      double getSunLongitude()
      The longitude of the sun at the time specified by this object.
      (package private) double[] getSunLongitude​(double julian)
      TODO Make this public when the entire class is package-private.
      long getSunTime​(double desired, boolean next)
      Find the next time at which the sun's ecliptic longitude will have the desired value.
      long getSunTime​(CalendarAstronomer.SolarLongitude desired, boolean next)
      Find the next time at which the sun's ecliptic longitude will have the desired value.
      long getTime()
      Get the current time of this CalendarAstronomer object, represented as the number of milliseconds since 1/1/1970 AD 0:00 GMT (Gregorian).
      private static double norm2PI​(double angle)
      Normalize an angle so that it's in the range 0 - 2pi.
      private static double normalize​(double value, double range)
      Given 'value', add or subtract 'range' until 0 <= 'value' < range.
      private static double normPI​(double angle)
      Normalize an angle into the range -PI - PI
      private static java.lang.String radToDms​(double angle)  
      private static java.lang.String radToHms​(double angle)  
      void setJulianDay​(double jdn)
      Set the current date and time of this CalendarAstronomer object.
      void setTime​(long aTime)
      Set the current date and time of this CalendarAstronomer object.
      private long timeOfAngle​(CalendarAstronomer.AngleFunc func, double desired, double periodDays, long epsilon, boolean next)  
      private double trueAnomaly​(double meanAnomaly, double eccentricity)
      Find the "true anomaly" (longitude) of an object from its mean anomaly and the eccentricity of its orbit.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • SIDEREAL_DAY

        public static final double SIDEREAL_DAY
        The number of standard hours in one sidereal day. Approximately 24.93.
        See Also:
        Constant Field Values
      • SOLAR_DAY

        public static final double SOLAR_DAY
        The number of sidereal hours in one mean solar day. Approximately 24.07.
        See Also:
        Constant Field Values
      • SYNODIC_MONTH

        public static final double SYNODIC_MONTH
        The average number of solar days from one new moon to the next. This is the time it takes for the moon to return the same ecliptic longitude as the sun. It is longer than the sidereal month because the sun's longitude increases during the year due to the revolution of the earth around the sun. Approximately 29.53.
        See Also:
        SIDEREAL_MONTH, Constant Field Values
      • SIDEREAL_MONTH

        public static final double SIDEREAL_MONTH
        The average number of days it takes for the moon to return to the same ecliptic longitude relative to the stellar background. This is referred to as the sidereal month. It is shorter than the synodic month due to the revolution of the earth around the sun. Approximately 27.32.
        See Also:
        SYNODIC_MONTH, Constant Field Values
      • TROPICAL_YEAR

        public static final double TROPICAL_YEAR
        The average number number of days between successive vernal equinoxes. Due to the precession of the earth's axis, this is not precisely the same as the sidereal year. Approximately 365.24
        See Also:
        SIDEREAL_YEAR, Constant Field Values
      • SIDEREAL_YEAR

        public static final double SIDEREAL_YEAR
        The average number of days it takes for the sun to return to the same position against the fixed stellar background. This is the duration of one orbit of the earth about the sun as it would appear to an outside observer. Due to the precession of the earth's axis, this is not precisely the same as the tropical year. Approximately 365.25.
        See Also:
        TROPICAL_YEAR, Constant Field Values
      • SECOND_MS

        public static final int SECOND_MS
        The number of milliseconds in one second.
        See Also:
        Constant Field Values
      • MINUTE_MS

        public static final int MINUTE_MS
        The number of milliseconds in one minute.
        See Also:
        Constant Field Values
      • HOUR_MS

        public static final int HOUR_MS
        The number of milliseconds in one hour.
        See Also:
        Constant Field Values
      • DAY_MS

        public static final long DAY_MS
        The number of milliseconds in one day.
        See Also:
        Constant Field Values
      • JULIAN_EPOCH_MS

        public static final long JULIAN_EPOCH_MS
        The start of the julian day numbering scheme used by astronomers, which is 1/1/4713 BC (Julian), 12:00 GMT. This is given as the number of milliseconds since 1/1/1970 AD (Gregorian), a negative number. Note that julian day numbers and the Julian calendar are not the same thing. Also note that julian days start at noon, not midnight.
        See Also:
        Constant Field Values
      • EPOCH_2000_MS

        static final long EPOCH_2000_MS
        Milliseconds value for 0.0 January 2000 AD.
        See Also:
        Constant Field Values
      • WINTER_SOLSTICE

        public static final CalendarAstronomer.SolarLongitude WINTER_SOLSTICE
        Constant representing the winter solstice. For use with getSunTime. Note: In this case, "winter" refers to the northern hemisphere's seasons.
      • time

        private long time
        Current time in milliseconds since 1/1/1970 AD
        See Also:
        Date.getTime()
      • julianDay

        private transient double julianDay
      • sunLongitude

        private transient double sunLongitude
      • meanAnomalySun

        private transient double meanAnomalySun
      • moonEclipLong

        private transient double moonEclipLong
    • Constructor Detail

      • CalendarAstronomer

        public CalendarAstronomer()
        Construct a new CalendarAstronomer object that is initialized to the current date and time.
      • CalendarAstronomer

        public CalendarAstronomer​(long aTime)
        Construct a new CalendarAstronomer object that is initialized to the specified time. The time is expressed as a number of milliseconds since January 1, 1970 AD (Gregorian).
        See Also:
        Date.getTime()
    • Method Detail

      • setTime

        public void setTime​(long aTime)
        Set the current date and time of this CalendarAstronomer object. All astronomical calculations are performed based on this time setting.
        Parameters:
        aTime - the date and time, expressed as the number of milliseconds since 1/1/1970 0:00 GMT (Gregorian).
        See Also:
        #setDate, getTime()
      • setJulianDay

        public void setJulianDay​(double jdn)
        Set the current date and time of this CalendarAstronomer object. All astronomical calculations are performed based on this time setting.
        Parameters:
        jdn - the desired time, expressed as a "julian day number", which is the number of elapsed days since 1/1/4713 BC (Julian), 12:00 GMT. Note that julian day numbers start at noon. To get the jdn for the corresponding midnight, subtract 0.5.
        See Also:
        getJulianDay(), JULIAN_EPOCH_MS
      • getTime

        public long getTime()
        Get the current time of this CalendarAstronomer object, represented as the number of milliseconds since 1/1/1970 AD 0:00 GMT (Gregorian).
        See Also:
        setTime(long), getDate()
      • getDate

        public java.util.Date getDate()
        Get the current time of this CalendarAstronomer object, represented as a Date object.
        See Also:
        #setDate, getTime()
      • getJulianDay

        public double getJulianDay()
        Get the current time of this CalendarAstronomer object, expressed as a "julian day number", which is the number of elapsed days since 1/1/4713 BC (Julian), 12:00 GMT.
        See Also:
        setJulianDay(double), JULIAN_EPOCH_MS
      • eclipticToEquatorial

        public final CalendarAstronomer.Equatorial eclipticToEquatorial​(double eclipLong,
                                                                        double eclipLat)
        Convert from ecliptic to equatorial coordinates.
        Parameters:
        eclipLong - The ecliptic longitude
        eclipLat - The ecliptic latitude
        Returns:
        The corresponding point in equatorial coordinates.
      • getSunLongitude

        public double getSunLongitude()
        The longitude of the sun at the time specified by this object. The longitude is measured in radians along the ecliptic from the "first point of Aries," the point at which the ecliptic crosses the earth's equatorial plane at the vernal equinox.

        Currently, this method uses an approximation of the two-body Kepler's equation for the earth and the sun. It does not take into account the perturbations caused by the other planets, the moon, etc.

      • getSunLongitude

        double[] getSunLongitude​(double julian)
        TODO Make this public when the entire class is package-private.
      • getSunTime

        public long getSunTime​(double desired,
                               boolean next)
        Find the next time at which the sun's ecliptic longitude will have the desired value.
      • getSunTime

        public long getSunTime​(CalendarAstronomer.SolarLongitude desired,
                               boolean next)
        Find the next time at which the sun's ecliptic longitude will have the desired value.
      • getMoonPosition

        public CalendarAstronomer.Equatorial getMoonPosition()
        The position of the moon at the time set on this object, in equatorial coordinates.
      • getMoonAge

        public double getMoonAge()
        The "age" of the moon at the time specified in this object. This is really the angle between the current ecliptic longitudes of the sun and the moon, measured in radians.
        See Also:
        #getMoonPhase
      • getMoonTime

        public long getMoonTime​(double desired,
                                boolean next)
        Find the next or previous time at which the Moon's ecliptic longitude will have the desired value.

        Parameters:
        desired - The desired longitude.
        next - true if the next occurrance of the phase is desired, false for the previous occurrance.
      • getMoonTime

        public long getMoonTime​(CalendarAstronomer.MoonAge desired,
                                boolean next)
        Find the next or previous time at which the moon will be in the desired phase.

        Parameters:
        desired - The desired phase of the moon.
        next - true if the next occurrance of the phase is desired, false for the previous occurrance.
      • timeOfAngle

        private long timeOfAngle​(CalendarAstronomer.AngleFunc func,
                                 double desired,
                                 double periodDays,
                                 long epsilon,
                                 boolean next)
      • normalize

        private static final double normalize​(double value,
                                              double range)
        Given 'value', add or subtract 'range' until 0 <= 'value' < range. The modulus operator.
      • norm2PI

        private static final double norm2PI​(double angle)
        Normalize an angle so that it's in the range 0 - 2pi. For positive angles this is just (angle % 2pi), but the Java mod operator doesn't work that way for negative numbers....
      • normPI

        private static final double normPI​(double angle)
        Normalize an angle into the range -PI - PI
      • trueAnomaly

        private double trueAnomaly​(double meanAnomaly,
                                   double eccentricity)
        Find the "true anomaly" (longitude) of an object from its mean anomaly and the eccentricity of its orbit. This uses an iterative solution to Kepler's equation.
        Parameters:
        meanAnomaly - The object's longitude calculated as if it were in a regular, circular orbit, measured in radians from the point of perigee.
        eccentricity - The eccentricity of the orbit
        Returns:
        The true anomaly (longitude) measured in radians
      • eclipticObliquity

        private double eclipticObliquity()
        Return the obliquity of the ecliptic (the angle between the ecliptic and the earth's equator) at the current time. This varies due to the precession of the earth's axis.
        Returns:
        the obliquity of the ecliptic relative to the equator, measured in radians.
      • clearCache

        private void clearCache()
      • radToHms

        private static java.lang.String radToHms​(double angle)
      • radToDms

        private static java.lang.String radToDms​(double angle)