

/* * * * * * * * * *    SUNRISET SCRIPT    * * * * * * * * * *\
*                                                             *
*     Computes Sun rise/set times, start/end of twilight.     *
*                                                             *
*        Originally written as DAYLEN.C, 1989-08-16           *
*            Modified to SUNRISET.C, 1992-12-01               *
*              (c) Paul Schlyter, 1989, 1992                  *
*                                                             *
*        Released to the public domain by Paul Schlyter, Dec. 1992  *
*                                                             *
*  --  Modified by Bo Johansson  1995-05-12 , 1995-10-14  --  *
*  --  Ported to JavaScript by Bo Johansson  1998-05-22   --  *
*  --   Slight modification by Bo Johansson  1998-06-29   --  *
*                                                             *
*  --   http://home3.swipnet.se/%7Ew-32150/index_e.htm    --  *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

// Global variables:

var twAngle = -6.0;    // For civil twilight, set to -12.0 for
                       // nautical, and -18.0 for astr. twilight

var srAngle = -35.0/60.0;    // For sunrise/sunset

var sRiseT;        // For sunrise/sunset times
var sSetT;
var srStatus;

var twStartT;      // For twilight times
var twEndT;
var twStatus;

var sDIST;     // Solar distance, astronomical units
var sRA;       // Sun's Right Ascension
var sDEC;      // Sun's declination

var sLON;      // True solar longitude

//-------------------------------------------------------------
// A function to compute the number of days elapsed since
// 2000 Jan 0.0  (which is equal to 1999 Dec 31, 0h UT)
//-------------------------------------------------------------
function dayDiff2000(y,m,d)
{
  return (367.0*(y)-((7*((y)+(((m)+9)/12)))/4)+
          ((275*(m))/9)+(d)-730530.0);
}

//-------------------------------------------------------------
// Some conversion factors between radians and degrees

var RADEG = 180.0 / Math.PI
var DEGRAD = Math.PI / 180.0

//-------------------------------------------------------------
// The trigonometric functions in degrees

function sind(x) { return Math.sin((x)*DEGRAD); }
function cosd(x) { return Math.cos((x)*DEGRAD); }
function tand(x) { return Math.tan((x)*DEGRAD); }

function atand(x) { return (RADEG*Math.atan(x)); }
function asind(x) { return (RADEG*Math.asin(x)); }
function acosd(x) { return (RADEG*Math.acos(x)); }

//function atan2d(y,x) { return (RADEG*Math.atan2(y,x)); }

function atan2d(y,x)          //###  Hack to work in MSIE3 ###
{
  var at2 = (RADEG*Math.atan(y/x));

  if( x < 0 && y < 0)
    at2 -= 180;

  else if( x < 0 && y > 0)
    at2 += 180;

  return at2;
}

//-------------------------------------------------------------
// This function computes times for sunrise/sunset.
// Sunrise/sunset is considered to occur when the Sun's upper
// limb is 35 arc minutes below the horizon (this accounts for
// the refraction of the Earth's atmosphere).
//-------------------------------------------------------------
function sunRiseSet(year,month,day,lat,lon)
{
  return ( sunTimes( year, month, day, lat, lon, srAngle, 1) )
}

//-------------------------------------------------------------
// This function computes the start and end times of civil
// twilight. Civil twilight starts/ends when the Sun's center
// is 6 degrees below the horizon.
//-------------------------------------------------------------
function civTwilight(year,month,day,lat,lon)
{
  return ( sunTimes( year, month, day, lat, lon, twAngle, 0) )
}

//-------------------------------------------------------------
// The "workhorse" function for sun rise/set times
//
// year,month,date = calendar date, 1801-2099 only.

//                      Should be 1901-2099 ???

// Eastern longitude positive, Western longitude negative
// Northern latitude positive, Southern latitude negative
//
// altit = the altitude which the Sun should cross. Set to
//         -35/60 degrees for rise/set, -6 degrees for civil,
//         -12 degrees for nautical and -18 degrees for
//         astronomical twilight.
//
// sUppLimb: non-zero -> upper limb, zero -> center. Set to
//           non-zero (e.g. 1) when computing rise/set times,
//           and to zero when computing start/end of twilight.
//
// Status:  0 = sun rises/sets this day, times stored in Global
//              variables
//          1 = sun above the specified "horizon" 24 hours.
//              Rising set to time when the sun is at south,
//              minus 12 hours while Setting is set to the
//              south time plus 12 hours.
//         -1 = sun is below the specified "horizon" 24 hours.
//              Rising and Setting are both set to the time
//              when the sun is at south.
//-------------------------------------------------------------
function sunTimes(year, month, day, lat, lon, altit, sUppLimb)
{
  var dayDiff    // Days since 2000 Jan 0.0 (negative before)
  var sRadius    // Sun's apparent radius
  var diuArc     // Diurnal arc
  var sSouthT    // Time when Sun is at south
  var locSidT    // Local sidereal time

  var stCode = 0     // Status code from function - usually 0

      /* Compute dayDiff of 12h local mean solar time */

  dayDiff = dayDiff2000(year,month,day) + 0.5 - lon/360.0;

      /* Compute local sideral time of this moment */

  locSidT = revolution( GMST0(dayDiff) + 180.0 + lon );

      /* Compute Sun's RA + Decl at this moment */

  sunRaDec( dayDiff );

      /* Compute time when Sun is at south - in hours UT */


  sSouthT = 12.0 - rev180(locSidT - sRA)/15.0;

      /* Compute the Sun's apparent radius, degrees */

  sRadius = 0.2666 / sDIST;

      /* Do correction to upper limb, if necessary */

  if ( sUppLimb != 0)            // For surise/sunset
    altit -= sRadius;

      /* Compute the diurnal arc that the Sun traverses */
      /* to reach the specified altitude altit:         */
  {
     var cost;
     cost = ( sind(altit) - sind(lat) * sind(sDEC) ) /
             ( cosd(lat) * cosd(sDEC) );

     if ( cost >= 1.0 )
     {
       stCode = -1;
       diuArc = 0.0;       // Sun always below altit
     }

     else if ( cost <= -1.0 )
     {
       stCode = 1;
       diuArc = 12.0;      // Sun always above altit
     }

     else
       diuArc = acosd(cost)/15.0;   // The diurnal arc, hours
  }

      /* Store rise and set times - in hours UT */

  if ( sUppLimb != 0)       // For sunrise/sunset
  {
    sRiseT = sSouthT - diuArc;

    if(sRiseT < 0)        // Sunrise day before
      sRiseT += 24;

    sSetT  = sSouthT + diuArc;

    if(sSetT > 24)        // Sunset next day
      sSetT -= 24;

    srStatus = stCode;
  }
  else                      // For twilight times
  {
    twStartT = sSouthT - diuArc;

    if(twStartT < 0)
      twStartT += 24;

    twEndT  = sSouthT + diuArc;

    if(twEndT > 24)
      twEndT -= 24;

    twStatus = stCode;
  }
} //================== sunTimes() =====================

//-------------------------------------------------------------
// This function computes the sun's spherical coordinates
//-------------------------------------------------------------
function sunRaDec(dayDiff)
{
  var eclObl;   // Obliquity of ecliptic
                // (inclination of Earth's axis)
  var x;
  var y;
  var z;

      /* Compute Sun's ecliptical coordinates */

  sunPos( dayDiff );

      /* Compute ecliptic rectangular coordinates (z=0) */

  x = sDIST * cosd(sLON);

  y = sDIST * sind(sLON);

      /* Compute obliquity of ecliptic */
      /* (inclination of Earth's axis) */

//  eclObl = 23.4393 - 3.563E-7 * dayDiff;

  eclObl = 23.4393 - 3.563/10000000 * dayDiff;  // for Opera

      /* Convert to equatorial rectangular coordinates */
      /* - x is uchanged                               */

  z = y * sind(eclObl);
  y = y * cosd(eclObl);

      /* Convert to spherical coordinates */

  sRA = atan2d( y, x );
  sDEC = atan2d( z, Math.sqrt(x*x + y*y) );

} //================= sunRaDec() =======================

//-------------------------------------------------------------
// Computes the Sun's ecliptic longitude and distance
// at an instant given in dayDiff, number of days since
// 2000 Jan 0.0.  The Sun's ecliptic latitude is not
// computed, since it's always very near 0.
//-------------------------------------------------------------
function sunPos(dayDiff)
{
  var M;       // Mean anomaly of the Sun
  var w;       // Mean longitude of perihelion
               // Note: Sun's mean longitude = M + w
  var e;       // Eccentricity of Earth's orbit
  var eAN;     // Eccentric anomaly
  var x;       // x, y coordinates in orbit
  var y;
  var v;       // True anomaly

      /* Compute mean elements */

  M = revolution( 356.0470 + 0.9856002585 * dayDiff );

//  w = 282.9404 + 4.70935E-5 * dayDiff;
//  e = 0.016709 - 1.151E-9 * dayDiff;

  w = 282.9404 + 4.70935/100000 * dayDiff;    // for Opera
  e = 0.016709 - 1.151/1000000000 * dayDiff;  // for Opera

      /* Compute true longitude and radius vector */

  eAN = M + e * RADEG * sind(M) * ( 1.0 + e * cosd(M) );

  x = cosd(eAN) - e;
  y = Math.sqrt( 1.0 - e*e ) * sind(eAN);

  sDIST = Math.sqrt( x*x + y*y );    // Solar distance

  v = atan2d( y, x );                // True anomaly

  sLON = v + w;                      // True solar longitude

  if ( sLON >= 360.0 )
    sLON -= 360.0;                   // Make it 0..360 degrees

} //=================== sunPos() =============================

var INV360 = 1.0 / 360.0;

//-------------------------------------------------------------
// Reduce angle to within 0..360 degrees
//-------------------------------------------------------------
function revolution( x )
{
  return (x - 360.0 * Math.floor( x * INV360 ));
}

//-------------------------------------------------------------
// Reduce angle to within -180..+180 degrees
//-------------------------------------------------------------
function rev180( x )
{
  return ( x - 360.0 * Math.floor( x * INV360 + 0.5 ) );
}

//-------------------------------------------------------------
// This function computes GMST0, the Greenwhich Mean Sidereal
// Time at 0h UT (i.e. the sidereal time at the Greenwhich
// meridian at 0h UT).
// GMST is then the sidereal time at Greenwich at any time of
// the day.  GMST0 is generalized as well, and is defined as:
//
//  GMST0 = GMST - UT
//
// This allows GMST0 to be computed at other times than 0h UT
// as well.  While this sounds somewhat contradictory, it is
// very practical:
// Instead of computing GMST like:
//
//  GMST = (GMST0) + UT * (366.2422/365.2422)
//
// where (GMST0) is the GMST last time UT was 0 hours, one simply
// computes:
//
//  GMST = GMST0 + UT
//
// where GMST0 is the GMST "at 0h UT" but at the current moment!
// Defined in this way, GMST0 will increase with about 4 min a
// day.  It also happens that GMST0 (in degrees, 1 hr = 15 degr)
// is equal to the Sun's mean longitude plus/minus 180 degrees!
// (if we neglect aberration, which amounts to 20 seconds of arc
// or 1.33 seconds of time)
//-------------------------------------------------------------
function GMST0( dayDiff )
{
  var const1 = 180.0 + 356.0470 + 282.9404;

//  var const2 = 0.9856002585 + 4.70935E-5;

  var const2 = 0.9856002585 + 4.70935/100000;  // for Opera

  return ( revolution( const1 + const2 * dayDiff ) );

} //=================== GMST0() =========================

/* * * * * * * *    SUNRISET SCRIPT - END -  * * * * * * * * */

/* * * * * * * * * *     SUNFORM SCRIPT    * * * * * * * * * *\
*                                                             *
*  Uses input from a form to computes Sun rise/set times,     *
*  start/end of twilight, using the SUNRISET script.          *
*                                                             *
*  In English (lCode = 0) or Swedish (lCode = 1)              *
*                                                             *
*  --  Written by Bo Johansson  1998-05-24 , 1998-06-29  --   *
*                                                             *
*  --   http://home3.swipnet.se/%7Ew-32150/index_e.htm    --  *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

function calculateSunRiseSet(year,month,day)
{
  var latText = "Latitude"
  var lonText = "Longitude"
  var yearText = "Year"
  var monthText = "Month"
  var dayText = "Date"

  var lat = 44
  var absLat = Math.abs(lat)
  var lon = 11
  var absLon = Math.abs(lon)

  sunRiseSet(year,month,day,lat,lon);
  civTwilight(year,month,day,lat,lon);

  var resultText = ""
  
  var twsText = "L' alba inizia alle "
  var tweText = "Il crepuscolo finisce alle "
  var srText = "Il sole sorge alle "
  var ssText = "Il sole tramonta alle "
  var offSet = 1
  
  if ( 	(month < 10 && month > 3)  || 
  	(month == 3 && day >= 27) || 
  	(month == 10 && day <= 27)
     ) {
  	offSet = 2
  }	
  
  twStartT = twStartT + offSet
  sRiseT = sRiseT + offSet
  sSetT = sSetT + offSet
  twEndT = twEndT + offSet
  
  
  var twst_h = Math.floor(twStartT) 
  var twst_m = Math.floor((twStartT - twst_h)*60)
  var sris_h = Math.floor(sRiseT) 
  var sris_m = Math.floor((sRiseT - sris_h)*60)
  var sset_h = Math.floor(sSetT) 
  var sset_m = Math.floor((sSetT - sset_h)*60)
  var twen_h = Math.floor(twEndT) 
  var twen_m = Math.floor((twEndT - twen_h)*60)

  /*if(twStatus == 0)  {
    resultText += twsText
    resultText += "<em>"
    if(twst_h < 10) resultText += "0"
    resultText += twst_h + ":"
    if(twst_m < 10) resultText += "0"
    resultText += twst_m + "</em><br>"
  }*/

  if(srStatus == 0) {
    resultText += srText
    resultText += "<em>"
    if(sris_h < 10) resultText += "0"
    resultText +=  sris_h + ":"
    if(sris_m < 10)resultText += "0"
    resultText += sris_m + "</em><br>"
    resultText += ssText
    resultText += "<em>"
    if(sset_h < 10) resultText += "0"
    resultText += sset_h + ":"
    if(sset_m < 10) resultText += "0"
    resultText += sset_m + "</em><br>"
  }

  /*if(twStatus == 0) {
    resultText +=  tweText
    resultText += "<em>"
    if(twen_h < 10)resultText += "0"
    resultText += twen_h + ":"
    if(twen_m < 10)resultText += "0"
    resultText += twen_m + "</em><br>"
  }*/

  return (resultText);

}  
//================= calculateSunRiseSet() =========================

/* * * * * * * * *   SUNFORM SCRIPT - END -  * * * * * * * * */

/* * * * * * * * * *    SUNTABLE SCRIPT    * * * * * * * * * *\
*                                                             *
*  Uses the SUNRISET script to computes Sun rise/set times,   *
*  start/end of twilight, and displays them in a table.       *
*                                                             *
*  In English (lCode = 0) or Italiano (lCode = 1)             *
*                                                             *
*  --  Written by Bo Johansson  1998-05-24 , 1998-06-29  --   *
*                                                             *
*  --   http://home3.swipnet.se/%7Ew-32150/index_e.htm    --  *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */