trevnorris

SunriseSunset Fork

Mar 8th, 2011
452
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // SunriseSunset Class (2011-01-30)
  2. //   Implementation of http://williams.best.vwh.net/sunrise_sunset_algorithm.htm
  3. //
  4. //   Copyright (c) 2011, Preston Hunt <me@prestonhunt.com>
  5. //   All rights reserved.
  6. //
  7. //   Redistribution and use in source and binary forms, with or without
  8. //   modification, are permitted provided that the following conditions
  9. //   are met:
  10. //
  11. //   Redistributions of source code must retain the above copyright
  12. //   notice, this list of conditions and the following disclaimer.
  13. //   Redistributions in binary form must reproduce the above copyright
  14. //   notice, this list of conditions and the following disclaimer in the
  15. //   documentation and/or other materials provided with the
  16. //   distribution.
  17. //
  18. //   The name of Preston Hunt may not be used to endorse or promote
  19. //   products derived from this software without specific prior written
  20. //   permission.
  21. //
  22. //   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  23. //   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  24. //   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  25. //   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  26. //   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  27. //   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  28. //   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  29. //   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  30. //   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  31. //   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  32. //   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  33. //   OF THE POSSIBILITY OF SUCH DAMAGE.
  34. //
  35. //   Provides sunrise and sunset times for specified date and position.
  36. //   All dates are UTC.  Year is 4-digit.  Month is 1-12.  Day is 1-31.
  37. //   Longitude is positive for east, negative for west.
  38. //
  39. //   Sample usage:
  40. //   var tokyo = new SunriseSunset( 2011, 1, 19, 35+40/60, 139+45/60);
  41. //   tokyo.sunriseUtcHours()      --> 21.8199 = 21:49 GMT
  42. //   tokyo.sunsetUtcHours()    --> 7.9070  = 07:54 GMT
  43. //   tokyo.sunriseLocalHours(9)   --> 6.8199  = 06:49 at GMT+9
  44. //   tokyo.sunsunsetLocalHours(9) --> 16.9070 = 16:54 at GMT+9
  45. //   tokyo.isDaylight(1.5)      --> true
  46. //
  47. //   var losangeles = new SunriseSunset( 2011, 1, 19, 34.05, -118.233333333 );
  48. //   etc.
  49. (function(Math, window) {
  50.  
  51. var MPI = Math.PI;
  52.  
  53. function sin(deg) {
  54.     return Math.sin(deg * MPI / 180);
  55. };
  56. function cos(deg) {
  57.     return Math.cos(deg * MPI / 180);
  58. };
  59. function tan(deg) {
  60.     return Math.tan(deg * MPI / 180);
  61. };
  62. function asin(x) {
  63.     return (180 / MPI) * Math.asin(x);
  64. };
  65. function acos(x) {
  66.     return (180 / MPI) * Math.acos(x);
  67. };
  68. function atan(x) {
  69.     return (180 / MPI) * Math.atan(x);
  70. };
  71.  
  72.  
  73. var SunriseSunset = function(utcFullYear, utcMonth, utcDay, latitude, longitude) {
  74.     this.zenith = 90.83;
  75.     this.utcFullYear = utcFullYear;
  76.     this.utcMonth = utcMonth;
  77.     this.utcDay = utcDay;
  78.     this.latitude = latitude;
  79.     this.longitude = longitude;
  80.     this.lngHour = longitude / 15;
  81.     this.rising = true;
  82. };
  83.  
  84. SunriseSunset.prototype = {
  85.     getDOY: function() {
  86.         var ndate = new Date();
  87.         return Math.ceil((ndate - (new Date(ndate.getFullYear(), 0, 1))) / 86400000);
  88.     },
  89.  
  90.     approximateTime: function() {
  91.         return this.getDOY() + ((this.rising ? 6 : 18 - this.lngHour) / 24)
  92.     },
  93.  
  94.     meanAnomaly: function() {
  95.         return (0.9856 * this.approximateTime()) - 3.289;
  96.     },
  97.  
  98.     trueLongitude: function() {
  99.         var M = this.meanAnomaly();
  100.         return (M + (1.916 * sin(M)) + (0.020 * sin(2 * M)) + 282.634) % 360;
  101.     },
  102.  
  103.     rightAscension: function() {
  104.         var L = this.trueLongitude(),
  105.             RA = (atan(0.91764 * tan(L))) % 360,
  106.             Lquadrant  = (Math.floor( L/90)) * 90,
  107.             RAquadrant = (Math.floor(RA/90)) * 90;
  108.         return (RA + (Lquadrant - RAquadrant)) / 15;
  109.     },
  110.  
  111.     sinDec: function() {
  112.         return 0.39782 * sin(this.trueLongitude());
  113.     },
  114.  
  115.     cosDec: function() {
  116.         return cos(asin(this.sinDec()));
  117.     },
  118.  
  119.     localMeanTime: function() {
  120.         var cosH = (cos(this.zenith) - (this.sinDec() * sin(this.latitude))) / (this.cosDec() * cos(this.latitude)),
  121.             RA = this.rightAscension(),
  122.             t = this.approximateTime(),
  123.             H = (this.rising ? 360 - acos(cosH) : acos(cosH)) / 15,
  124.             T = H + RA - (0.06571 * t) - 6.622;
  125.         return (cosH > 1) ?
  126.                 "the sun never rises on this location (on the specified date)" : (cosH < -1) ?
  127.             "the sun never sets on this location (on the specified date)" : T;
  128.     },
  129.  
  130.     UTCTime: function() {
  131.         return (this.localMeanTime() - this.lngHour) % 24;
  132.     },
  133.  
  134.     sunriseUtcHours: function() {
  135.         this.rising = true;
  136.         return this.UTCTime();
  137.     },
  138.  
  139.     sunsetUtcHours: function() {
  140.         this.rising = false;
  141.         return this.UTCTime();
  142.     },
  143.  
  144.     hoursRange: function(h) {
  145.         return (h >= 24) ? (h - 24) : ((h < 0) ? (h + 24) : h);
  146.     },
  147.  
  148.     sunriseLocalHours: function(gmt) {
  149.         return this.hoursRange(gmt + this.sunriseUtcHours());
  150.     },
  151.  
  152.     sunsetLocalHours: function(gmt) {
  153.         return this.hoursRange(gmt + this.sunsetUtcHours());
  154.     },
  155.  
  156.     isDaylight: function( utcCurrentHours ) {
  157.         var sunriseHours = this.sunriseUtcHours(),
  158.             sunsetHours = this.sunsetUtcHours();
  159.         return (sunsetHours < sunriseHours) ?
  160.             (utcCurrentHours > sunriseHours || utcCurrentHours < sunsetHours) ?
  161.                 true : false : (utcCurrentHours >= sunriseHours) ?
  162.             (utcCurrentHours < sunsetHours) : false;
  163.     }
  164. };
  165.  
  166. window.SunriseSunset = SunriseSunset;
  167.  
  168. })(Math, this);
RAW Paste Data