根据地理坐标计算白天时数

9

我希望根据给定的纬度、经度和日期时间计算日光小时数。也就是说,根据地理坐标,在特定日期计算日出时间和日落时间。


这个问题在StackOverflow上有许多语言的解决方案。难道没有一个适合你吗? - Jonas Elfström
在右上角的搜索框中搜索计算日出时间。 - Jonas Elfström
4个回答

19

请查看纬度、经度和日照时数

   D = daylength
   L = latitude
   J = day of the year

   P = asin[.39795*cos(.2163108 + 2*atan{.9671396*tan[.00860(J-186)]})]

                          _                                         _
                         / sin(0.8333*pi/180) + sin(L*pi/180)*sin(P) \
   D = 24 - (24/pi)*acos{  -----------------------------------------  }
                         \_          cos(L*pi/180)*cos(P)           _/

3
好的,但是对我来说感觉像代数曲面。所有这些三角反三角运算所隐藏的方程式是什么? - Joshua P. Swanson

7

这里是一个Python函数,它通过纬度和一年中的日期(1到356之间的数字)作为参数返回白天小时数:

import math
def Daylight(latitude,day):
P = math.asin(0.39795 * math.cos(0.2163108 + 2 * math.atan(0.9671396 * math.tan(.00860 * (day - 186)))))
pi = math.pi
daylightamount = 24 - (24 / pi) * math.acos(
    (math.sin((0.8333 * pi / 180) + math.sin(latitude * pi / 180) * math.sin(P)) / (math.cos(latitude * pi / 180) * math.cos(P))))
return daylightamount

1
我对这个函数(尤其是daylightamount部分)进行了一些编辑,根据Forsythe, William C.等人的论文《A model comparison for daylength as a function of latitude and day of year》中的建议,修复了括号方面的小错误。daylightamount = 24 - (24 / pi) * math.acos((math.sin(0.8333 * pi / 180) + math.sin(latitude * pi / 180) * math.sin(P)) / (math.cos(latitude * pi / 180) * math.cos(P))) - ooozooo

0

我刚回答了另一个问题,认为我的解决方案也适用于这里。这是一个JavaScript解决方案,所以如果需要,您应该能够轻松转换到其他语言。

我在GitHub Sundial下创建了一个存储库,它在许可的修改BSD许可下授权,因此您可以自由地在自己的项目中使用它。

它应该准确到0.0001分钟,并考虑了地球的轴倾角时间方程

Sundial AMD可加载的太阳日光计算器

/*  Credit and References */
// http://lexikon.astronomie.info/zeitgleichung/   EOT 
// http://articles.adsabs.harvard.edu/cgi-bin/nph-iarticle_query?bibcode=1989MNRAS.238.1529H&db_key=AST&page_ind=2&plate_select=NO&data_type=GIF&type=SCREEN_GIF&classic=YES
// http://code.google.com/p/eesim/source/browse/trunk/EnergySim/src/sim/_environment.py?spec=svn6&r=6
// http://mathforum.org/library/drmath/view/56478.html 
// http://www.jgiesen.de/elevaz/basics/meeus.htm
// http://www.ehow.com/how_8495097_calculate-sunrise-latitude.html
// http://www.jgiesen.de/javascript/Beispiele/TN_Applet/DayNight125d.java
// http://astro.unl.edu/classaction/animations/coordsmotion/daylighthoursexplorer.html
// http://www.neoprogrammics.com/nutations/Nutation_In_Longitude_And_RA.php
(function (factory) {
    if (typeof define === 'function' && define.amd ) {
        // AMD. Register as module
        if(typeof dojo === 'object') {
            define(["dojo/_base/declare"], function(declare){
                return declare( "my.calc.Sun", null, factory());
            });
        } else {
            define( 'Sundial', null, factory());
        }
    } else {
        Sun = new factory();
    }
}(function () {   
    return {
        date : new Date(),  
        getDate : function(){
          return this.date;  
        },
        setDate : function(d){
          this.date = d;
          return this;
        },
        getJulianDays: function(){
            this._julianDays = Math.floor(( this.date / 86400000) - ( this.date.getTimezoneOffset() / 1440) + 2440587.5);
            return this._julianDays;
        },
        // Calculate the Equation of Time
        // The equation of time is the difference between apparent solar time and mean solar time. 
        // At any given instant, this difference will be the same for every observer on Earth.
        getEquationOfTime : function (){        
            var K = Math.PI/180.0;
            var T = (this.getJulianDays() - 2451545.0) / 36525.0;   
            var eps = this._getObliquity(T); // Calculate the Obliquity (axial tilt of earth)
            var RA = this._getRightAscension(T);
            var LS = this._getSunsMeanLongitude(T);
            var deltaPsi = this._getDeltaPSI(T);                    
            var E = LS - 0.0057183 - RA + deltaPsi*Math.cos(K*eps);     
            if (E>5) {
                E = E - 360.0;
            }
            E = E*4; // deg. to min     
            E = Math.round(1000*E)/1000;                                
            return E;       
        },
        getTotalDaylightHoursInYear : function(lat){
            // We can just use the current Date Object, and incrementally
            // Add 1 Day 365 times... 
            var totalDaylightHours = 0 ;
            for (var d = new Date(this.date.getFullYear(), 0, 1); d <= new Date(this.date.getFullYear(), 11, 30); d.setDate(d.getDate() + 1)) {
                this.date = d;
                // console.log( this.getDaylightHours(lat) );
                totalDaylightHours += this.getDaylightHours(lat);
            }
            return totalDaylightHours;  
        },
        getDaylightHours : function (lat) {
            var K = Math.PI/180.0;
            var C, Nenner, C2, dlh;
            var T = (this.getJulianDays() - 2451545.0) / 36525.0;   
            this._getRightAscension(T); // Need to get the Suns Declination

            Nenner = Math.cos(K*lat)*Math.cos(K*this._sunDeclination);
            C = -Math.sin(K*this._sunDeclination)*Math.sin(K*lat)/Nenner; 
            C2=C*C;
            // console.log( T, C2, C, Nenner, lat, K,  Math.cos(K*lat) );
            if ((C>-1) && (C<1)) {
                dlh=90.0 - Math.atan(C / Math.sqrt(1 - C2)) / K;
                dlh=2.0*dlh/15.0;
                dlh=Math.round(dlh*100)/100; 
            }
            if (C>1) {
                dlh=0.0;
            }
            if (C<-1) {
                dlh=24.0;
            }
            return dlh;
        },
        _getRightAscension : function(T) {  
            var K = Math.PI/180.0;              
            var L, M, C, lambda, RA, eps, delta, theta;                     
            L = this._getSunsMeanLongitude(T); // Calculate the mean longitude of the Sun       
            M = 357.52910 + 35999.05030*T - 0.0001559*T*T - 0.00000048*T*T*T; // Mean anomoly of the Sun
            M = M % 360;        
            if (M<0) {
                M = M + 360;
            }       
            C = (1.914600 - 0.004817*T - 0.000014*T*T)*Math.sin(K*M);
            C = C + (0.019993 - 0.000101*T)*Math.sin(K*2*M);
            C = C + 0.000290*Math.sin(K*3*M);       
            theta = L + C; // get true longitude of the Sun                     
            eps = this._getObliquity(T);                
            eps = eps + 0.00256*Math.cos(K*(125.04 - 1934.136*T));      
            lambda = theta - 0.00569 - 0.00478*Math.sin(K*(125.04 - 1934.136*T)); // get apparent longitude of the Sun
            RA = Math.atan2(Math.cos(K*eps)*Math.sin(K*lambda), Math.cos(K*lambda));                
            RA = RA/K;
            if (RA<0) {
                RA = RA + 360.0;
            }           
            delta = Math.asin(Math.sin(K*eps)*Math.sin(K*lambda));
            delta = delta/K;        
            this._sunDeclination = delta;               
            return RA;      
        },
        // Calculate the Mean Longitude of the Sun
        _getSunsMeanLongitude : function(T){
            var L = 280.46645 + 36000.76983*T + 0.0003032*T*T;  
            L = L % 360;        
            if (L<0) {
                L = L + 360;
            }
            return L;           
        },
        // Nutation in ecliptical longitude expressed in degrees.
        _getDeltaPSI : function(T){
            var K = Math.PI/180.0;
            var deltaPsi, omega, LS, LM;            
            LS = this._getSunsMeanLongitude(T); 
            LM = 218.3165 + 481267.8813*T;      
            LM = LM % 360;  
            if (LM<0) {
                LM = LM + 360;
            }   
            // Longitude of ascending node of lunar orbit on the ecliptic as measured from the mean equinox of date.
            omega = 125.04452 - 1934.136261*T + 0.0020708*T*T + T*T*T/450000;
            deltaPsi = -17.2*Math.sin(K*omega) - 1.32*Math.sin(K*2*LS) - 0.23*Math.sin(K*2*LM) + 0.21*Math.sin(K*2*omega);
            deltaPsi = deltaPsi/3600.0;     
            return deltaPsi;    
        },
        // T = Time Factor Time factor in Julian centuries reckoned from J2000.0, corresponding to JD
        // Calculate Earths Obliquity Nutation
        _getObliquity : function (T) {
            var K = Math.PI/180.0;
            var LS = this._getSunsMeanLongitude(T);
            var LM = 218.3165 + 481267.8813*T;  
            var eps0 =  23.0 + 26.0/60.0 + 21.448/3600.0 - (46.8150*T + 0.00059*T*T - 0.001813*T*T*T)/3600;
            var omega = 125.04452 - 1934.136261*T + 0.0020708*T*T + T*T*T/450000;       
            var deltaEps = (9.20*Math.cos(K*omega) + 0.57*Math.cos(K*2*LS) + 0.10*Math.cos(K*2*LM) - 0.09*Math.cos(K*2*omega))/3600;
            return eps0 + deltaEps; 
        }
    };
}));

jsFiddle 演示

您可以在 jsfiddle 上查看如何使用它的演示。

http://jsfiddle.net/wjKRw/

等我有时间的时候,会去查看存储库中的示例用例。 GitHub Sundial


0

sin24+(24cos-18^12)^(一年中的日数)+(纬度)^24= 日照小时数


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接