Enjoy an ad free experience by logging in. Not a member yet? Register.

Results 1 to 15 of 15

06262012, 06:37 AM #1
 Join Date
 May 2012
 Posts
 9
 Thanks
 2
 Thanked 0 Times in 0 Posts
Sunrise and sunset according to longitude and latitude
Code:<html> <head> <title>Sunrise and sunset</title> <script type="text/javascript"> function sunupdown(longitude, ew, latitude, ns, localoffset){ var d = new Date(); var dyear = d.getUTCFullYear(); var dmonth = d.getUTCMonth(); var dday = d.getUTCday(); var zenith = 90.83; var lnghour = longitude / 15; var n1, n2, n3, n, t1, t2, m1, m2, l1, l2, ra1, ra2, lquadrant1, lquadrant2, raquadrant1, raquadrant2; var sindec1, sindec2, cosdec1, cosdec2, cosh1, cosh2, h1, h2, T1, T2, UT1, UT2, localT1, localT2; var output = " ", output1 = " ", output2 = " "; // Set coords as negative if West or South. if(ew == 'w'  ew == 'W'){longitude = (2*longitude);} if(ns == 's'  ew == 'S'){latitude = (2*latitude);} // Calculate the day of the year. n1 = Math.floor(275 * dmonth / 9); n2 = Math.floor((dmonth + 9) / 12); n3 = (1 + Math.floor((dyear  4 * Math.floor(dyear / 4) + 2) / 3)); n = n1  (n2 * n3) + dday  30; // Get sunrise and sunset times. t1 = n + ((6  lnghour) / 24); t2 = n + ((18  lnghour) / 24); // Sun's mean anomaly. m1 = (0.9856 * t1)  3.289; m2 = (0.9856 * t2)  3.289; // Sun's true longitude. l1 = m1 + (1.916 * Math.sin(m1)) + (0.020 * Math.sin(2 * m1)) + 282.634; if(l1 < 0){l1 += 360;} if(l1 > 360){l1 = 360;} l2 = m2 + (1.916 * Math.sin(m2)) + (0.020 * Math.sin(2 * m2)) + 282.634; if(l2 < 0){l2 += 360;} if(l2 > 360){l2 = 360;} // Sun's right ascension. ra1 = Math.atan(0.91764 * Math.tan(l1)); if(ra1 < 0){ra1 += 360;} if(ra1 > 360){ra1 = 360;} ra2 = Math.atan(0.91764 * Math.tan(l2)); if(ra2 < 0){ra2 += 360;} if(ra2 > 360){ra2 = 360;} // Sun's quadrant. lquadrant1 = (Math.floor(l1/90)) * 90; raquadrant1 = (Math.floor(ra1/90)) * 90; ra1 = ra1 + (lquadrant1  raquadrant1); lquadrant2 = (Math.floor(l2/90)) * 90; raquadrant2 = (Math.floor(ra2/90)) * 90; ra2 = ra2 + (lquadrant2  raquadrant2); // Convert right ascension into hours. ra1 = ra1 / 15; ra2 = ra2 / 15; // Get sun's declination. sindec1 = 0.39782 * Math.sin(l1); sindec2 = 0.39782 * Math.sin(l2); cosdec1 = Math.cos(Math.asin(sindec1)); cosdec2 = Math.cos(Math.asin(sindec2)); // Sun's local hour angle. cosh1 = (Math.cos(zenith)  (sindec1 * Math.sin(latitude))) / (cosdec1 * Math.cos(latitude)); cosh2 = (Math.cos(zenith)  (sindec2 * Math.sin(latitude))) / (cosdec2 * Math.cos(latitude)); if(cosh1 > 1){output1 = "No sunrise.";} if(cosh2 < 1){output2 = "No sunset.";} // Get hour. h1 = 360  Math.acos(cosh1); h2 = Math.acos(cosh2); h1 = h1 / 15; h2 = h2 / 15; // Local mean time for rise and set. T1 = ra1  (0.06571 * t1)  6.622; T2 = ra2  (0.06571 * t2)  6.622; // Adjust back to UTC. UT1 = T1  lnghour; if(UT1 < 0){UT1 += 24;} if(UT1 > 24){UT1 = 24;} UT2 = T2  lnghour; if(UT2 < 0){UT2 += 24;} if(UT2 > 24){UT2 = 24;} // Convert UTC value to local based on longitude and latitude. localT1 = UT1 + localoffset; localT2 = UT2 + localoffset; // Output sunrise and sunset times as a string. if(output1 != " "){localT1 = output1;} if(output2 != " "){localT2 = output2;} document.write("<p>Sunrise: "+localT1+"<br>Sunset: "+localT2+"</p>"); } </script> </head> <body> <h1>Sunrise and sunset at location X.</h1> <script type="text/javascript">sunupdown(50, 'e', 50, 's', 5);</script> </body> </html>
Basically it's not working yet, and I'd appreicate any help. There's no output, and I'm not sure why. @_@
06262012, 08:28 AM
#2
 Join Date
 Jun 2002
 Location
 London, England
 Posts
 18,371
 Thanks
 204
 Thanked 2,573 Times in 2,551 Posts
Syntax error:
var dday = d.getUTCDay(); // must be capital D in Day
I think that there must be an error in the calculations as I get the improbable results
Sunrise: 11.026954690764316
Sunset: No sunset.
All advice is supplied packaged by intellectual weight, and not by volume. Contents may settle slightly in transit.
Last edited by Philip M; 06262012 at 08:31 AM.
All the code given in this post has been tested and is intended to address the question asked.
Unless stated otherwise it is not just a demonstration.
Users who have thanked Philip M for this post:
OxygenThief (06272012)
06272012, 04:01 AM
#3
 Join Date
 May 2012
 Posts
 9
 Thanks
 2
 Thanked 0 Times in 0 Posts
Ah, thanks.
As for the numbers, I believe I have to sort out the conversions between decimal and DMS. That may be the issue now.
07062012, 08:00 PM
#4
 Join Date
 Jul 2012
 Posts
 7
 Thanks
 0
 Thanked 0 Times in 0 Posts
I have this code working.
I found a couple of errors...
'var dday = d.getUTCday();' should be 'var dday = d.getUTCDay();'
'if(ns == 's'  ew == 'S'){latitude = (2*latitude);}' should be 'if(ns == 's'  ns == 'S'){latitude = (2*latitude);}'
I have actually used the form 'if(ns == 's'  ns == 'S'){latitude *= 1;}' for both longitude and latitude negations.
The algorithm uses degrees throughout, but the trig functions in javascript run in 'radians mode'. This is warned about in the heading at
http://williams.best.vwh.net/sunrise..._algorithm.htm
Here are the edits needed for the sunrise bits which converts degrees to radians and viceversa. Use them as a template for the sunset bits (l2, ra2, etc..)...
l1 = m1 + (1.916 * Math.sin((Math.PI/180)*m1)) + (0.020 * Math.sin((Math.PI/180)*2 * m1)) + 282.634;
ra1 = (180/Math.PI)*Math.atan(0.91764 * Math.tan((Math.PI/180)*l1));
sindec1 = 0.39782 * Math.sin((Math.PI/180)*l1);
cosh1 = (Math.cos((Math.PI/180)*zenith)  (sindec1 * Math.sin((Math.PI/180)*latitude))) / (cosdec1 * Math.cos((Math.PI/180)*latitude));
h1 = 360  (180/Math.PI)*Math.acos(cosh1);
I think that is all of them. If not you should be able to work out any I have missed.
Note that this expression does NOT require editing...
cosdec1 = Math.cos(Math.asin(sindec1));
because 'sindec1' is not in degrees and Math.asin() returns radians into Math.cos() which returns 'cosdec1' which is not in degrees. Clear ?  :)
Note also that localT1 and localT2 have to be checked and corrected for underflow (<0) and overflow (>24).
Thanks for the reference and code.
07062012, 09:04 PM
#5
 Join Date
 Jun 2002
 Location
 London, England
 Posts
 18,371
 Thanks
 204
 Thanked 2,573 Times in 2,551 Posts
Why not post your complete code for others to enjoy and learn from?
All the code given in this post has been tested and is intended to address the question asked.
Unless stated otherwise it is not just a demonstration.
07072012, 12:09 AM
#6
 Join Date
 Jul 2012
 Posts
 7
 Thanks
 0
 Thanked 0 Times in 0 Posts
Well  it is basically just OxygenThief's code with the edits as given  not really my code.
I could post it if wanted...
07072012, 12:37 AM
#7
 Join Date
 Jul 2012
 Posts
 7
 Thanks
 0
 Thanked 0 Times in 0 Posts
Here goes... I am a newbie to the forum so I hope I don't break something...
Works for me...Code:function sunriseSunset(longitude, ew, latitude, ns, localoffset) { var d = new Date(); var dyear = d.getUTCFullYear(); var dmonth = d.getUTCMonth() + 1; var dday = d.getUTCDate(); var zenith = 90.83; var lnghour = longitude / 15.0; var n1, n2, n3, n, t1, t2, m1, m2, l1, l2, ra1, ra2, lquadrant1, lquadrant2, raquadrant1, raquadrant2; var sindec1, sindec2, cosdec1, cosdec2, cosh1, cosh2, h1, h2, T1, T2, UT1, UT2, localT1, localT2; var output = " ", output1 = " ", output2 = " "; // Set coords as negative if West or South. if(ew == 'w'  ew == 'W'){longitude *= 1;} if(ns == 's'  ns == 'S'){latitude *= 1;} // Calculate the day of the year. n1 = Math.floor(275 * dmonth / 9); n2 = Math.floor((dmonth + 9) / 12); n3 = (1 + Math.floor((dyear  4 * Math.floor(dyear / 4) + 2) / 3)); n = n1  (n2 * n3) + dday  30; // Get sunrise and sunset times. t1 = n + ((6  lnghour) / 24); t2 = n + ((18  lnghour) / 24); // Sun's mean anomaly. m1 = (0.9856 * t1)  3.289; m2 = (0.9856 * t2)  3.289; // Sun's true longitude. l1 = m1 + (1.916 * Math.sin((Math.PI/180)*m1)) + (0.020 * Math.sin((Math.PI/180)*2 * m1)) + 282.634; if(l1 < 0){l1 += 360;} if(l1 > 360){l1 = 360;} l2 = m2 + (1.916 * Math.sin((Math.PI/180)*m2)) + (0.020 * Math.sin(2 * (Math.PI/180)*m2)) + 282.634; if(l2 < 0){l2 += 360;} if(l2 > 360){l2 = 360;} // Sun's right ascension. ra1 = (180/Math.PI)*Math.atan(0.91764 * Math.tan((Math.PI/180)*l1)); if(ra1 < 0){ra1 += 360;} if(ra1 > 360){ra1 = 360;} ra2 = (180/Math.PI)*Math.atan(0.91764 * Math.tan((Math.PI/180)*l2)); if(ra2 < 0){ra2 += 360;} if(ra2 > 360){ra2 = 360;} // Sun's quadrant. lquadrant1 = (Math.floor(l1/90)) * 90; raquadrant1 = (Math.floor(ra1/90)) * 90; ra1 = ra1 + (lquadrant1  raquadrant1); lquadrant2 = (Math.floor(l2/90)) * 90; raquadrant2 = (Math.floor(ra2/90)) * 90; ra2 = ra2 + (lquadrant2  raquadrant2); // Convert right ascension into hours. ra1 = ra1 / 15.0; ra2 = ra2 / 15.0; // Get sun's declination. sindec1 = 0.39782 * Math.sin((Math.PI/180)*l1); sindec2 = 0.39782 * Math.sin((Math.PI/180)*l2); cosdec1 = Math.cos(Math.asin(sindec1)); cosdec2 = Math.cos(Math.asin(sindec2)); // Sun's local hour angle. cosh1 = (Math.cos((Math.PI/180)*zenith)  (sindec1 * Math.sin((Math.PI/180)*latitude))) / (cosdec1 * Math.cos((Math.PI/180)*latitude)); cosh2 = (Math.cos((Math.PI/180)*zenith)  (sindec2 * Math.sin((Math.PI/180)*latitude))) / (cosdec2 * Math.cos((Math.PI/180)*latitude)); if(cosh1 > 1){output1 = "No sunrise.";} if(cosh2 < 1){output2 = "No sunset.";} // Get hour. h1 = 360  (180/Math.PI)*Math.acos(cosh1); h2 = (180/Math.PI)*Math.acos(cosh2); h1 = h1 / 15; h2 = h2 / 15; // Local mean time for rise and set. T1 = h1 + ra1  (0.06571 * t1)  6.622; T2 = h2 + ra2  (0.06571 * t2)  6.622; // Adjust back to UTC. UT1 = T1  lnghour; if(UT1 < 0){UT1 += 24;} if(UT1 > 24){UT1 = 24;} UT2 = T2  lnghour; if(UT2 < 0){UT2 += 24;} if(UT2 > 24){UT2 = 24;} // Convert UTC value to local based on longitude and latitude. localT1 = UT1 + localoffset; localT1 = (localT1 > 24) ? localT124:localT1; localT1 = (localT1 < 0) ? localT1+24:localT1; localT2 = UT2 + localoffset; localT2 = (localT2 > 24) ? localT224:localT2; localT2 = (localT2 < 0) ? localT2+24:localT2; // Output sunrise and sunset times as a string. if(output1 != " "){localT1 = output1;} if(output2 != " "){localT2 = output2;} // Correct underflow/overflow and convert to 12 hour  am/pm format var localT1Hour = Math.floor(localT1); var localT1Minute = Math.floor((localT1  localT1Hour)*60); localT1Minute = (localT1Minute < 10) ? "0" + localT1Minute: localT1Minute; localT1Minute = (localT1Hour < 12) ? localT1Minute + " AM":localT1Minute + " PM"; localT1Hour = (localT1Hour > 12) ? localT1Hour  12: localT1Hour; var localT2Hour = Math.floor(localT2); var localT2Minute = Math.floor((localT2  localT2Hour)*60); localT2Minute = (localT2Minute < 10) ? "0" + localT2Minute: localT2Minute; localT2Minute = (localT2Hour < 12) ? localT2Minute + " AM":localT2Minute + " PM"; localT2Hour = (localT2Hour > 12) ? localT2Hour  12: localT2Hour; document.getElementById('sunrise').innerHTML = "*** Night time hours here are currently from " +localT2Hour+':'+localT2Minute+ " in the evening to "+localT1Hour+':'+localT1Minute + " the<br/>next morning <i><b>  my local time<\/b><\/i>, so you will only see a black photo during those hours..."; }
BTW  forgot to mention in the previous post.... getUTCMonth() is zerobased  so the algorithmn need it to be incremented before use...
Also note the use of 'getUTCDay()' is incorrect  that returns from 06, use getUTCDate() instead which returns the correct 131 values (I only found this after I saw the days were getting shorter lately, when they should be getting longer)...
Last edited by vk2xv; 07082012 at 11:33 PM. Reason: getUTCMonth() is zerobased issue and the correction from 'getUTCDay()' to 'getUTCDate()'...
07092012, 02:17 AM
#8
 Join Date
 Jul 2012
 Posts
 7
 Thanks
 0
 Thanked 0 Times in 0 Posts
Just found another error  the calculation of 'lnghour' should be done AFTER the adjustment of sign for E/W. Not a problem for me as I am East of GM, but would have been an error for those West of GM.
Change code from this...
to this...Code:..... var lnghour = longitude / 15.0; var n1, n2, n3, n, t1, t2, m1, m2, l1, l2, ra1, ra2, lquadrant1, lquadrant2, raquadrant1, raquadrant2; var sindec1, sindec2, cosdec1, cosdec2, cosh1, cosh2, h1, h2, T1, T2, UT1, UT2, localT1, localT2; var output = " ", output1 = " ", output2 = " "; // Set coords as negative if West or South. if(ew == 'w'  ew == 'W'){longitude *= 1;} if(ns == 's'  ns == 'S'){latitude *= 1;} .....
Code:..... var lnghour; var n1, n2, n3, n, t1, t2, m1, m2, l1, l2, ra1, ra2, lquadrant1, lquadrant2, raquadrant1, raquadrant2; var sindec1, sindec2, cosdec1, cosdec2, cosh1, cosh2, h1, h2, T1, T2, UT1, UT2, localT1, localT2; var output = " ", output1 = " ", output2 = " "; // Set coords as negative if West or South. if(ew == 'w'  ew == 'W'){longitude *= 1;} if(ns == 's'  ns == 'S'){latitude *= 1;} lnghour = longitude / 15.0; ....
07092012, 08:55 AM
#9
 Join Date
 Jun 2002
 Location
 London, England
 Posts
 18,371
 Thanks
 204
 Thanked 2,573 Times in 2,551 Posts
I don't think it is working properly!
*** Night time hours here are currently from 1:16 AM in the evening to 8:57 AM the nnext morning  my local time, so you will only see a black photo during those hours...
I entered 0.5610° W, 51.3162° N
All the code given in this post has been tested and is intended to address the question asked.
Unless stated otherwise it is not just a demonstration.
07092012, 09:40 AM
#10
 Join Date
 Jul 2012
 Posts
 7
 Thanks
 0
 Thanked 0 Times in 0 Posts
07092012, 09:46 AM
#11
 Join Date
 Jun 2002
 Location
 London, England
 Posts
 18,371
 Thanks
 204
 Thanked 2,573 Times in 2,551 Posts
I must have made a wrong entry!
But my result is slightly different:
sunriseSunset(.56, 'w', 51.3, 'n', 0);
*** Night time hours here are currently from 8:16 PM in the evening to 3:57 AM the next morning  my local time, so you will only see a black photo during those hours...
Is that because it is a different day here in UK compared to the antipodes? But the times are UTC dates/times.
Yes, you are right! I entered the coordinates for my office in Woking. Google Maps is a wonderful thing!
Last edited by Philip M; 07092012 at 11:32 AM.
All the code given in this post has been tested and is intended to address the question asked.
Unless stated otherwise it is not just a demonstration.
07092012, 10:13 AM
#12
 Join Date
 Jul 2012
 Posts
 7
 Thanks
 0
 Thanked 0 Times in 0 Posts
I changed to sunriseSunset(.56, 'w', 51.3, 'n', 0); [had entered .5 for long before]
and it returned 8:17PM and 3:57AM this time.
I am not sure of why the original code used the UTC variations of getXXXX(). The page which contains the algorithm seems to indicate local time/dates.
I changed the code to this...
and it still returned 8:17PM and 3:57AM. What do you get when you use the above code ?Code:var d = new Date(); var dyear = d.getFullYear(); var dmonth = d.getMonth() + 1; var dday = d.getDate();
07092012, 10:17 AM
#13
 Join Date
 Jun 2002
 Location
 London, England
 Posts
 18,371
 Thanks
 204
 Thanked 2,573 Times in 2,551 Posts
Night time hours here are currently from 8:16 PM in the evening to 3:57 Could it be maths differences between browsers? I am using IE9, but same result in Chrome.
Your calculations are in UTC and take no account of DST. Local times of sunrise/sunset for London on 9 Jul 2012 04:55 and 21:16
Last edited by Philip M; 07092012 at 10:30 AM.
All the code given in this post has been tested and is intended to address the question asked.
Unless stated otherwise it is not just a demonstration.
07092012, 11:07 AM
#14
 Join Date
 Jul 2012
 Posts
 7
 Thanks
 0
 Thanked 0 Times in 0 Posts
The day number is 191.
http://www.calendardate.com/todays.htm
the leap year is taken into account here...
I know some calculations say 192 (your script returns 191 on a pencil and paper walkthru. ??? i.e., 31+29+30+31+30+31+9 = 191), but I will stick with the astronomical version which I have also handcalculated as 191.Code:n3 = (1 + Math.floor((dyear  4 * Math.floor(dyear / 4) + 2) / 3));
BTW  it is probably a good time to reiterate I am only trying to get someone else's coding of yet another person's algorithm going. So it their code/algorithm which doesn't take into account DST. And I have changed the original code to not use UTC.
I leave it up to the reader to fathom out how to code in DST  I assumed that you would do that manually by putting in the right offset (for here it would be 10 for no DST and 11 for DST).
BTW  the small discrepancy in times (1 minute) is due to a local geographic correction in my code I need to make here to account for mountains....
When I take that out and apply manual DST correction (+1) it returns 9:16PM and 4:57AM.
So all's well....
Last edited by vk2xv; 07092012 at 11:41 AM. Reason: Accounting for 1 minute difference...
07092012, 11:40 AM
#15
 Join Date
 Jun 2002
 Location
 London, England
 Posts
 18,371
 Thanks
 204
 Thanked 2,573 Times in 2,551 Posts
You are right  the day number is indeed 191.
sunriseSunset(.56, 'w', 51.3, 'n', 1);
results in
Night time hours here are currently from 9:16 PM UTC in the evening to 4:57 AM UTC
Just to complete the topic, here is a script to identify whether DST is used and in operation in a location:
Code:<html> <head> <script type = "text/javascript"> var now =new Date(); // today var yr = now.getFullYear(); var DSTused = false; var jan = new Date(yr,0,1); // 1st January var janoff = jan.getTimezoneOffset(); var jul = new Date(yr,6,1); // 1st July var juloff = jul.getTimezoneOffset(); //alert ("January " + janoff + " July " + juloff); // for testing if (janoff != juloff) { DSTused = true; alert ("This country uses DST"); } else { alert ("This country does NOT use DST"); } if (DSTused) { var maxval = Math.max(janoff, juloff); // Note that JavaScript returns the offset in minutes and reverses the sign (so for example time zone +10 will return an offset of 600). var ntzo = now.getTimezoneOffset(); //alert (ntzo + " "+ maxval); // for testing if (ntzo != maxval) { alert ("DST is in operation on this day") } else { alert ("The country uses DST but DST is NOT in operation on this day"); } } </script> </body> </html>
Last edited by Philip M; 07092012 at 11:43 AM.
All the code given in this post has been tested and is intended to address the question asked.
Unless stated otherwise it is not just a demonstration.