From 355c44b95557e386aa0b4088474443d7773b279b Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Wed, 8 Dec 2010 10:14:47 +0000 Subject: [PATCH] sun rise calendar git-svn-id: https://osmand.googlecode.com/svn/trunk@780 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8 --- .../src/net/osmand/SunriseSunset.java | 811 ++++++++++++++++++ 1 file changed, 811 insertions(+) create mode 100644 DataExtractionOSM/src/net/osmand/SunriseSunset.java diff --git a/DataExtractionOSM/src/net/osmand/SunriseSunset.java b/DataExtractionOSM/src/net/osmand/SunriseSunset.java new file mode 100644 index 0000000000..de9758581a --- /dev/null +++ b/DataExtractionOSM/src/net/osmand/SunriseSunset.java @@ -0,0 +1,811 @@ +package net.osmand; +/****************************************************************************** +* +* SunriseSunset.java +* +******************************************************************************* +* +* Java Class: SunriseSunset +* +* This Java class is part of a collection of classes developed for the +* reading and processing of oceanographic and meterological data collected +* since 1970 by environmental buoys and stations. This dataset is +* maintained by the National Oceanographic Data Center and is publicly +* available. These Java classes were written for the US Environmental +* Protection Agency's National Exposure Research Laboratory under Contract +* No. GS-10F-0073K with Neptune and Company of Los Alamos, New Mexico. +* +* Purpose: +* +* This Java class performs calculations to determine the time of +* sunrise and sunset given lat, long, and date. +* +* Inputs: +* +* Latitude, longitude, date/time, and time zone. +* +* Outputs: +* +* Local time of sunrise and sunset as calculated by the +* program. +* If no sunrise or no sunset occurs, or if the sun is up all day +* or down all day, appropriate boolean values are set. +* A boolean is provided to identify if the time provided is during the day. +* +* The above values are accessed by the following methods: +* +* Date getSunrise() returns date/time of sunrise +* Date getSunset() returns date/time of sunset +* boolean isSunrise() returns true if there was a sunrise, else false +* boolean isSunset() returns true if there was a sunset, else false +* boolean isSunUp() returns true if sun is up all day, else false +* boolean isSunDown() returns true if sun is down all day, else false +* boolean isDaytime() returns true if sun is up at the time +* specified, else false +* +* Required classes from the Java library: +* +* java.util.Date +* java.text.SimpleDateFormat +* java.text.ParseException; +* java.math.BigDecimal; +* +* Package of which this class is a member: +* +* default +* +* Known limitations: +* +* It is assumed that the data provided are within valie ranges +* (i.e. latitude between -90 and +90, longitude between 0 and 360, +* a valid date, and time zone between -14 and +14. +* +* Compatibility: +* +* Java 1.1.8 +* +* References: +* +* The mathematical algorithms used in this program are patterned +* after those debveloped by Roger Sinnott in his BASIC program, +* SUNUP.BAS, published in Sky & Telescope magazine: +* Sinnott, Roger W. "Sunrise and Sunset: A Challenge" +* Sky & Telescope, August, 1994 p.84-85 +* +* The following is a cross-index of variables used in SUNUP.BAS. +* A single definition from multiple reuse of variable names in +* SUNUP.BAS was clarified with various definitions in this program. +* +* SUNUP.BAS this class +* +* A dfA +* A(2) dfAA1, dfAA2 +* A0 dfA0 +* A2 dfA2 +* A5 dfA5 +* AZ Not used +* C dfCosLat +* C0 dfC0 +* D iDay +* D(2) dfDD1, dfDD2 +* D0 dfD0 +* D1 dfD1 +* D2 dfD2 +* D5 dfD5 +* D7 Not used +* DA dfDA +* DD dfDD +* G bGregorian, dfGG +* H dfTimeZone +* H0 dfH0 +* H1 dfH1 +* H2 dfH2 +* H3 dfHourRise, dfHourSet +* H7 Not used +* J dfJ +* J3 dfJ3 +* K1 dfK1 +* L dfLL +* L0 dfL0 +* L2 dfL2 +* L5 dfLon +* M iMonth +* M3 dfMinRise, dfMinSet +* N7 Not used +* P dfP +* S iSign, dfSinLat, dfSS +* T dfT +* T0 dfT0 +* T3 not used +* TT dfTT +* U dfUU +* V dfVV +* V0 dfV0 +* V1 dfV1 +* V2 dfV2 +* W dfWW +* Y iYear +* Z dfZenith +* Z0 dfTimeZone +* +* +* Author/Company: +* +* JDT: John Tauxe, Neptune and Company +* JMG: Jo Marie Green +* +* Change log: +* +* date ver by description of change +* _________ _____ ___ ______________________________________________ +* 5 Jan 01 0.006 JDT Excised from ssapp.java v. 0.005. +* 11 Jan 01 0.007 JDT Minor modifications to comments based on +* material from Sinnott, 1994. +* 7 Feb 01 0.008 JDT Fixed backwards time zone. The standard is that +* local time zone is specified in hours EAST of +* Greenwich, so that EST would be -5, for example. +* For some reason, SUNUP.BAS does this backwards +* (probably an americocentric perspective) and +* SunriseSunset adopted that convention. Oops. +* So the sign in the math is changed. +* 7 Feb 01 0.009 JDT Well, that threw off the azimuth calculation... +* Removed the azimuth calculations. +* 14 Feb 01 0.010 JDT Added ability to accept a time (HH:mm) in +* dateInput, and decide if that time is daytime +* or nighttime. +* 27 Feb 01 0.011 JDT Added accessor methods in place of having public +* variables to get results. +* 28 Feb 01 0.012 JDT Cleaned up list of imported classes. +* 28 Mar 01 1.10 JDT Final version accompanying deliverable 1b. +* 4 Apr 01 1.11 JDT Moved logic supporting .isDaytime into method. +* Moved calculations out of constructor. +* 01 May 01 1.12 JMG Added 'GMT' designation and testing lines. +* 16 May 01 1.13 JDT Added setLenient( false ) and setTimeZone( tz ) +* to dfmtDay, dfmtMonth, and dfmtYear in +* doCalculations. +* 27 Jun 01 1.14 JDT Removed reliance on StationConstants (GMT). +* 13 Aug 01 1.20 JDT Final version accompanying deliverable 1c. +* 6 Sep 01 1.21 JDT Thorough code and comment review. +* 21 Sep 01 1.30 JDT Final version accompanying deliverable 2. +* 17 Dec 01 1.40 JDT Version accompanying final deliverable. +* +*----------------------------------------------------------------------------*/ + +// Import required classes and packages +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.text.ParseException; +import java.math.BigDecimal; +import java.util.TimeZone; + + +/****************************************************************************** +* class: SunriseSunset class +******************************************************************************* +* +* This Java class performs calculations to determine the time of +* sunrise and sunset given lat, long, and date. +* +* It is assumed that the data provided are within valie ranges +* (i.e. latitude between -90 and +90, longitude between 0 and 360, +* a valid date, and time zone between -14 and +14. +* +*----------------------------------------------------------------------------*/ +public class SunriseSunset +{ + + // Declare and initialize variables + private double dfLat; // latitude from user + private double dfLon; // latitude from user + private Date dateInput; // date/time from user + private double dfTimeZone; // time zone from user + + private Date dateSunrise; // date and time of sunrise + private Date dateSunset; // date and time of sunset + private boolean bSunriseToday = false; // flag for sunrise on this date + private boolean bSunsetToday = false; // flag for sunset on this date + private boolean bSunUpAllDay = false; // flag for sun up all day + private boolean bSunDownAllDay = false; // flag for sun down all day + private boolean bDaytime = false; // flag for daytime, given + // hour and min in dateInput + private boolean bSunrise = false; // sunrise during hour checked + private boolean bSunset = false; // sunset during hour checked + private boolean bGregorian = false; // flag for Gregorian calendar + private int iJulian; // Julian day + private int iYear; // year of date of interest + private int iMonth; // month of date of interest + private int iDay; // day of date of interest + private int iCount; // a simple counter + private int iSign; // SUNUP.BAS: S + private double dfHourRise, dfHourSet; // hour of event: SUNUP.BAS H3 + private double dfMinRise, dfMinSet; // minute of event: SUNUP.BAS M3 + private double dfSinLat, dfCosLat; // sin and cos of latitude + private double dfZenith; // SUNUP.BAS Z: Zenith + private SimpleDateFormat dfmtDate; // formatting for date alone + private SimpleDateFormat dfmtDateTime; // formatting for date and time + private SimpleDateFormat dfmtYear; // formatting for year + private SimpleDateFormat dfmtMonth; // formatting for month + private SimpleDateFormat dfmtDay; // formatting for day + // Many variables in SUNUP.BAS have undocumented meanings, + // and so are translated rather directly to avoid confusion: + private double dfAA1 = 0, dfAA2 = 0; // SUNUP.BAS A(2) + private double dfDD1 = 0, dfDD2 = 0; // SUNUP.BAS D(2) + private double dfC0; // SUNUP.BAS C0 + private double dfK1; // SUNUP.BAS K1 + private double dfP; // SUNUP.BAS P + private double dfJ; // SUNUP.BAS J + private double dfJ3; // SUNUP.BAS J3 + private double dfA; // SUNUP.BAS A + private double dfA0, dfA2, dfA5; // SUNUP.BAS A0, A2, A5 + private double dfD0, dfD1, dfD2, dfD5; // SUNUP.BAS D0, D1, D2, D5 + private double dfDA, dfDD; // SUNUP.BAS DA, DD + private double dfH0, dfH1, dfH2; // SUNUP.BAS H0, H1, H2 + private double dfL0, dfL2; // SUNUP.BAS L0, L2 + private double dfT, dfT0, dfTT; // SUNUP.BAS T, T0, TT + private double dfV0, dfV1, dfV2; // SUNUP.BAS V0, V1, V2 + + private TimeZone tz = TimeZone.getTimeZone( "GMT" ); + + +/****************************************************************************** +* method: SunriseSunset +******************************************************************************* +* +* Constructor for SunriseSunset class. +* +*----------------------------------------------------------------------------*/ + public SunriseSunset( + double dfLatIn, // latitude + double dfLonIn, // longitude + Date dateInputIn, // date + double dfTimeZoneIn // time zone + ) + { + // Copy values supplied as agruments to local variables. + dfLat = dfLatIn; + dfLon = dfLonIn; + dateInput = dateInputIn; + dfTimeZone = dfTimeZoneIn; + + // Call the method to do the calculations. + doCalculations(); + + } // end of class constructor + + +/****************************************************************************** +* method: doCalculations +******************************************************************************* +* +* Method for performing the calculations done in SUNUP.BAS. +* +*----------------------------------------------------------------------------*/ + private void doCalculations() + { + try + { + // Break out day, month, and year from date provided. + // (This is necesary for the math algorithms.) + + dfmtYear = new SimpleDateFormat( "yyyy" ); + dfmtYear.setLenient( false ); + dfmtYear.setTimeZone( tz ); + + dfmtMonth = new SimpleDateFormat( "M" ); + dfmtMonth.setLenient( false ); + dfmtMonth.setTimeZone( tz ); + + dfmtDay = new SimpleDateFormat( "d" ); + dfmtDay.setLenient( false ); + dfmtDay.setTimeZone( tz ); + + iYear = Integer.parseInt( dfmtYear.format( dateInput ) ); + iMonth = Integer.parseInt( dfmtMonth.format( dateInput ) ); + iDay = Integer.parseInt( dfmtDay.format( dateInput ) ); + + // Convert time zone hours to decimal days (SUNUP.BAS line 50) + dfTimeZone = dfTimeZone / 24.0; + + // NOTE: (7 Feb 2001) Here is a non-standard part of SUNUP.BAS: + // It (and this algorithm) assumes that the time zone is + // positive west, instead of the standard negative west. + // Classes calling SunriseSunset will be assuming that + // times zones are specified in negative west, so here the + // sign is changed so that the SUNUP algorithm works: + dfTimeZone = -dfTimeZone; + + // Convert longitude to fraction (SUNUP.BAS line 50) + dfLon = dfLon / 360.0; + + // Convert calendar date to Julian date: + // Check to see if it's later than 1583: Gregorian calendar + // When declared, bGregorian is initialized to false. + // ** Consider making a separate class of this function. ** + if( iYear >= 1583 ) bGregorian = true; + // SUNUP.BAS 1210 + dfJ = -Math.floor( 7.0 // SUNUP used INT, not floor + * ( Math.floor( + ( iMonth + 9.0 ) + / 12.0 + ) + iYear + ) / 4.0 + ) + // add SUNUP.BAS 1240 and 1250 for G = 0 + + Math.floor( iMonth * 275.0 / 9.0 ) + + iDay + + 1721027.0 + + iYear * 367.0; + + if ( bGregorian ) + { + // SUNUP.BAS 1230 + if ( ( iMonth - 9.0 ) < 0.0 ) iSign = -1; + else iSign = 1; + dfA = Math.abs( iMonth - 9.0 ); + // SUNUP.BAS 1240 and 1250 + dfJ3 = -Math.floor( + ( + Math.floor( + Math.floor( iYear + + (double)iSign + * Math.floor( dfA / 7.0 ) + ) + / 100.0 + ) + 1.0 + ) * 0.75 + ); + // correct dfJ as in SUNUP.BAS 1240 and 1250 for G = 1 + dfJ = dfJ + dfJ3 + 2.0; + } + // SUNUP.BAS 1290 + iJulian = (int)dfJ - 1; + + // SUNUP.BAS 60 and 70 (see also line 1290) + dfT = (double)iJulian - 2451545.0 + 0.5; + dfTT = dfT / 36525.0 + 1.0; // centuries since 1900 + + // Calculate local sidereal time at 0h in zone time + // SUNUP.BAS 410 through 460 + dfT0 = ( dfT * 8640184.813 / 36525.0 + + 24110.5 + + dfTimeZone * 86636.6 + + dfLon * 86400.0 + ) + / 86400.0; + dfT0 = dfT0 - Math.floor( dfT0 ); // NOTE: SUNUP.BAS uses INT() + dfT0 = dfT0 * 2.0 * Math.PI; + // SUNUP.BAS 90 + dfT = dfT + dfTimeZone; + + // SUNUP.BAS 110: Get Sun's position + for( iCount=0; iCount<=1; iCount++ ) // Loop thru only twice + { + // Calculate Sun's right ascension and declination + // at the start and end of each day. + // SUNUP.BAS 910 - 1160: Fundamental arguments + // from van Flandern and Pulkkinen, 1979 + + // declare local temporary doubles for calculations + double dfGG; // SUNUP.BAS G + double dfLL; // SUNUP.BAS L + double dfSS; // SUNUP.BAS S + double dfUU; // SUNUP.BAS U + double dfVV; // SUNUP.BAS V + double dfWW; // SUNUP.BAS W + + dfLL = 0.779072 + 0.00273790931 * dfT; + dfLL = dfLL - Math.floor( dfLL ); + dfLL = dfLL * 2.0 * Math.PI; + + dfGG = 0.993126 + 0.0027377785 * dfT; + dfGG = dfGG - Math.floor( dfGG ); + dfGG = dfGG * 2.0 * Math.PI; + + dfVV = 0.39785 * Math.sin( dfLL ) + - 0.01000 * Math.sin( dfLL - dfGG ) + + 0.00333 * Math.sin( dfLL + dfGG ) + - 0.00021 * Math.sin( dfLL ) * dfTT; + + dfUU = 1 + - 0.03349 * Math.cos( dfGG ) + - 0.00014 * Math.cos( dfLL * 2.0 ) + + 0.00008 * Math.cos( dfLL ); + + dfWW = - 0.00010 + - 0.04129 * Math.sin( dfLL * 2.0 ) + + 0.03211 * Math.sin( dfGG ) + - 0.00104 * Math.sin( 2.0 * dfLL - dfGG ) + - 0.00035 * Math.sin( 2.0 * dfLL + dfGG ) + - 0.00008 * Math.sin( dfGG ) * dfTT; + + // Compute Sun's RA and Dec; SUNUP.BAS 1120 - 1140 + dfSS = dfWW / Math.sqrt( dfUU - dfVV * dfVV ); + dfA5 = dfLL + + Math.atan( dfSS / Math.sqrt( 1.0 - dfSS * dfSS )); + + dfSS = dfVV / Math.sqrt( dfUU ); + dfD5 = Math.atan( dfSS / Math.sqrt( 1 - dfSS * dfSS )); + + // Set values and increment t + if ( iCount == 0 ) // SUNUP.BAS 125 + { + dfAA1 = dfA5; + dfDD1 = dfD5; + } + else // SUNUP.BAS 145 + { + dfAA2 = dfA5; + dfDD2 = dfD5; + } + dfT = dfT + 1.0; // SUNUP.BAS 130 + } // end of Get Sun's Position for loop + + if ( dfAA2 < dfAA1 ) dfAA2 = dfAA2 + 2.0 * Math.PI; + // SUNUP.BAS 150 + + dfZenith = Math.PI * 90.833 / 180.0; // SUNUP.BAS 160 + dfSinLat = Math.sin( dfLat * Math.PI / 180.0 ); // SUNUP.BAS 170 + dfCosLat = Math.cos( dfLat * Math.PI / 180.0 ); // SUNUP.BAS 170 + + dfA0 = dfAA1; // SUNUP.BAS 190 + dfD0 = dfDD1; // SUNUP.BAS 190 + dfDA = dfAA2 - dfAA1; // SUNUP.BAS 200 + dfDD = dfDD2 - dfDD1; // SUNUP.BAS 200 + + dfK1 = 15.0 * 1.0027379 * Math.PI / 180.0; // SUNUP.BAS 330 + + // Initialize sunrise and sunset times, and other variables + // hr and min are set to impossible times to make errors obvious + dfHourRise = 99.0; + dfMinRise = 99.0; + dfHourSet = 99.0; + dfMinSet = 99.0; + dfV0 = 0.0; // initialization implied by absence in SUNUP.BAS + dfV2 = 0.0; // initialization implied by absence in SUNUP.BAS + + // Test each hour to see if the Sun crosses the horizon + // and which way it is heading. + for( iCount=0; iCount<24; iCount++ ) // SUNUP.BAS 210 + { + double tempA; // SUNUP.BAS A + double tempB; // SUNUP.BAS B + double tempD; // SUNUP.BAS D + double tempE; // SUNUP.BAS E + + dfC0 = (double)iCount; + dfP = ( dfC0 + 1.0 ) / 24.0; // SUNUP.BAS 220 + dfA2 = dfAA1 + dfP * dfDA; // SUNUP.BAS 230 + dfD2 = dfDD1 + dfP * dfDD; // SUNUP.BAS 230 + dfL0 = dfT0 + dfC0 * dfK1; // SUNUP.BAS 500 + dfL2 = dfL0 + dfK1; // SUNUP.BAS 500 + dfH0 = dfL0 - dfA0; // SUNUP.BAS 510 + dfH2 = dfL2 - dfA2; // SUNUP.BAS 510 + // hour angle at half hour + dfH1 = ( dfH2 + dfH0 ) / 2.0; // SUNUP.BAS 520 + // declination at half hour + dfD1 = ( dfD2 + dfD0 ) / 2.0; // SUNUP.BAS 530 + + // Set value of dfV0 only if this is the first hour, + // otherwise, it will get set to the last dfV2 (SUNUP.BAS 250) + if ( iCount == 0 ) // SUNUP.BAS 550 + { + dfV0 = dfSinLat * Math.sin( dfD0 ) + + dfCosLat * Math.cos( dfD0 ) * Math.cos( dfH0 ) + - Math.cos( dfZenith ); // SUNUP.BAS 560 + } + else + dfV0 = dfV2; // That is, dfV2 from the previous hour. + + dfV2 = dfSinLat * Math.sin( dfD2 ) + + dfCosLat * Math.cos( dfD2 ) * Math.cos( dfH2 ) + - Math.cos( dfZenith ); // SUNUP.BAS 570 + + // if dfV0 and dfV2 have the same sign, then proceed to next hr + if ( + ( dfV0 >= 0.0 && dfV2 >= 0.0 ) // both are positive + || // or + ( dfV0 < 0.0 && dfV2 < 0.0 ) // both are negative + ) + { + // Break iteration and proceed to test next hour + dfA0 = dfA2; // SUNUP.BAS 250 + dfD0 = dfD2; // SUNUP.BAS 250 + continue; // SUNUP.BAS 610 + } + + dfV1 = dfSinLat * Math.sin( dfD1 ) + + dfCosLat * Math.cos( dfD1 ) * Math.cos( dfH1 ) + - Math.cos( dfZenith ); // SUNUP.BAS 590 + + tempA = 2.0 * dfV2 - 4.0 * dfV1 + 2.0 * dfV0; + // SUNUP.BAS 600 + tempB = 4.0 * dfV1 - 3.0 * dfV0 - dfV2; // SUNUP.BAS 600 + tempD = tempB * tempB - 4.0 * tempA * dfV0; // SUNUP.BAS 610 + + if ( tempD < 0.0 ) + { + // Break iteration and proceed to test next hour + dfA0 = dfA2; // SUNUP.BAS 250 + dfD0 = dfD2; // SUNUP.BAS 250 + continue; // SUNUP.BAS 610 + } + + tempD = Math.sqrt( tempD ); // SUNUP.BAS 620 + + // Determine occurence of sunrise or sunset. + + // Flags to identify occurrence during this day are + // bSunriseToday and bSunsetToday, and are initialized false. + // These are set true only if sunrise or sunset occurs + // at any point in the hourly loop. Never set to false. + + // Flags to identify occurrence during this hour: + bSunrise = false; // reset before test + bSunset = false; // reset before test + + if ( dfV0 < 0.0 && dfV2 > 0.0 ) // sunrise occurs this hour + { + bSunrise = true; // SUNUP.BAS 640 + bSunriseToday = true; // sunrise occurred today + } + + if ( dfV0 > 0.0 && dfV2 < 0.0 ) // sunset occurs this hour + { + bSunset = true; // SUNUP.BAS 660 + bSunsetToday = true; // sunset occurred today + } + + tempE = ( tempD - tempB ) / ( 2.0 * tempA ); + if ( tempE > 1.0 || tempE < 0.0 ) // SUNUP.BAS 670, 680 + tempE = ( -tempD - tempB ) / ( 2.0 * tempA ); + + // Set values of hour and minute of sunset or sunrise + // only if sunrise/set occurred this hour. + if ( bSunrise ) + { + dfHourRise = Math.floor( dfC0 + tempE + 1.0/120.0 ); + dfMinRise = Math.floor( + ( dfC0 + tempE + 1.0/120.0 + - dfHourRise + ) + * 60.0 + ); + } + + if ( bSunset ) + { + dfHourSet = Math.floor( dfC0 + tempE + 1.0/120.0 ); + dfMinSet = Math.floor( + ( dfC0 + tempE + 1.0/120.0 + - dfHourSet + ) + * 60.0 + ); + } + + // Change settings of variables for next loop + dfA0 = dfA2; // SUNUP.BAS 250 + dfD0 = dfD2; // SUNUP.BAS 250 + + } // end of loop testing each hour for an event + + // After having checked all hours, set flags if no rise or set + // bSunUpAllDay and bSundownAllDay are initialized as false + if ( !bSunriseToday && !bSunsetToday ) + { + if ( dfV2 < 0.0 ) + bSunDownAllDay = true; + else + bSunUpAllDay = true; + } + + // Load dateSunrise with data + dfmtDateTime = new SimpleDateFormat( "d M yyyy HH:mm z" ); + if( bSunriseToday ) + { + dateSunrise = dfmtDateTime.parse( iDay + + " " + iMonth + + " " + iYear + + " " + (int)dfHourRise + + ":" + (int)dfMinRise + + " GMT" ); + } + + // Load dateSunset with data + if( bSunsetToday ) + { + dateSunset = dfmtDateTime.parse( iDay + + " " + iMonth + + " " + iYear + + " " + (int)dfHourSet + + ":" + (int)dfMinSet + + " GMT" ); + } + } // end of try + + // Catch errors + catch( ParseException e ) + { + System.out.println( "\nCannot parse date" ); + System.out.println( e ); + System.exit( 1 ); + } // end of catch + + } + + +/****************************************************************************** +* method: getSunrise() +******************************************************************************* +* +* Gets the date and time of sunrise. If there is no sunrise, returns null. +* +* Member of SunriseSunset class +* +* -------------------------------------------------------------------------- */ + public Date getSunrise() + { + if ( bSunriseToday ) + return( dateSunrise ); + else + return( null ); + } + + +/****************************************************************************** +* method: getSunset() +******************************************************************************* +* +* Gets the date and time of sunset. If there is no sunset, returns null. +* +* Member of SunriseSunset class +* +* -------------------------------------------------------------------------- */ + public Date getSunset() + { + if ( bSunsetToday ) + return( dateSunset ); + else + return( null ); + } + + +/****************************************************************************** +* method: isSunrise() +******************************************************************************* +* +* Returns a boolean identifying if there was a sunrise. +* +* Member of SunriseSunset class +* +* -------------------------------------------------------------------------- */ + public boolean isSunrise() + { + return( bSunriseToday ); + } + + +/****************************************************************************** +* method: isSunset() +******************************************************************************* +* +* Returns a boolean identifying if there was a sunset. +* +* Member of SunriseSunset class +* +* -------------------------------------------------------------------------- */ + public boolean isSunset() + { + return( bSunsetToday ); + } + + +/****************************************************************************** +* method: isSunUp() +******************************************************************************* +* +* Returns a boolean identifying if the sun is up all day. +* +* Member of SunriseSunset class +* +* -------------------------------------------------------------------------- */ + public boolean isSunUp() + { + return( bSunUpAllDay ); + } + + +/****************************************************************************** +* method: isSunDown() +******************************************************************************* +* +* Returns a boolean identifying if the sun is down all day. +* +* Member of SunriseSunset class +* +* -------------------------------------------------------------------------- */ + public boolean isSunDown() + { + return( bSunDownAllDay ); + } + + +/****************************************************************************** +* method: isDaytime() +******************************************************************************* +* +* Returns a boolean identifying if it is daytime at the hour contained in +* the Date object passed to SunriseSunset on construction. +* +* Member of SunriseSunset class +* +* -------------------------------------------------------------------------- */ + public boolean isDaytime() + { + // Determine if it is daytime (at sunrise or later) + // or nighttime (at sunset or later) at the location of interest + // but expressed in the time zone requested. + if ( bSunriseToday && bSunsetToday ) // sunrise and sunset + { + if ( dateSunrise.before( dateSunset ) ) // sunrise < sunset + { + if ( + ( + dateInput.after( dateSunrise ) + || + dateInput.equals( dateSunrise ) + ) + && + dateInput.before( dateSunset ) + ) + bDaytime = true; + else + bDaytime = false; + } + else // sunrise comes after sunset (in opposite time zones) + { + if ( + ( + dateInput.after( dateSunrise ) + || + dateInput.equals( dateSunrise ) + ) + || // use OR rather than AND + dateInput.before( dateSunset ) + ) + bDaytime = true; + else + bDaytime = false; + } + } + else if ( bSunUpAllDay ) // sun is up all day + bDaytime = true; + else if ( bSunDownAllDay ) // sun is down all day + bDaytime = false; + else if ( bSunriseToday ) // sunrise but no sunset + { + if ( dateInput.before( dateSunrise ) ) + bDaytime = false; + else + bDaytime = true; + } + else if ( bSunsetToday ) // sunset but no sunrise + { + if ( dateInput.before( dateSunset ) ) + bDaytime = true; + else + bDaytime = false; + } + else bDaytime = false; // this should never execute + + return( bDaytime ); + } + +} // end of class + +/*----------------------------------------------------------------------------- +* end of class +*----------------------------------------------------------------------------*/ \ No newline at end of file