Skip to content

Commit

Permalink
Initial load of Sunrise/Sunset calculation library.
Browse files Browse the repository at this point in the history
  • Loading branch information
mikereedell committed Dec 3, 2008
0 parents commit a0dce78
Show file tree
Hide file tree
Showing 9 changed files with 621 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .classpath
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="test"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="output" path="bin"/>
</classpath>
17 changes: 17 additions & 0 deletions .project
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>SunriseSunsetCalculator</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
12 changes: 12 additions & 0 deletions .settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,12 @@
#Mon Nov 17 12:01:06 EST 2008
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=do not generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.5
67 changes: 67 additions & 0 deletions src/com/reedell/sunrisesunset/Location.java
@@ -0,0 +1,67 @@
package com.reedell.sunrisesunset;

import java.math.BigDecimal;

/**
* Simple VO class to store latitude/longitude information.
*/
public class Location {
private BigDecimal latitude;
private BigDecimal longitude;

/**
* Creates a new instance of <code>Location</code> with the given parameters.
*
* @param latitude
* the latitude, in degrees, of this location. North latitude is positive, south negative.
* @param longitude
* the longitude, in degrees of this locatio. East longitude is positive, west negative.
*/
public Location(BigDecimal latitude, BigDecimal longitude) {
this.latitude = latitude;
this.longitude = longitude;
}

/**
* Creates a new instance of <code>Location</code> with the given parameters.
*
* @param latitude
* the latitude, in degrees, of this location. North latitude is positive, south negative.
* @param longitude
* the longitude, in degrees of this locatio. East longitude is positive, west negative.
*/
public Location(String latitude, String longitude) {
this.latitude = new BigDecimal(latitude);
this.longitude = new BigDecimal(longitude);
}

/**
* @return the latitude
*/
public BigDecimal getLatitude() {
return latitude;
}

/**
* @param latitude
* the latitude to set
*/
public void setLatitude(BigDecimal latitude) {
this.latitude = latitude;
}

/**
* @return the longitude
*/
public BigDecimal getLongitude() {
return longitude;
}

/**
* @param longitude
* the longitude to set
*/
public void setLongitude(BigDecimal longitude) {
this.longitude = longitude;
}
}
75 changes: 75 additions & 0 deletions src/com/reedell/sunrisesunset/SolarEventCalculator.java
@@ -0,0 +1,75 @@
package com.reedell.sunrisesunset;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Calendar;

/**
* Parent class of the Sunrise and Sunset calculator classes.
*/
public class SolarEventCalculator {
protected Calendar eventDate;

protected Location location;
protected double zenith;
protected static final BigDecimal RAD_TO_DEG = new BigDecimal(180 / Math.PI);
protected static final BigDecimal DEG_TO_RAD = BigDecimal.valueOf(Math.PI / 180.0);
protected static final BigDecimal FIFTEEN_DEG_IN_RAD = BigDecimal.valueOf(Math.toRadians(15));

/**
* Constructs a new <code>SolarEventCalculator</code> based on the given parameters.
*
* @param location
* <code>Location</code> object containing the coordinates to base the calculation on.
* @param zenith
* zenith, in degrees, used in the solar calculation.
*/
public SolarEventCalculator(Location location, Integer zenith) {
this(location, zenith, Calendar.getInstance());
}

/**
* Constructs a new <code>SolarEventCalculator</code> based on the given parameters.
*
* @param location
* <code>Location</code> object containing the coordinates to base the calculation on.
* @param zenith
* zenith, in degrees, used in the solar calculation.
* @param eventDate
* date of the solar event to calculate.
*/
public SolarEventCalculator(Location location, Integer zenith, Calendar eventDate) {
this.location = location;
this.zenith = zenith;
this.eventDate = eventDate;
}

public BigDecimal getDayOfYear() {
return new BigDecimal(this.eventDate.get(Calendar.DAY_OF_YEAR));
}

public int getUTCOffset() {
return this.eventDate.getTimeZone().getOffset(this.eventDate.getTimeInMillis());
}

public BigDecimal getZenithInRadians() {
return BigDecimal.valueOf(Math.toRadians(this.zenith));
}

protected BigDecimal getBaseLongitudeHour() {
return convertDegreesToRadians(this.location.getLongitude()).divide(FIFTEEN_DEG_IN_RAD, 4, RoundingMode.HALF_EVEN);
}

protected BigDecimal getArcCosineFor(BigDecimal number) {
BigDecimal arcCosine = BigDecimal.valueOf(Math.acos(number.doubleValue()));
return arcCosine;
}

protected BigDecimal convertRadiansToDegrees(BigDecimal radians) {
return radians.multiply(RAD_TO_DEG);
}

protected BigDecimal convertDegreesToRadians(BigDecimal degrees) {
return degrees.multiply(DEG_TO_RAD);
}
}
120 changes: 120 additions & 0 deletions src/com/reedell/sunrisesunset/SunriseCalculator.java
@@ -0,0 +1,120 @@
package com.reedell.sunrisesunset;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Calendar;

/**
*
*/
public class SunriseCalculator extends SolarEventCalculator {

public SunriseCalculator(Location location, Integer zenith) {
super(location, zenith, Calendar.getInstance());
}

public SunriseCalculator(Location location, Integer zenith, Calendar sunriseDate) {
super(location, zenith, sunriseDate);
}

protected BigDecimal getLongitudeHour() {
return getDayOfYear().add(
(BigDecimal.valueOf(6).subtract(this.getBaseLongitudeHour())).divide(BigDecimal.valueOf(24), 4,
RoundingMode.HALF_EVEN));
}

protected BigDecimal getMeanAnomaly() {
BigDecimal multiplier = new BigDecimal(0.9856);
return (multiplier.multiply(getLongitudeHour())).subtract(new BigDecimal(3.289));
}

protected BigDecimal getSunTrueLongitude() {
BigDecimal meanAnomalyInRads = convertDegreesToRadians(getMeanAnomaly());
BigDecimal sinMeanAnomaly = new BigDecimal(Math.sin(meanAnomalyInRads.doubleValue()));
BigDecimal sinDoubleMeanAnomaly = new BigDecimal(Math
.sin(meanAnomalyInRads.multiply(BigDecimal.valueOf(2)).doubleValue()));

BigDecimal firstPart = getMeanAnomaly().add(sinMeanAnomaly.multiply(BigDecimal.valueOf(1.916)));
BigDecimal secondPart = sinDoubleMeanAnomaly.multiply(BigDecimal.valueOf(0.020)).add(BigDecimal.valueOf(282.634));
BigDecimal trueLongitude = firstPart.add(secondPart);

if (trueLongitude.doubleValue() > 360) {
trueLongitude = trueLongitude.subtract(BigDecimal.valueOf(360));
}
return trueLongitude;
}

protected BigDecimal getSunRightAscension() {
BigDecimal trueLongInRads = this.convertDegreesToRadians(getSunTrueLongitude());
BigDecimal tanL = new BigDecimal(Math.tan(trueLongInRads.doubleValue()));

BigDecimal innerParens = this.convertRadiansToDegrees(tanL).multiply(BigDecimal.valueOf(0.91764));
BigDecimal rightAscension = new BigDecimal(Math.atan(this.convertDegreesToRadians(innerParens).doubleValue()));
return rightAscension;
}

protected BigDecimal setQuadrantOfRightAscension() {
BigDecimal ninety = BigDecimal.valueOf(90);
BigDecimal longitudeQuadrant = getSunTrueLongitude().divide(ninety, 4, RoundingMode.FLOOR);
longitudeQuadrant = longitudeQuadrant.multiply(ninety);

BigDecimal rightAscensionQuadrant = getSunRightAscension().divide(ninety, 4, RoundingMode.FLOOR);
rightAscensionQuadrant = rightAscensionQuadrant.multiply(ninety);

BigDecimal augend = longitudeQuadrant.subtract(rightAscensionQuadrant);
return (getSunRightAscension().add(augend)).divide(BigDecimal.valueOf(15), 4, RoundingMode.HALF_EVEN);
}

protected BigDecimal getRightAscensionInHours() {
return this.setQuadrantOfRightAscension().divide(FIFTEEN_DEG_IN_RAD, 4, RoundingMode.HALF_EVEN);
}

protected BigDecimal getSinOfSunDeclination() {
BigDecimal sunTrueLongInRads = convertDegreesToRadians(getSunTrueLongitude());
BigDecimal sinTrueLongitude = BigDecimal.valueOf(Math.sin(sunTrueLongInRads.doubleValue()));
BigDecimal sinOfDeclination = BigDecimal.valueOf(0.39782).multiply(sinTrueLongitude);

return sinOfDeclination;
}

protected BigDecimal getCosineOfSunDeclination() {
BigDecimal arcSinOfSinDeclination = BigDecimal.valueOf(Math.asin(this.getSinOfSunDeclination().doubleValue()));
BigDecimal cosDeclination = BigDecimal.valueOf(Math.cos(arcSinOfSinDeclination.doubleValue()));
return cosDeclination;
}

protected BigDecimal getCosineSunLocalHour() {
BigDecimal cosineZenith = BigDecimal.valueOf(Math.cos(this.zenith));
BigDecimal sinLatitude = BigDecimal.valueOf(Math.sin(convertDegreesToRadians(this.location.getLatitude()).doubleValue()));
BigDecimal cosLatitude = BigDecimal.valueOf(Math.cos(convertDegreesToRadians(this.location.getLatitude()).doubleValue()));

BigDecimal sinDeclinationTimesSinLat = getSinOfSunDeclination().multiply(sinLatitude);
BigDecimal top = cosineZenith.subtract(sinDeclinationTimesSinLat);
BigDecimal bottom = getCosineOfSunDeclination().multiply(cosLatitude);

BigDecimal cosineLocalHour = top.divide(bottom, 4, RoundingMode.HALF_EVEN);
return cosineLocalHour;
}

protected BigDecimal getSunLocalHour() {
BigDecimal arcCosineOfCosineHourAngle = getArcCosineFor(getCosineSunLocalHour());
BigDecimal localHour = BigDecimal.valueOf(360).subtract(arcCosineOfCosineHourAngle);

return localHour.divide(BigDecimal.valueOf(15), 4, RoundingMode.HALF_EVEN);
}

protected BigDecimal getLocalMeanTime() {
BigDecimal innerParens = BigDecimal.valueOf(0.06571).multiply(getLongitudeHour());
BigDecimal localMeanTime = getSunLocalHour().add(getRightAscensionInHours()).subtract(innerParens);
localMeanTime = localMeanTime.subtract(BigDecimal.valueOf(6.622));
return localMeanTime;
}

protected BigDecimal getUTCTime() {
return getLocalMeanTime().subtract(getBaseLongitudeHour());
}

protected BigDecimal getLocalTime() {
return this.getUTCTime().subtract(BigDecimal.valueOf(getUTCOffset()));
}
}

0 comments on commit a0dce78

Please sign in to comment.