 |
|
 |
some hint:
TimeZone timeZone = TimeZone.CurrentTimeZone; // get current tz
double latitude = SunTime.DegreesToAngle(48, 4, 24); // donetsk ua
double longitude = SunTime.DegreesToAngle(37, 44, 22); // donetsk ua
//UtcOffset calculate by tz
SunTime suntime = new SunTime(latitude, longitude, timeZone.GetUtcOffset(date).Hours, timeZone.GetDaylightChanges(date.Year), date);
|
|
|
|
 |
|
 |
Excellent work and nicely done.
One correction though, and I can't believe I'm the 1st person to see this in the 2.5 years since you've posted this...
The "official zenith" is 90 degrees, 50 arcminutes.
Thus, line 25 of SunTime.cs should read:
Official = 90833;
instead of:
Official = 90500;
Cheers!
|
|
|
|
 |
|
 |
Thank you for the remark!
It has been fixed and will be uploaded by the CodeProject editors in a couple of days I suppose.
|
|
|
|
 |
|
 |
Thank you for the clear and easy-to-use code !
|
|
|
|
 |
|
 |
Where can i find UTC Offset values for different places
|
|
|
|
 |
|
|
 |
|
 |
Looks like this does not handle latitudes above 67 degrees. At 68 degrees, the calculations yield an intermediate NaN that is not handled, and the resulting value is garbage. I've not looked at it long enough to figure out the problem, and may not, but wanted to provide the information.
Also consider what happens when at extreme latitudes where the sun may not rise (or set) for days at a time.
The NOAA algorithm seems to handle this, so I my just implement that...
|
|
|
|
 |
|
 |
Just for reference, this is an repro example of a call that will result in the problem described.
SunTime suntime = new SunTime(
SunTime.DegreesToAngle( 68, 0, 0 ),
SunTime.DegreesToAngle( -112, 8, 54 ),
-7,
daylightChanges,
date );
modified on Monday, June 22, 2009 3:21 PM
|
|
|
|
 |
|
 |
Hello
I neeed to program this function in a ATMEGA32 for outside light control
X893: how much size is the code? Is not it less if we programmed with tables instead of mathematical functions?
Regards
|
|
|
|
 |
|
 |
I don't think the code will be that big. The problem is that you'll need to include a floating point library...
Other options are f.e.:
1. define yourself a 16.16 fixed point number, translate all the math to fixed point math and use CORDIC math to calculate sin / cos / tan, etc...
2. when you're at a fixed location, you can use a desktop application to calculate sunset and sunrise time for a number of days in the year. Convert the times to minutes and create a lookup table. Then use interpolation to find the correct sunrise/sunset time for a given date. See C code example below:
/* Generated with the "Suntime table generator" program */
#define SUN_TABLE_SIZE 92
#define SUN_TABLE_DIV 4
static const unsigned int SunsetTable[] = { 1006, 1010, 1015, 1021, 1027, 1033, 1040, 1047, 1054, 1061, 1068, 1076, 1083, 1090, 1097, 1104, 1110, 1117, 1124, 1131, 1137, 1144, 1150, 1157, 1163, 1170, 1176, 1183, 1189, 1195, 1202, 1208, 1214, 1220, 1226, 1231, 1237, 1241, 1246, 1250, 1253, 1255, 1257, 1258, 1258, 1258, 1257, 1254, 1252, 1248, 1244, 1239, 1233, 1227, 1221, 1214, 1206, 1199, 1191, 1183, 1174, 1165, 1157, 1148, 1139, 1130, 1121, 1112, 1103, 1094, 1085, 1076, 1068, 1060, 1052, 1044, 1037, 1030, 1023, 1017, 1012, 1007, 1003, 1000, 997, 996, 995, 995, 996, 998, 1001, 1004};
static const unsigned int SunriseTable[] = { 529, 528, 526, 524, 521, 517, 512, 507, 501, 495, 488, 481, 473, 465, 457, 449, 440, 432, 423, 414, 405, 396, 387, 378, 369, 361, 352, 344, 336, 328, 320, 313, 307, 300, 295, 289, 285, 281, 278, 275, 273, 272, 272, 273, 274, 276, 279, 282, 286, 290, 295, 300, 306, 312, 317, 323, 329, 336, 342, 348, 354, 360, 366, 372, 379, 385, 391, 397, 404, 410, 416, 423, 430, 436, 443, 450, 457, 464, 471, 477, 484, 491, 497, 503, 509, 514, 518, 522, 525, 527, 528, 529};
/* Determine if the given 4 number year is a leap year (true) or not (false) */
unsigned char SunIsLeapYear(unsigned int Year)
{
return (((Year % 4 == 0) && (Year % 100 != 0)) || (Year % 400 == 0));
}
/* Returns the day of the year (1 - 366) for a given date */
unsigned int SunGetDayOfYear(unsigned char Day, unsigned char Month, unsigned int Year)
{
unsigned int Doy = (275 * (unsigned int)Month) / 9;
Doy -= (unsigned int)((Month + 9) / 12);
if (!SunIsLeapYear(Year))
Doy -= (unsigned int)((Month + 9) / 12);
return Doy + (unsigned int)Day - 30;
}
unsigned int SunGetTime(unsigned char day, unsigned char month, unsigned int year, unsigned char rising)
{
unsigned int a, b, t1, t2;
a = b = SunGetDayOfYear(day, month, year);
a /= SUN_TABLE_DIV; /* Lookup table index */
b %= SUN_TABLE_DIV; /* Interpolation index */
if (a >= SUN_TABLE_SIZE)
a = SUN_TABLE_SIZE - 1;
/* Get two points t1 & t2 so we can interpolate between these two */
if (rising)
{
t1 = SunriseTable[a];
a++;
if (a < SUN_TABLE_SIZE)
t2 = SunriseTable[a];
else
t2 = SunriseTable[0];
}
else
{
t1 = SunsetTable[a];
a++;
if (a < SUN_TABLE_SIZE)
t2 = SunsetTable[a];
else
t2 = SunsetTable[0];
}
/* Linear interpolation */
t2 *= b;
t1 *= (SUN_TABLE_DIV - b);
t1 += t2;
t1 /= SUN_TABLE_DIV;
return t1;
}
|
|
|
|
 |
|
 |
Thanx, great article.
I did't catch all algorithm yet but is it possible to use it
to get position of the Sun during the day?
I mean, we can find when it reach position of sunset or sunrise so I hope
it should be possible to get position (angle) for given time?
Any hint on how would be great
Thank you
Viliam
viliam
|
|
|
|
 |
|
 |
Hi Viliam,
Thanks, you're probably looking for this.
Right-click on the page and view the page source, the javascript code they use to calculate the solar position is out there.
Regards,
Wouter
|
|
|
|
 |
|
 |
Thanx, it looks good
viliam
|
|
|
|
 |
|
 |
A 5 from me.
A question though. utcOffset is int. Is it the difference between GMT time and local time? For many countries it's not an integer or maybe I'm missing something here?
"In the end it's a little boy expressing himself." Yanni
modified on Tuesday, March 3, 2009 6:07 AM
|
|
|
|
 |
|
 |
You're right. The utcOffset should be changed to a double, together with its property.
Thanks for your comment.
|
|
|
|
 |
|
 |
i implement this algoritm on ATMega32 microprocessor. As part of GPS tracker device.
Thanks
|
|
|
|
 |
|
 |
nice hobbyist project but next time, provide some gui and do not force me to edit parameters in source if this could be done by doing some smart things with my culture/IP/windows language settings.....
Adrian Pasik
|
|
|
|
 |
|
 |
This class is part of a larger project that I can't post here. I just want to share this class to let other ppl save some time.
modified on Saturday, February 28, 2009 9:08 AM
|
|
|
|
 |
|