Click here to Skip to main content
Email Password   helpLost your password?

Introduction

This simple C# Singleton class calculates the sunrise and sunset times for a given date.

Background

After searching for a simple and decent implementation for calculating sunrise and sunset times for given dates, and trying several implementations that were either too complicated to migrate to C# or simply not working, I found a simple yet working JavaScript implementation here.

I migrated the code to C#, tweaking it a little so that it provides accurate calculations. Also, I wrapped it as a Singleton class (assuming multiple instances would not be required for such a class) and added a lock to the main calculation method, in order to make it thread safe (via blocking).

Using the Code

The singleton class SunTimes can be called from anywhere in your code by calling SunTimes.Instance.

The class contains a single method, with one overload, named CalculateSunRiseSetTimes(). You simply call this method, provide it with three input parameters: latitude and longitude of the desired location, and date for which to calculate. Moreover, you need to pass it four (4) output (ref) parameters: riseTime (sunrise time), setTime (sunset time), isSunrise (does the sun rise that day at all?) and isSunset (does the sun set that day at all?).

The method returns a boolean value if the calculation succeeds (it will fail, if the time zone and longitude are incompatible).

Here is a sample usage of the class:

...

DateTime date = DateTime.Today;
bool isSunrise = false;
bool isSunset = false;
DateTime sunrise = DateTime.Now;
DateTime sunset = DateTime.Now;

// Print out the Sunrise and Sunset times for the next 20 days
for (int i=0; i<20; i++)
{
                                                // Coordinates of Tel-Aviv
     SunTimes.Instance.CalculateSunRiseSetTimes(new SunTimes.LatitudeCoords
                                   (32, 4, 0, SunTimes.LatitudeCoords.Direction.North),
                                                new SunTimes.LongitudeCoords
                                   (34, 46, 0, SunTimes.LongitudeCoords.Direction.East),
                                                date, ref sunrise, ref sunset, 
			                     ref isSunrise, ref isSunset);

     Debug.Print(date + '': Sunrise @'' + sunrise.ToString('HH:mm') + ''  
				Sunset @'' + sunset.ToString(''HH:mm''));

     date = date.AddDays(1); // Move to the next day
}

...

Points of Interest

This implementation is not in particular fancy, not is it the slickest design, but hey - it does the work (at least as far as I've tested it). I will be happy to get any comments (not on its design, please, only if you detect any actual bugs).

History

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralKILLER BUG [modified]
Jools557
14:09 26 Apr '09  
Other than having to remove "using System.Linq;", the code works BUT NOT IN ALL SCENARIOS.

The following 'error check’ actually introduces an error and needs to be removed: -
-----------------
if ((Sign(zone) == Sign(lon)) && (zone != 0))
{
Debug.Print("WARNING: time zone and longitude are incompatible!");
return false;
}
-----------------;
This error check is inappropriate because in reality countries have adopted pragmatic "time zone(s)" based on country / state / county borders, regardless of whether those borders happen to stray across actual time zones.

If the code above is removed, and the TimeZone.CurrentTimeZone and the coordinates are correct, the result will be correct.

An example of where the downloaded code goes wrong:-
The town of Penzance in England uses TimeZone.CurrentTimeZone = "GMT Standard Time" GMT(0), as the rest of England does. It is however in GMT(-1).  GMT(0) starts East of Penzance in Greenwich, London (where time zones were 'invented' - hence "Greenwich Mean Time" (GMT)) - http://en.wikipedia.org/wiki/Greenwich_Mean_Time[^].

Use these coordinates (for Penzance, England, UK) to see the bad result.
(50, 7, 6, SunTimes.LatitudeCoords.Direction.North),
(5, 32, 12, SunTimes.LongitudeCoords.Direction.West)

NB: You will find this problem in virtually every country, so remove the offending code.




BOTTOM LINE: -
Remove these 2 pieces of code and it'll work properly: -
-----------------
using System.Linq;
-----------------

and

-----------------
if ((Sign(zone) == Sign(lon)) && (zone != 0))
{
Debug.Print("WARNING: time zone and longitude are incompatible!");
return false;
}
-----------------

modified on Monday, April 27, 2009 7:51 PM

GeneralRe: KILLER BUG
Zacky Pickholz
23:54 5 May '09  
Thanks Jools! great input.Thumbs Up

Did you happen to test the (fixed) code at locations across the globe, and can tell if basically the code is correct worldwide?

some claim it does not work well in all locations (e.g. Rafone's post below)

Will appreciate any more inputs,

Cheers
GeneralNice but one question [modified]
Rafone
20:50 16 Mar '09  
I live in Arizona USA my tz offset is -7 so I had to fix this line to make it work

original
double zone = -(int)Math.Round(TimeZone.CurrentTimeZone.GetUtcOffset(date).TotalSeconds / 3600);

changed
double zone = (int)Math.Round(TimeZone.CurrentTimeZone.GetUtcOffset(date).TotalSeconds / 3600);

at the current moment the class is calulating
sunrise 5:42
sunset 17:41

the local weather page says...
sunrise 6:36
sunset 18:37

is this because we don't do the dst shuffle??

thanks a bunch...this is neat

rafone

Statistics are like bikini's...
What they reveal is astonishing ...
But what they hide is vital ...

modified on Tuesday, March 17, 2009 2:26 AM

GeneralRe: Nice but one question
Zacky Pickholz
23:51 21 Apr '09  
Hey Rafone,

Thanks for the input, I now know the code might not work worldwide and potentially needs some fixing.

I don't think the (just) an issue of DST. Essentially the code should give the exact sunrise and sunset times down to the minute level, and there is a discrepancy of 6 minutes between the calculated time and your local weather pages (which I assume are accurate).

DST might cause the 1 hour diff, but I'm more alarmed with the 6 minutes diff.

I wish I could give you a better solution, but unfortunately I know zilch about astronomy as opposed to my coding knowledge. I merely adapter/adjusted the code from JavaScript.

Perhaps some other user could provide us with a resolution?
GeneralRe: Nice but one question
PIEBALDconsult
5:13 22 Apr '09  
OT:

Whereabouts in Arizona? I'm in Gold Canyon (near Apache Junction).

CP now has groups, though we don't yet know what to do with them. I created a group called Tosche Station[^]. You may wish to join, if only to see who else is in the area.
GeneralRe: Nice but one question
Rafone
8:05 22 Apr '09  
I'm in Tempe.
I ended up using a class from the NOAA to get sunrise sunset working. It did take into account the astronomical calc's.

rafone

Statistics are like bikini's...
What they reveal is astonishing ...
But what they hide is vital ...

GeneralRe: Nice but one question
Zacky Pickholz
23:49 5 May '09  
Hi Rafone,

Please can you share the class you've found with all of us? or provide a link to it?

Thanks,
Zacky
GeneralRe: Nice but one question
Rafone
3:46 6 May '09  
Hi Guys;

I think the site is...

http://www.srrb.noaa.gov/highlights/sunrise/sunrise.html[^]

The adopted class

using System;
using System.Collections.Generic;
using System.Text;

// NAA - NOAA's Astronomical Algorithms
// (JavaScript web page http://www.srrb.noaa.gov/highlights/sunrise/sunrise.html by
// Chris Cornwall, Aaron Horiuchi and Chris Lehman)
// Ported to C# by Pete Gray (petegray@ieee.org), June 2006
// Released as Open Source and can be used in any way, as long as the above description
// remains in place.

namespace your program
{

static public partial class NAA
{
//*********************************************************************/

// Convert radian angle to degrees

static public double radToDeg(double angleRad)
{
return (180.0 * angleRad / Math.PI);
}

//*********************************************************************/

// Convert degree angle to radians

static public double degToRad(double angleDeg)
{
return (Math.PI * angleDeg / 180.0);
}


//***********************************************************************/
//* Name: calcJD
//* Type: Function
//* Purpose: Julian day from calendar day
//* Arguments:
//* year : 4 digit year
//* month: January = 1
//* day : 1 - 31
//* Return value:
//* The Julian day corresponding to the date
//* Note:
//* Number is returned for start of day. Fractional days should be
//* added later.
//***********************************************************************/

static public double calcJD(int year, int month, int day)
{
if (month <= 2) {
year -= 1;
month += 12;
}
double A = Math.Floor(year/100.0);
double B = 2 - A + Math.Floor(A/4);

double JD = Math.Floor(365.25*(year + 4716)) + Math.Floor(30.6001*(month+1)) + day + B - 1524.5;
return JD;
}

//***********************************************************************/
//* Name: calcTimeJulianCent
//* Type: Function
//* Purpose: convert Julian Day to centuries since J2000.0.
//* Arguments:
//* jd : the Julian Day to convert
//* Return value:
//* the T value corresponding to the Julian Day
//***********************************************************************/

static public double calcTimeJulianCent(double jd)
{
double T = (jd - 2451545.0)/36525.0;
return T;
}


//***********************************************************************/
//* Name: calcJDFromJulianCent
//* Type: Function
//* Purpose: convert centuries since J2000.0 to Julian Day.
//* Arguments:
//* t : number of Julian centuries since J2000.0
//* Return value:
//* the Julian Day corresponding to the t value
//***********************************************************************/

static public double calcJDFromJulianCent(double t)
{
double JD = t * 36525.0 + 2451545.0;
return JD;
}


//***********************************************************************/
//* Name: calGeomMeanLongSun
//* Type: Function
//* Purpose: calculate the Geometric Mean Longitude of the Sun
//* Arguments:
//* t : number of Julian centuries since J2000.0
//* Return value:
//* the Geometric Mean Longitude of the Sun in degrees
//***********************************************************************/

static public double calcGeomMeanLongSun(double t)
{
double L0 = 280.46646 + t * (36000.76983 + 0.0003032 * t);
while(L0 > 360.0)
{
L0 -= 360.0;
}
while(L0 < 0.0)
{
L0 += 360.0;
}
return L0; // in degrees
}


//***********************************************************************/
//* Name: calGeomAnomalySun
//* Type: Function
//* Purpose: calculate the Geometric Mean Anomaly of the Sun
//* Arguments:
//* t : number of Julian centuries since J2000.0
//* Return value:
//* the Geometric Mean Anomaly of the Sun in degrees
//***********************************************************************/

static public double calcGeomMeanAnomalySun(double t)
{
double M = 357.52911 + t * (35999.05029 - 0.0001537 * t);
return M; // in degrees
}

//***********************************************************************/
//* Name: calcEccentricityEarthOrbit
//* Type: Function
//* Purpose: calculate the eccentricity of earth's orbit
//* Arguments:
//* t : number of Julian centuries since J2000.0
//* Return value:
//* the unitless eccentricity
//***********************************************************************/


static public double calcEccentricityEarthOrbit(double t)
{
double e = 0.016708634 - t * (0.000042037 + 0.0000001267 * t);
return e; // unitless
}

//***********************************************************************/
//* Name: calcSunEqOfCenter
//* Type: Function
//* Purpose: calculate the equation of center for the sun
//* Arguments:
//* t : number of Julian centuries since J2000.0
//* Return value:
//* in degrees
//***********************************************************************/


static public double calcSunEqOfCenter(double t)
{
double m = calcGeomMeanAnomalySun(t);

double mrad = degToRad(m);
double sinm = Math.Sin(mrad);
double sin2m = Math.Sin(mrad+mrad);
double sin3m = Math.Sin(mrad+mrad+mrad);

double C = sinm * (1.914602 - t * (0.004817 + 0.000014 * t)) + sin2m * (0.019993 - 0.000101 * t) + sin3m * 0.000289;
return C; // in degrees
}

//***********************************************************************/
//* Name: calcSunTrueLong
//* Type: Function
//* Purpose: calculate the true longitude of the sun
//* Arguments:
//* t : number of Julian centuries since J2000.0
//* Return value:
//* sun's true longitude in degrees
//***********************************************************************/


static public double calcSunTrueLong(double t)
{
double l0 = calcGeomMeanLongSun(t);
double c = calcSunEqOfCenter(t);

double O = l0 + c;
return O; // in degrees
}

//***********************************************************************/
//* Name: calcSunTrueAnomaly
//* Type: Function
//* Purpose: calculate the true anamoly of the sun
//* Arguments:
//* t : number of Julian centuries since J2000.0
//* Return value:
//* sun's true anamoly in degrees
//***********************************************************************/

static public double calcSunTrueAnomaly(double t)
{
double m = calcGeomMeanAnomalySun(t);
double c = calcSunEqOfCenter(t);

double v = m + c;
return v; // in degrees
}

//***********************************************************************/
//* Name: calcSunRadVector
//* Type: Function
//* Purpose: calculate the distance to the sun in AU
//* Arguments:
//* t : number of Julian centuries since J2000.0
//* Return value:
//* sun radius vector in AUs
//***********************************************************************/

static public double calcSunRadVector(double t)
{
double v = calcSunTrueAnomaly(t);
double e = calcEccentricityEarthOrbit(t);

double R = (1.000001018 * (1 - e * e)) / (1 + e * Math.Cos(degToRad(v)));
return R; // in AUs
}

//***********************************************************************/
//* Name: calcSunApparentLong
//* Type: Function
//* Purpose: calculate the apparent longitude of the sun
//* Arguments:
//* t : number of Julian centuries since J2000.0
//* Return value:
//* sun's apparent longitude in degrees
//***********************************************************************/

static public double calcSunApparentLong(double t)
{
double o = calcSunTrueLong(t);

double omega = 125.04 - 1934.136 * t;
double lambda = o - 0.00569 - 0.00478 * Math.Sin(degToRad(omega));
return lambda; // in degrees
}

//***********************************************************************/
//* Name: calcMeanObliquityOfEcliptic
//* Type: Function
//* Purpose: calculate the mean obliquity of the ecliptic
//* Arguments:
//* t : number of Julian centuries since J2000.0
//* Return value:
//* mean obliquity in degrees
//***********************************************************************/

static public double calcMeanObliquityOfEcliptic(double t)
{
double seconds = 21.448 - t*(46.8150 + t*(0.00059 - t*(0.001813)));
double e0 = 23.0 + (26.0 + (seconds/60.0))/60.0;
return e0; // in degrees
}

//***********************************************************************/
//* Name: calcObliquityCorrection
//* Type: Function
//* Purpose: calculate the corrected obliquity of the ecliptic
//* Arguments:
//* t : number of Julian centuries since J2000.0
//* Return value:
//* corrected obliquity in degrees
//***********************************************************************/

static public double calcObliquityCorrection(double t)
{
double e0 = calcMeanObliquityOfEcliptic(t);

double omega = 125.04 - 1934.136 * t;
double e = e0 + 0.00256 * Math.Cos(degToRad(omega));
return e; // in degrees
}

//***********************************************************************/
//* Name: calcSunRtAscension
//* Type: Function
//* Purpose: calculate the right ascension of the sun
//* Arguments:
//* t : number of Julian centuries since J2000.0
//* Return value:
//* sun's right ascension in degrees
//***********************************************************************/

static public double calcSunRtAscension(double t)
{
double e = calcObliquityCorrection(t);
double lambda = calcSunApparentLong(t);

double tananum = (Math.Cos(degToRad(e)) * Math.Sin(degToRad(lambda)));
double tanadenom = (Math.Cos(degToRad(lambda)));
double alpha = radToDeg(Math.Atan2(tananum, tanadenom));
return alpha; // in degrees
}

//***********************************************************************/
//* Name: calcSunDeclination
//* Type: Function
//* Purpose: calculate the declination of the sun
//* Arguments:
//* t : number of Julian centuries since J2000.0
//* Return value:
//* sun's declination in degrees
//***********************************************************************/

static public double calcSunDeclination(double t)
{
double e = calcObliquityCorrection(t);
double lambda = calcSunApparentLong(t);

double sint = Math.Sin(degToRad(e)) * Math.Sin(degToRad(lambda));
double theta = radToDeg(Math.Asin(sint));
return theta; // in degrees
}

//***********************************************************************/
//* Name: calcEquationOfTime
//* Type: Function
//* Purpose: calculate the difference between true solar time and mean
//* solar time
//* Arguments:
//* t : number of Julian centuries since J2000.0
//* Return value:
//* equation of time in minutes of time
//***********************************************************************/

static public double calcEquationOfTime(double t)
{
double epsilon = calcObliquityCorrection(t);
double l0 = calcGeomMeanLongSun(t);
double e = calcEccentricityEarthOrbit(t);
double m = calcGeomMeanAnomalySun(t);

double y = Math.Tan(degToRad(epsilon)/2.0);
y *= y;

double sin2l0 = Math.Sin(2.0 * degToRad(l0));
double sinm = Math.Sin(degToRad(m));
double cos2l0 = Math.Cos(2.0 * degToRad(l0));
double sin4l0 = Math.Sin(4.0 * degToRad(l0));
double sin2m = Math.Sin(2.0 * degToRad(m));

double Etime = y * sin2l0 - 2.0 * e * sinm + 4.0 * e * y * sinm * cos2l0
- 0.5 * y * y * sin4l0 - 1.25 * e * e * sin2m;

return radToDeg(Etime)*4.0; // in minutes of time
}

//***********************************************************************/
//* Name: calcHourAngleSunrise
//* Type: Function
//* Purpose: calculate the hour angle of the sun at sunrise for the
//* latitude
//* Arguments:
//* lat : latitude of observer in degrees
//* solarDec : declination angle of sun in degrees
//* Return value:
//* hour angle of sunrise in radians
//***********************************************************************/

static public double calcHourAngleSunrise(double lat, double solarDec)
{
double latRad = degToRad(lat);
double sdRad = degToRad(solarDec);

double HAarg = (Math.Cos(degToRad(90.833))/(Math.Cos(latRad)*Math.Cos(sdRad))-Math.Tan(latRad) * Math.Tan(sdRad));

double HA = (Math.Acos(Math.Cos(degToRad(90.833))/(Math.Cos(latRad)*Math.Cos(sdRad))-Math.Tan(latRad) * Math.Tan(sdRad)));

return HA; // in radians
}

//***********************************************************************/
//* Name: calcHourAngleSunset
//* Type: Function
//* Purpose: calculate the hour angle of the sun at sunset for the
//* latitude
//* Arguments:
//* lat : latitude of observer in degrees
//* solarDec : declination angle of sun in degrees
//* Return value:
//* hour angle of sunset in radians
//***********************************************************************/

static public double calcHourAngleSunset(double lat, double solarDec)
{
double latRad = degToRad(lat);
double sdRad = degToRad(solarDec);

double HAarg = (Math.Cos(degToRad(90.833))/(Math.Cos(latRad)*Math.Cos(sdRad))-Math.Tan(latRad) * Math.Tan(sdRad));

double HA = (Math.Acos(Math.Cos(degToRad(90.833))/(Math.Cos(latRad)*Math.Cos(sdRad))-Math.Tan(latRad) * Math.Tan(sdRad)));

return -HA; // in radians
}


//***********************************************************************/
//* Name: calcSunriseUTC
//* Type: Function
//* Purpose: calculate the Universal Coordinated Time (UTC) of sunrise
//* for the given day at the given location on earth
//* Arguments:
//* JD : julian day
//* latitude : latitude of observer in degrees
//* longitude : longitude of observer in degrees
//* Return value:
//* time in minutes from zero Z
//***********************************************************************/

static public double calcSunriseUTC(double JD, double latitude, double longitude)
{
double t = calcTimeJulianCent(JD);

// *** Find the time of solar noon at the location, and use
// that declination. This is better than start of the
// Julian day

double noonmin = calcSolNoonUTC(t, longitude);
double tnoon = calcTimeJulianCent (JD+noonmin/1440.0);

// *** First pass to approximate sunrise (using solar noon)

double eqTime = calcEquationOfTime(tnoon);
double solarDec = calcSunDeclination(tnoon);
double hourAngle = calcHourAngleSunrise(latitude, solarDec);

double delta = longitude - radToDeg(hourAngle);
double timeDiff = 4 * delta; // in minutes of time
double timeUTC = 720 + timeDiff - eqTime; // in minutes

// alert("eqTime = " + eqTime + "\nsolarDec = " + solarDec + "\ntimeUTC = " + timeUTC);

// *** Second pass includes fractional jday in gamma calc

double newt = calcTimeJulianCent(calcJDFromJulianCent(t) + timeUTC/1440.0);
eqTime = calcEquationOfTime(newt);
solarDec = calcSunDeclination(newt);
hourAngle = calcHourAngleSunrise(latitude, solarDec);
delta = longitude - radToDeg(hourAngle);
timeDiff = 4 * delta;
timeUTC = 720 + timeDiff - eqTime; // in minutes

// alert("eqTime = " + eqTime + "\nsolarDec = " + solarDec + "\ntimeUTC = " + timeUTC);

return timeUTC;
}

//***********************************************************************/
//* Name: calcSolNoonUTC
//* Type: Function
//* Purpose: calculate the Universal Coordinated Time (UTC) of solar
//* noon for the given day at the given location on earth
//* Arguments:
//* t : number of Julian centuries since J2000.0
//* longitude : longitude of observer in degrees
//* Return value:
//* time in minutes from zero Z
//***********************************************************************/

static public double calcSolNoonUTC(double t, double longitude)
{
// First pass uses approximate solar noon to calculate eqtime
double tnoon = calcTimeJulianCent(calcJDFromJulianCent(t) + longitude/360.0);
double eqTime = calcEquationOfTime(tnoon);
double solNoonUTC = 720 + (longitude * 4) - eqTime; // min

double newt = calcTimeJulianCent(calcJDFromJulianCent(t) -0.5 + solNoonUTC/1440.0);

eqTime = calcEquationOfTime(newt);
// double solarNoonDec = calcSunDeclination(newt);
solNoonUTC = 720 + (longitude * 4) - eqTime; // min

return solNoonUTC;
}

//***********************************************************************/
//* Name: calcSunsetUTC
//* Type: Function
//* Purpose: calculate the Universal Coordinated Time (UTC) of sunset
//* for the given day at the given location on earth
//* Arguments:
//* JD : julian day
//* latitude : latitude of observer in degrees
//* longitude : longitude of observer in degrees
//* Return value:
//* time in minutes from zero Z
//***********************************************************************/

static public double calcSunsetUTC(double JD, double latitude, double longitude)
{
double t = calcTimeJulianCent(JD);

// *** Find the time of solar noon at the location, and use
// that declination. This is better than start of the
// Julian day

double noonmin = calcSolNoonUTC(t, longitude);
double tnoon = calcTimeJulianCent (JD+noonmin/1440.0);

// First calculates sunrise and approx length of day

double eqTime = calcEquationOfTime(tnoon);
double solarDec = calcSunDeclination(tnoon);
double hourAngle = calcHourAngleSunset(latitude, solarDec);

double delta = longitude - radToDeg(hourAngle);
double timeDiff = 4 * delta;
double timeUTC = 720 + timeDiff - eqTime;

// first pass used to include fractional day in gamma calc

double newt = calcTimeJulianCent(calcJDFromJulianCent(t) + timeUTC/1440.0);
eqTime = calcEquationOfTime(newt);
solarDec = calcSunDeclination(newt);
hourAngle = calcHourAngleSunset(latitude, solarDec);

delta = longitude - radToDeg(hourAngle);
timeDiff = 4 * delta;
timeUTC = 720 + timeDiff - eqTime; // in minutes

return timeUTC;
}

}
}


happy coding
rafone

Statistics are like bikini's...
What they reveal is astonishing ...
But what they hide is vital ...

GeneralRe: Nice but one question
Zacky Pickholz
11:29 6 May '09  
Thanks Rafone!

Do you find this code to be working better than my code? if so - how? is it more accurate?

Thanks again,

Zacky
GeneralRe: Nice but one question
Rafone
12:26 6 May '09  
Hey as I stated above yours mostly worked but it was not taking into account my No DST and the civil twlight etc.
This class does take all this into account.

Statistics are like bikini's...
What they reveal is astonishing ...
But what they hide is vital ...

GeneralWhy not static?
PIEBALDconsult
18:08 9 Jan '09  
Static classes in C# offer everything classic singletons do, and do it better.
GeneralRe: Why not static?
Zacky Pickholz
23:41 21 Apr '09  
That is just a matter of an implementation decision.
There are several ways to implement design patterns.

The main value of this code is not its pattern but the actual calculation engine.
GeneralRe: Why not static?
PIEBALDconsult
5:02 22 Apr '09  
Which is why I would choose static over classic singleton. Less code, and if you change your mind you have less code to remove.
GeneralHow do I reference this in VB.Net?
pmannino
0:52 9 Jan '09  
I've copied your code into my VB.Net project, but my main program cannot see the SunTimes class. C# is a foreign language to me. Smile
GeneralRe: How do I reference this in VB.Net?
Zacky Pickholz
23:43 21 Apr '09  
I don't have an answer for that, but surely someone more acquainted with VB will have an answer.

Perhaps you need to tweak my package/classes definitions and make them available to "outsiders".

Essentially it should be pretty straightforward to reuse my code from VB.
GeneralProblem getting sunrise and sunset to output.
newb2vb
6:05 4 Nov '08  
Zacky,

This code is very cool. I am fairly new to C# but not new to coding. I am having a problem with the code. I want to display the sunrise and sunset time for only the current day in my application. Therefore I commented out the for loop and the date change. Also, instead of showing the info in debug console, I want to show it on my form through two labels.

The problem I am having though is that when I run the code, the two labels show the current date and the time of 12:00:00 AM instead of showing sunrise and sunset. I know that I am initially issuing that date and time using the DateTime.Today when declaring the variables but I understood that it did not matter what you assigned to the variable because the code would change it when it runs through the class.

What am I missing?

Thanks!


private void button2_Click(object sender, EventArgs e)
{
DateTime date = DateTime.Now;
bool isSunrise = false;
bool isSunset = false;
DateTime sunrise = DateTime.Today;
DateTime sunset = DateTime.Today;

// Print out the Sunrise and Sunset times for the next 20 days
//for (int i=0; i<20; i++)

// Coordinates of Tel-Aviv
SunTimes.Instance.CalculateSunRiseSetTimes(new SunTimes.LatitudeCoords
(32, 4, 0, SunTimes.LatitudeCoords.Direction.North),
new SunTimes.LongitudeCoords
(34, 46, 0, SunTimes.LongitudeCoords.Direction.East),
date, ref sunrise, ref sunset,
ref isSunrise, ref isSunset);
label3.Text = sunrise.ToString();
label4.Text = sunset.ToString();


//Debug.Print(date + '': Sunrise @'' + sunrise.ToString('HH:mm') + ''
//Sunset @'' + sunset.ToString(''HH:mm''));

//date = date.AddDays(1); // Move to the next day
}
GeneralRe: Problem getting sunrise and sunset to output.
Medlan
6:52 4 Nov '08  
If you use a Console Application use Console.WriteLine("....")
If you have Windows Forms try MessageBox.Show("...")
Generalerror
harrifer
9:19 31 Oct '08  
I get this error when i try to use the class
'SunTimes' is inaccessible due to its protection level

How Can i solve this.
GeneralRe: error
rsam_london
16:19 31 Oct '08  
The class is a Singleton:http://en.wikipedia.org/wiki/Singleton_pattern[^]

You need to access it via "SunTimes.Instance" - just like the example.
rsam
GeneralProblem with rounding the UtcOffset
rsam_london
18:11 29 Oct '08  
Hi,
This bit of code rounds the UTC offset to the number of hours:
double zone = -(int)Math.Round(TimeZone.CurrentTimeZone.GetUtcOffset(date).TotalSeconds / 3600);


Unfortunately this doesn't work where the offset in hours isn't a integer, e.g. India is presently UTC-5.5. Removing the cast/round fixes the problem:
double zone = -TimeZone.CurrentTimeZone.GetUtcOffset(date).TotalSeconds / 3600;


Thanks, Smile
rsam
GeneralTwilight times?
acasia2
14:07 9 Oct '08  
Hi Great article. I've been looking into this myself. The PHP function date_sun_info gives 3 twilight times (astro, nautical and civil) - for definitions see http://www.nmm.ac.uk/explore/astronomy-and-time/time-facts/lighting-up-time[^]">
Unfortunately I'm not a PHP programmer (pure C#)
I wondered if you could help me implement those twilight times - Your code must calculate when the sun is at the horizon, I just need to figure out when it is 6/12/18 degrees below the horizon
GeneralRe: Twilight times?
Kenv
7:54 31 Oct '08  
Look at this line:

z = Math.Cos(90.833 * mDR); // refraction + sun semidiameter at horizon

in the TestHour method. Changing 90.833 to 96 should give you Civil twilight. You should be able to work out any other "twilights" you need.
GeneralRe: Twilight times?
Rafone
21:26 16 Mar '09  
Do you happen to know how to find these?

Duration of day
Sun in south at 12:36 PM at altitude 55° above horizon
Civil twilight
Nautical twilight
Astronomical twilight


tia
rafone

Statistics are like bikini's...
What they reveal is astonishing ...
But what they hide is vital ...

GeneralGreat code BUT ... need to fix ...
on_your_6
15:33 2 Oct '08  
need to fix code From:

DateTime date = DateTime.Today;
bool isSunrise = false;
bool isSunset = false;
DateTime sunrise = DateTime.Now;
DateTime sunset = DateTime.Now;


To:
DateTime date = DateTime.Now;
bool isSunrise = false;
bool isSunset = false;
DateTime sunrise = DateTime.Today;
DateTime sunset = DateTime.Today;


after this fix the code works great
GeneralRe: Great code BUT ... need to fix ...
Zacky Pickholz
2:17 7 Oct '08  
Thanks for the input on-your-6!

I believe your first line comment is correct (i.e. DateTime date = DateTime.Now), but the other two lines are irrelevant (these are output params, doesn't matter what value you hold in them initially).

In any case this is only a fix to the example usage, but the engine it working perfectly as far as I know.

Thanks again Laugh

Zacky.


Last Updated 13 Sep 2008 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010