-
-
Save ruiokada/b28076d4911820ddcbbc to your computer and use it in GitHub Desktop.
| /** | |
| * Calculates today's sunrise and sunset hours in local time (or in the given tz) for the given latitude, longitude. | |
| * The tz parameter is mainly for the possible circumstance that your system timezone does not match the location | |
| * you are currently at. | |
| * | |
| * Computations are based on the formulas found in: | |
| * https://en.wikipedia.org/wiki/Julian_day#Converting_Julian_or_Gregorian_calendar_date_to_Julian_Day_Number | |
| * https://en.wikipedia.org/wiki/Sunrise_equation#Complete_calculation_on_Earth | |
| * | |
| * @method suntimes | |
| * @param {Float} lat Latitude of location (South is negative) | |
| * @param {Float} lng Longitude of location (West is negative) | |
| * @param {Integer} tz Timezone hour offset. e.g. Pacific/Los Angeles Standard Time is -8 (Optional, defaults to system timezone) | |
| * @return {Array} Returns an array of length 2 with the sunrise and sunset times as floats on 24-hour time. | |
| * e.g. 6.5 is 6:30am, 23.2 is 11:12pm, 0.3 is 12:18am | |
| * Returns an array with [null, -1] if the sun never rises, and [-1, null] if the sun never sets. | |
| * | |
| * ### LICENSING ### | |
| * | |
| * This code contains information derived from Wikipedia content licensed under | |
| * the Creative Commons Attribution-ShareAlike License. As such, this code | |
| * is distributed under the GPLv3 license: | |
| * | |
| * This program is free software: you can redistribute it and/or modify | |
| * it under the terms of the GNU General Public License as published by | |
| * the Free Software Foundation, either version 3 of the License, or | |
| * (at your option) any later version. | |
| * | |
| * This program is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| * GNU General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU General Public License | |
| * along with this program. If not, see <https://www.gnu.org/licenses/>. | |
| */ | |
| function suntimes(lat, lng, tz) { | |
| var d = new Date(); | |
| var radians = Math.PI / 180.0; | |
| var degrees = 180.0 / Math.PI; | |
| var a = Math.floor((14 - (d.getMonth() + 1.0)) / 12) | |
| var y = d.getFullYear() + 4800 - a; | |
| var m = (d.getMonth() + 1) + 12 * a - 3; | |
| var j_day = d.getDate() + Math.floor((153 * m + 2)/5) + 365 * y + Math.floor(y/4) - Math.floor(y/100) + Math.floor(y/400) - 32045; | |
| var n_star = j_day - 2451545.0009 - lng / 360.0; | |
| var n = Math.floor(n_star + 0.5); | |
| var solar_noon = 2451545.0009 - lng / 360.0 + n; | |
| var M = 356.0470 + 0.9856002585 * n; | |
| var C = 1.9148 * Math.sin( M * radians ) + 0.02 * Math.sin( 2 * M * radians ) + 0.0003 * Math.sin( 3 * M * radians ); | |
| var L = ( M + 102.9372 + C + 180 ) % 360; | |
| var j_transit = solar_noon + 0.0053 * Math.sin( M * radians) - 0.0069 * Math.sin( 2 * L * radians ); | |
| var D = Math.asin( Math.sin( L * radians ) * Math.sin( 23.45 * radians ) ) * degrees; | |
| var cos_omega = ( Math.sin(-0.83 * radians) - Math.sin( lat * radians ) * Math.sin( D * radians ) ) / ( Math.cos( lat * radians ) * Math.cos( D * radians ) ); | |
| // sun never rises | |
| if( cos_omega > 1) | |
| return [null, -1]; | |
| // sun never sets | |
| if( cos_omega < -1 ) | |
| return [-1, null]; | |
| // get Julian dates of sunrise/sunset | |
| var omega = Math.acos( cos_omega ) * degrees; | |
| var j_set = j_transit + omega / 360.0; | |
| var j_rise = j_transit - omega / 360.0; | |
| /* | |
| * get sunrise and sunset times in UTC | |
| * Check section "Finding Julian date given Julian day number and time of | |
| * day" on wikipedia for where the extra "+ 12" comes from. | |
| */ | |
| var utc_time_set = 24 * (j_set - j_day) + 12; | |
| var utc_time_rise = 24 * (j_rise - j_day) + 12; | |
| var tz_offset = tz === undefined ? -1 * d.getTimezoneOffset() / 60 : tz; | |
| var local_rise = (utc_time_rise + tz_offset) % 24; | |
| var local_set = (utc_time_set + tz_offset) % 24; | |
| return [local_rise, local_set]; | |
| } |
I saw your docs on tz:
* @param {Integer} tz Timezone hour offset. e.g. Pacific/Los Angeles is -8 (Optional, defaults to system timezone)
And I'm in LA and when I give it -8 as a parameter it gives a different result. Seems to be because (new Date()).getTimezoneOffset()/60 is 7 and not -8. I'm guessing the 1hr difference is daylight savings and the negative vs positive is because we're UTC-8 but we're 8 (now 7) hours behind)
I saw your docs on
tz:
* @param {Integer} tz Timezone hour offset. e.g. Pacific/Los Angeles is -8 (Optional, defaults to system timezone)And I'm in LA and when I give it
-8as a parameter it gives a different result. Seems to be because(new Date()).getTimezoneOffset()/60is 7 and not -8. I'm guessing the 1hr difference is daylight savings and the negative vs positive is because we're UTC-8 but we're 8 (now 7) hours behind)
Thanks for mentioning this. I have specified that -8 is PST in the docs.
@PHDPeter Good question, I can answer it only partially. I forgot to specify that the output gives the decimal "hour of the day" of the sunrise and sunset times (i.e. a decimal number between 0 and 24). For example, 6.5 is 6:30am, 23.2 is 11:12pm, and 0.3 is 12:18am. Getting the hour is the floor of this decimal number and the minute is
((decimal hour) - floor(decimal hour)) * 60. So something like this:Then you can do what you need with that information.