Click here to Skip to main content
12,294,775 members (59,356 online)
Click here to Skip to main content

Stats

70.8K views
3.2K downloads
77 bookmarked
Posted

Solar Calculator - Calculate Sunrise, Sunset, and Maximum Solar Radiation

, 10 Jan 2011 CPOL
A C# assembly for calculating Sunrise, Sunset, and Maximum Solar Radiation
// AstronomyTest.cs - NUnit Test Cases for Astronomy
//
// Patrick Kalkman  pkalkie@gmail.cm
//
// (C) 2003 Patrick Kalkman http://www.semanticarchitecture.net
//
using System;
using NUnit.Framework;

namespace Astronomy
{
   /// <summary>
   /// Test for the Sun related calculations.
   /// The test values of the declination of the sun are 
   /// taken from http://www.wsanford.com/~wsanford/exo/sundials/DEC_Sun.html
   /// The test values for sunrise and sunset are taken from 
   /// http://home.hccnet.nl/v.d.horn/weersverwachting/zonsopkomst_zonsondergang.htm
   /// The test values for maximum solar radiation are taken from
   /// solrad.xls (Solar position and radiation calculator for Microsoft Excel/VBA By Greg Pelletier)
   /// </summary>
   [TestFixture]
   public class SunCalculatorTest
   {
      [Test]
      public void SunRiseTestNetherlands()
      {
         TestSunRise(new DateTime(2010, 4, 1), new DateTime(2010, 4, 1, 7, 15, 0), CreateSunCalculatorForUtrecht(true));
         TestSunRise(new DateTime(2010, 9, 1), new DateTime(2010, 9, 1, 6, 51, 0), CreateSunCalculatorForUtrecht(true));
         TestSunRise(new DateTime(2010, 1, 10), new DateTime(2010, 1, 10, 8, 45, 0), CreateSunCalculatorForUtrecht(false));
      }

      [Test]
      public void SunRiseTestLosAngeles()
      {
         TestSunRise(new DateTime(2010, 5, 28), new DateTime(2010, 5, 28, 5, 45, 0), CreateSunCalculatorForLosAngeles(true));
         TestSunRise(new DateTime(2011, 1, 7), new DateTime(2011, 1, 7, 7, 00, 0), CreateSunCalculatorForLosAngeles(false));
      }

      [Test]
      public void SunSetTestLosAngeles()
      {
         TestSunSet(new DateTime(2010, 5, 28), new DateTime(2010, 5, 28, 19, 57, 0), CreateSunCalculatorForLosAngeles(true));
         TestSunSet(new DateTime(2011, 1, 7), new DateTime(2011, 1, 7, 17, 00, 0), CreateSunCalculatorForLosAngeles(false));
      }

      [Test]
      public void SunSetTestNetherlands()
      {
         TestSunSet(new DateTime(2010, 4, 1), new DateTime(2010, 4, 1, 20, 13, 0), CreateSunCalculatorForUtrecht(true));
         TestSunSet(new DateTime(2010, 9, 1), new DateTime(2010, 9, 1, 20, 28, 0), CreateSunCalculatorForUtrecht(true));
         TestSunSet(new DateTime(2010, 1, 10), new DateTime(2010, 1, 10, 16, 50, 0), CreateSunCalculatorForUtrecht(false));
      }

      [Test]
      public void CalculateDeclinationOfTheSunTestNetherlands()
      {
         TestDeclinationOfTheSunCalculation(10, -22.05);
         TestDeclinationOfTheSunCalculation(40, -14.56);
         TestDeclinationOfTheSunCalculation(60, -8.03);
      }

      [Test]
      public void CalculateMaximumSolarRadiationTestNetherlands()
      {
         TestMaximumSolarRadiation(new DateTime(2010, 1, 24, 13, 0, 0), 261.62, false);
         TestMaximumSolarRadiation(new DateTime(2010, 1, 26, 16, 30, 0), 76.79, false);
         TestMaximumSolarRadiation(new DateTime(2010, 5, 1, 12, 0, 0), 717.65, true);
      }

      private static void TestMaximumSolarRadiation(DateTime dateTimeToCalculate, double expectedMaximumRadiation, bool useSummerTime)
      {
         //A difference of max 150 W/m2 is acceptable.
         SunCalculator sunCalculator = CreateSunCalculatorForUtrecht(useSummerTime);
         double maximumSolarRadiation = sunCalculator.CalculateMaximumSolarRadiation(dateTimeToCalculate);
         Assert.AreEqual(expectedMaximumRadiation, maximumSolarRadiation, 150);
      }

      private static void TestSunRise(DateTime sunRiseDateTime, DateTime expectedSunRiseDateTime, SunCalculator sunCalculator)
      {
         //A difference of max 15 minutes is acceptable.
         DateTime sunRise = sunCalculator.CalculateSunRise(sunRiseDateTime);
         TimeSpan difference = expectedSunRiseDateTime - sunRise;
         Assert.LessOrEqual(Math.Abs(difference.Minutes), 15);
      }

      private static void TestSunSet(DateTime sunSetDateTime, DateTime expectedSunSetDateTime, SunCalculator sunCalculator)
      {
         //A difference of max 15 minutes is acceptable.
         DateTime sunSet = sunCalculator.CalculateSunSet(sunSetDateTime);
         TimeSpan difference = expectedSunSetDateTime - sunSet;
         Assert.LessOrEqual(Math.Abs(difference.Minutes), 15);
      }

      private static void TestDeclinationOfTheSunCalculation(int dayNumber, double expectedValueInDegrees)
      {
         //A difference of 0.05 is acceptable.
         double expectedValueInRadians = expectedValueInDegrees * Math.PI / 180;
         SunCalculator sun = new SunCalculator();
         double calculatedDeclinationOfTheSun = sun.CalculateDeclination(dayNumber);
         Assert.AreEqual(expectedValueInRadians, calculatedDeclinationOfTheSun, 0.05);
      }

      private static SunCalculator CreateSunCalculatorForUtrecht(bool useSummerTime)
      {
         const Double LongituteUtrechtNetherlands = 5.127869;
         const Double LatitudeUtrechtNetherlands = 52.108192;
         return CreateSunCalculator(LongituteUtrechtNetherlands, LatitudeUtrechtNetherlands, 15, useSummerTime);
      }

      private static SunCalculator CreateSunCalculatorForLosAngeles(bool useSummerTime)
      {
         const Double LongituteLosAngeles = -118.243685;
         const Double LatitudeLosAngeles = 34.052234;

         return CreateSunCalculator(LongituteLosAngeles, LatitudeLosAngeles, -120, useSummerTime);
      }

      private static SunCalculator CreateSunCalculator(double longitude, double latitude, long longituteTimeZone, bool useSummerTime)
      {
         return new SunCalculator(longitude, latitude, longituteTimeZone, useSummerTime);
      }
   }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Patrick Kalkman
Architect http://www.simpletechture.nl
Netherlands Netherlands
Patrick Kalkman is a senior Software Architect with more than 20 years professional development experience. He works for SimpleTechture where he helps teams develop state of the art web applications.

Patrick enjoys writing his blog. It discusses agile software development. Patrick can be reached at patrick@simpletechture.nl.

Published Windows 8 apps:

Published Windows Phone apps:

Awards:

Best Mobile article of March 2012
Best Mobile article of June 2012

You may also be interested in...

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160525.2 | Last Updated 10 Jan 2011
Article Copyright 2010 by Patrick Kalkman
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid