FileDocCategorySizeDatePackage
TwilightCalculator.javaAPI DocAndroid 5.1 API4277Thu Mar 12 22:22:42 GMT 2015com.android.server

TwilightCalculator

public class TwilightCalculator extends Object
hide

Fields Summary
public static final int
DAY
Value of {@link #mState} if it is currently day
public static final int
NIGHT
Value of {@link #mState} if it is currently night
private static final float
DEGREES_TO_RADIANS
private static final float
J0
private static final float
ALTIDUTE_CORRECTION_CIVIL_TWILIGHT
private static final float
C1
private static final float
C2
private static final float
C3
private static final float
OBLIQUITY
private static final long
UTC_2000
public long
mSunset
Time of sunset (civil twilight) in milliseconds or -1 in the case the day or night never ends.
public long
mSunrise
Time of sunrise (civil twilight) in milliseconds or -1 in the case the day or night never ends.
public int
mState
Current state
Constructors Summary
Methods Summary
public voidcalculateTwilight(long time, double latiude, double longitude)
calculates the civil twilight bases on time and geo-coordinates.

param
time time in milliseconds.
param
latiude latitude in degrees.
param
longitude latitude in degrees.


                                 
            
        final float daysSince2000 = (float) (time - UTC_2000) / DateUtils.DAY_IN_MILLIS;

        // mean anomaly
        final float meanAnomaly = 6.240059968f + daysSince2000 * 0.01720197f;

        // true anomaly
        final float trueAnomaly = meanAnomaly + C1 * FloatMath.sin(meanAnomaly) + C2
                * FloatMath.sin(2 * meanAnomaly) + C3 * FloatMath.sin(3 * meanAnomaly);

        // ecliptic longitude
        final float solarLng = trueAnomaly + 1.796593063f + (float) Math.PI;

        // solar transit in days since 2000
        final double arcLongitude = -longitude / 360;
        float n = Math.round(daysSince2000 - J0 - arcLongitude);
        double solarTransitJ2000 = n + J0 + arcLongitude + 0.0053f * FloatMath.sin(meanAnomaly)
                + -0.0069f * FloatMath.sin(2 * solarLng);

        // declination of sun
        double solarDec = Math.asin(FloatMath.sin(solarLng) * FloatMath.sin(OBLIQUITY));

        final double latRad = latiude * DEGREES_TO_RADIANS;

        double cosHourAngle = (FloatMath.sin(ALTIDUTE_CORRECTION_CIVIL_TWILIGHT) - Math.sin(latRad)
                * Math.sin(solarDec)) / (Math.cos(latRad) * Math.cos(solarDec));
        // The day or night never ends for the given date and location, if this value is out of
        // range.
        if (cosHourAngle >= 1) {
            mState = NIGHT;
            mSunset = -1;
            mSunrise = -1;
            return;
        } else if (cosHourAngle <= -1) {
            mState = DAY;
            mSunset = -1;
            mSunrise = -1;
            return;
        }

        float hourAngle = (float) (Math.acos(cosHourAngle) / (2 * Math.PI));

        mSunset = Math.round((solarTransitJ2000 + hourAngle) * DateUtils.DAY_IN_MILLIS) + UTC_2000;
        mSunrise = Math.round((solarTransitJ2000 - hourAngle) * DateUtils.DAY_IN_MILLIS) + UTC_2000;

        if (mSunrise < time && mSunset > time) {
            mState = DAY;
        } else {
            mState = NIGHT;
        }