【问题标题】:C# Sunrise/Sunset with latitude/longitudeC#日出/日落与纬度/经度
【发布时间】:2010-01-13 12:25:52
【问题描述】:

C# 中有没有一种方法可以计算给定一天的太阳落下和升起时的纬度和经度?

【问题讨论】:

标签: c# latitude-longitude


【解决方案1】:

我知道这篇文章已经过时了,但万一有人还在看……

CoordinateSharp 以 Nuget 包的形式提供。它是一个独立的包,可以处理太阳时间和月亮时间。

Celestial cel = Celestial.CalculateCelestialTimes(85.57682, -70.75678, new DateTime(2017,8,21));
Console.WriteLine(cel.SunRise.Value.ToString());

注意:

它假定 DateTimes 始终采用 UTC。

最后,如果日期返回 null,您可能需要引用 Celestial 对象 Sun/Moon .Condition。当太阳全天升起/落下时会发生这种情况。

编辑 2019 年 1 月 9 日

自这篇文章以来,图书馆发生了巨大的变化。它现在也可以处理当地时间了。

【讨论】:

  • 但它不是免费的!它有一个限制性且令人困惑的公共和商业使用许可组合,自述文件中的任何地方都没有解释。它需要为任何封闭源代码的商业用途购买商业许可证...
  • @JonMcPherson 你是对的,任何封闭源代码的分布式使用都需要购买商业许可证。话虽如此,这是super affordable 一次无限次使用的费用。我将在 README 中添加注释。感谢您的反馈。
  • 我还会注意到,如果它们属于某些场景(科学、学术等),他们会为封闭源代码产品授予免费使用商业许可。我想说大约一半的许可证是我上次查看时免费提供的。
【解决方案2】:

这个 API 似乎对我有用:

http://sunrise-sunset.org/api

【讨论】:

  • 请注意,该 API 需要署名。
  • API 在返回的数据中不包括夏令时调整
【解决方案3】:

我已经在 UWP 中测试了这个 nuget 包。

https://www.nuget.org/packages/SolarCalculator/

文档有点粗略,在这里:

https://github.com/porrey/Solar-Calculator

你可以用它来获得日出,给定

la = 纬度;和 lo = 经度;对于您所在的地区:

            SolarTimes solarTimes = new SolarTimes(DateTime.Now, la, lo);
            DateTime sr = solarTimes.Sunrise;
            DateTime dt = Convert.ToDateTime(sr);
            textblockb.Text = dt.ToString("h:mm:ss");

您可以使用 PM 管理器在 Visual Studio 中安装它

Install-Package SolarCalculator -Version 2.0.2 

或通过在“管理 NuGet 包”Visual Studio 库中查找 SolarCalculator。

【讨论】:

    【解决方案4】:

    对此的公认答案是 JavaScript 实现,它不适合我的应用程序,因为我需要在 C# 中进行计算。

    我使用了这个 C# 代码:http://wiki.crowe.co.nz/Calculate%20Sunrise%2fSunset.ashx,我已在此处针对日出/日落时间进行了验证:http://www.timeanddate.com/astronomy/

    如果我将秒四舍五入到最接近的分钟,C# 实现的日出和日落时间与 timeanddate.com 上显示的相应值匹配,包括夏令时的情况。虽然代码有点压倒性(除非您也想要月相数据),所以我将对其进行重构,以专门完成我现在需要的数字。

    【讨论】:

    • 在网上尝试了很多例子后,这个对我有用。我能够毫不费力地在线转换为 VB。如果您在冬天在北极圈内,它会给出 9999 年,但只需循环后退一天或前进一天,直到您收到非 9999 的响应,您就可以开始了。
    【解决方案5】:

    dotsa答案的VB.Net版本,也可以自动确定时区。

    输出(通过今晚看日落检查):

    Main.VB:

    Module Main
    
    Sub Main()
    
        ' http://www.timeanddate.com/sun/usa/seattle
        ' http://www.esrl.noaa.gov/gmd/grad/solcalc/
    
        ' Vessy, Switzerland
        Dim latitude As Double = 46.17062
        Dim longitude As Double = 6.161667
        Dim dst As Boolean = True
        Dim timehere As DateTime = DateTime.Now
    
        Console.WriteLine("It is currently {0:HH:mm:ss} UTC", DateTime.UtcNow)
        Console.WriteLine("The time here, at {0}°,{1}° is {2:HH:mm:ss}", latitude, longitude, timehere)
        Dim local As TimeZoneInfo = TimeZoneInfo.Local
        Dim zone As Integer = local.BaseUtcOffset().TotalHours
    
        If local.SupportsDaylightSavingTime Then
            Dim standard As String = local.StandardName
            Dim daylight As String = local.DaylightName
            dst = local.IsDaylightSavingTime(timehere)
            Dim current As String = IIf(dst, daylight, standard)
            Console.WriteLine("Daylight-saving time is supported here. Current offset {0:+0} hours, {1}", zone, current)
        Else
            Console.WriteLine("Daylight-saving time is not supported here")
        End If
    
        System.Console.WriteLine("Sunrise today {0}", Sunrises(latitude, longitude))
        System.Console.WriteLine("Sunset  today {0}", Sunsets(latitude, longitude))
        System.Console.ReadLine()
    End Sub
    
    End Module
    

    Sun.vb:

    Public Module Sun
    ' Get sunrise time at latitude, longitude using local system timezone
    Function Sunrises(latitude As Double, longitude As Double) As DateTime
        Dim julian As Double = JulianDay(DateTime.Now)
        Dim rises As Double = SunRiseUTC(julian, latitude, longitude)
        Dim timehere As DateTime = DateTime.Now
        Dim local As TimeZoneInfo = TimeZoneInfo.Local
        Dim dst As Boolean = local.IsDaylightSavingTime(timehere)
        Dim zone As Integer = local.BaseUtcOffset().TotalHours
        Dim result As DateTime = getDateTime(rises, zone, timehere, dst)
        Return result
    End Function
    ' Get sunset time at latitude, longitude using local system timezone
    Function Sunsets(latitude As Double, longitude As Double) As DateTime
        Dim julian As Double = JulianDay(DateTime.Now)
        Dim rises As Double = SunSetUTC(julian, latitude, longitude)
        Dim timehere As DateTime = DateTime.Now
        Dim local As TimeZoneInfo = TimeZoneInfo.Local
        Dim dst As Boolean = local.IsDaylightSavingTime(timehere)
        Dim zone As Integer = local.BaseUtcOffset().TotalHours
        Dim result As DateTime = getDateTime(rises, zone, timehere, dst)
        Return result
    End Function
    ' Convert radian angle to degrees
    Public Function Degrees(angleRad As Double) As Double
        Return (180.0 * angleRad / Math.PI)
    End Function
    ' Convert degree angle to radians
    Public Function Radians(angleDeg As Double) As Double
        Return (Math.PI * angleDeg / 180.0)
    End Function
    '* Name: JulianDay  
    '* Type: Function   
    '* Purpose: Julian day from calendar day    
    '* Arguments:   
    '* year : 4 digit year  
    '* month: January = 1   
    '* day : 1 - 31 
    '* Return value:    
    '* The Julian day corresponding to the date 
    '* Note:    
    '* Number is returned for start of day. Fractional days should be   
    '* added later. 
    Public Function JulianDay(year As Integer, month As Integer, day As Integer) As Double
        If month <= 2 Then
            year -= 1
            month += 12
        End If
        Dim A As Double = Math.Floor(year / 100.0)
        Dim B As Double = 2 - A + Math.Floor(A / 4)
    
        Dim julian As Double = Math.Floor(365.25 * (year + 4716)) + Math.Floor(30.6001 * (month + 1)) + day + B - 1524.5
        Return julian
    End Function
    
    Public Function JulianDay([date] As DateTime) As Double
        Return JulianDay([date].Year, [date].Month, [date].Day)
    End Function
    
    '***********************************************************************/
    '* Name: JulianCenturies    
    '* Type: Function   
    '* Purpose: convert Julian Day to centuries since J2000.0.  
    '* Arguments:   
    '* julian : the Julian Day to convert   
    '* Return value:    
    '* the T value corresponding to the Julian Day  
    '***********************************************************************/
    
    Public Function JulianCenturies(julian As Double) As Double
        Dim T As Double = (julian - 2451545.0) / 36525.0
        Return T
    End Function
    
    
    '***********************************************************************/
    '* Name: JulianDayFromJulianCentury 
    '* Type: Function   
    '* Purpose: convert centuries since J2000.0 to Julian Day.  
    '* Arguments:   
    '* t : number of Julian centuries since J2000.0 
    '* Return value:    
    '* the Julian Day corresponding to the t value  
    '***********************************************************************/
    
    Public Function JulianDayFromJulianCentury(t As Double) As Double
        Dim julian As Double = t * 36525.0 + 2451545.0
        Return julian
    End Function
    
    
    '***********************************************************************/
    '* Name: calGeomMeanLongSun 
    '* Type: Function   
    '* Purpose: calculate the Geometric Mean Longitude of the Sun   
    '* Arguments:   
    '* t : number of Julian centuries since J2000.0 
    '* Return value:    
    '* the Geometric Mean Longitude of the Sun in degrees   
    '***********************************************************************/
    
    Public Function GemoetricMeanLongitude(t As Double) As Double
        Dim L0 As Double = 280.46646 + t * (36000.76983 + 0.0003032 * t)
        While L0 > 360.0
            L0 -= 360.0
        End While
        While L0 < 0.0
            L0 += 360.0
        End While
        Return L0
        ' in degrees
    End Function
    
    
    '***********************************************************************/
    '* Name: calGeomAnomalySun  
    '* Type: Function   
    '* Purpose: calculate the Geometric Mean Anomaly of the Sun 
    '* Arguments:   
    '* t : number of Julian centuries since J2000.0 
    '* Return value:    
    '* the Geometric Mean Anomaly of the Sun in degrees 
    '***********************************************************************/
    
    Public Function GemoetricMeanAnomaly(t As Double) As Double
        Dim M As Double = 357.52911 + t * (35999.05029 - 0.0001537 * t)
        Return M
        ' in degrees
    End Function
    
    '***********************************************************************/
    '* Name: EarthOrbitEccentricity 
    '* Type: Function   
    '* Purpose: calculate the eccentricity of earth's orbit 
    '* Arguments:   
    '* t : number of Julian centuries since J2000.0 
    '* Return value:    
    '* the unitless eccentricity    
    '***********************************************************************/
    
    
    Public Function EarthOrbitEccentricity(t As Double) As Double
        Dim e As Double = 0.016708634 - t * (0.000042037 + 0.0000001267 * t)
        Return e
        ' unitless
    End Function
    
    '***********************************************************************/
    '* Name: SunCentre  
    '* Type: Function   
    '* Purpose: calculate the equation of center for the sun    
    '* Arguments:   
    '* t : number of Julian centuries since J2000.0 
    '* Return value:    
    '* in degrees   
    '***********************************************************************/
    
    
    Public Function SunCentre(t As Double) As Double
        Dim m As Double = GemoetricMeanAnomaly(t)
    
        Dim mrad As Double = Radians(m)
        Dim sinm As Double = Math.Sin(mrad)
        Dim sin2m As Double = Math.Sin(mrad + mrad)
        Dim sin3m As Double = Math.Sin(mrad + mrad + mrad)
    
        Dim C As Double = sinm * (1.914602 - t * (0.004817 + 0.000014 * t)) + sin2m * (0.019993 - 0.000101 * t) + sin3m * 0.000289
        Return C
        ' in degrees
    End Function
    
    '***********************************************************************/
    '* Name: SunTrueLongitude   
    '* Type: Function   
    '* Purpose: calculate the true longitude of the sun 
    '* Arguments:   
    '* t : number of Julian centuries since J2000.0 
    '* Return value:    
    '* sun's true longitude in degrees  
    '***********************************************************************/
    
    
    Public Function SunTrueLongitude(t As Double) As Double
        Dim l0 As Double = GemoetricMeanLongitude(t)
        Dim c As Double = SunCentre(t)
    
        Dim O As Double = l0 + c
        Return O
        ' in degrees
    End Function
    
    '***********************************************************************/
    '* Name: SunTrueAnomaly 
    '* Type: Function   
    '* Purpose: calculate the true anamoly of the sun   
    '* Arguments:   
    '* t : number of Julian centuries since J2000.0 
    '* Return value:    
    '* sun's true anamoly in degrees    
    '***********************************************************************/
    
    Public Function SunTrueAnomaly(t As Double) As Double
        Dim m As Double = GemoetricMeanAnomaly(t)
        Dim c As Double = SunCentre(t)
    
        Dim v As Double = m + c
        Return v
        ' in degrees
    End Function
    
    '***********************************************************************/
    '* Name: SunDistanceAU  
    '* Type: Function   
    '* Purpose: calculate the distance to the sun in AU 
    '* Arguments:   
    '* t : number of Julian centuries since J2000.0 
    '* Return value:    
    '* sun radius vector in AUs 
    '***********************************************************************/
    
    Public Function SunDistanceAU(t As Double) As Double
        Dim v As Double = SunTrueAnomaly(t)
        Dim e As Double = EarthOrbitEccentricity(t)
    
        Dim R As Double = (1.000001018 * (1 - e * e)) / (1 + e * Math.Cos(Radians(v)))
        Return R
        ' in AUs
    End Function
    
    '***********************************************************************/
    '* Name: SunApparentLongitude   
    '* Type: Function   
    '* Purpose: calculate the apparent longitude of the sun 
    '* Arguments:   
    '* t : number of Julian centuries since J2000.0 
    '* Return value:    
    '* sun's apparent longitude in degrees  
    '***********************************************************************/
    
    Public Function SunApparentLongitude(t As Double) As Double
        Dim o As Double = SunTrueLongitude(t)
    
        Dim omega As Double = 125.04 - 1934.136 * t
        Dim lambda As Double = o - 0.00569 - 0.00478 * Math.Sin(Radians(omega))
        Return lambda
        ' in degrees
    End Function
    
    '***********************************************************************/
    '* Name: MeanObliquityOfEcliptic    
    '* Type: Function   
    '* Purpose: calculate the mean obliquity of the ecliptic    
    '* Arguments:   
    '* t : number of Julian centuries since J2000.0 
    '* Return value:    
    '* mean obliquity in degrees    
    '***********************************************************************/
    
    Public Function MeanObliquityOfEcliptic(t As Double) As Double
        Dim seconds As Double = 21.448 - t * (46.815 + t * (0.00059 - t * (0.001813)))
        Dim e0 As Double = 23.0 + (26.0 + (seconds / 60.0)) / 60.0
        Return e0
        ' in degrees
    End Function
    
    '***********************************************************************/
    '* Name: calcObliquityCorrection    
    '* Type: Function   
    '* Purpose: calculate the corrected obliquity of the ecliptic   
    '* Arguments:   
    '* t : number of Julian centuries since J2000.0 
    '* Return value:    
    '* corrected obliquity in degrees   
    '***********************************************************************/
    
    Public Function calcObliquityCorrection(t As Double) As Double
        Dim e0 As Double = MeanObliquityOfEcliptic(t)
    
        Dim omega As Double = 125.04 - 1934.136 * t
        Dim e As Double = e0 + 0.00256 * Math.Cos(Radians(omega))
        Return e
        ' in degrees
    End Function
    
    '***********************************************************************/
    '* Name: SunRightAscension  
    '* Type: Function   
    '* Purpose: calculate the right ascension of the sun    
    '* Arguments:   
    '* t : number of Julian centuries since J2000.0 
    '* Return value:    
    '* sun's right ascension in degrees 
    '***********************************************************************/
    
    Public Function SunRightAscension(t As Double) As Double
        Dim e As Double = calcObliquityCorrection(t)
        Dim lambda As Double = SunApparentLongitude(t)
    
        Dim tananum As Double = (Math.Cos(Radians(e)) * Math.Sin(Radians(lambda)))
        Dim tanadenom As Double = (Math.Cos(Radians(lambda)))
        Dim alpha As Double = Degrees(Math.Atan2(tananum, tanadenom))
        Return alpha
        ' in degrees
    End Function
    
    '***********************************************************************/
    '* Name: SunDeclination 
    '* Type: Function   
    '* Purpose: calculate the declination of the sun    
    '* Arguments:   
    '* t : number of Julian centuries since J2000.0 
    '* Return value:    
    '* sun's declination in degrees 
    '***********************************************************************/
    
    Public Function SunDeclination(t As Double) As Double
        Dim e As Double = calcObliquityCorrection(t)
        Dim lambda As Double = SunApparentLongitude(t)
    
        Dim sint As Double = Math.Sin(Radians(e)) * Math.Sin(Radians(lambda))
        Dim theta As Double = Degrees(Math.Asin(sint))
        Return theta
        ' in degrees
    End Function
    
    '***********************************************************************/
    '* Name: TrueSolarToMeanSolar   
    '* Type: Function   
    '* Purpose: calculate the difference between true solar time and mean   
    '*   solar time 
    '* Arguments:   
    '* t : number of Julian centuries since J2000.0 
    '* Return value:    
    '* equation of time in minutes of time  
    '***********************************************************************/
    
    Public Function TrueSolarToMeanSolar(t As Double) As Double
        Dim epsilon As Double = calcObliquityCorrection(t)
        Dim l0 As Double = GemoetricMeanLongitude(t)
        Dim e As Double = EarthOrbitEccentricity(t)
        Dim m As Double = GemoetricMeanAnomaly(t)
    
        Dim y As Double = Math.Tan(Radians(epsilon) / 2.0)
        y *= y
    
        Dim sin2l0 As Double = Math.Sin(2.0 * Radians(l0))
        Dim sinm As Double = Math.Sin(Radians(m))
        Dim cos2l0 As Double = Math.Cos(2.0 * Radians(l0))
        Dim sin4l0 As Double = Math.Sin(4.0 * Radians(l0))
        Dim sin2m As Double = Math.Sin(2.0 * Radians(m))
    
        Dim Etime As Double = y * sin2l0 - 2.0 * e * sinm + 4.0 * e * y * sinm * cos2l0 - 0.5 * y * y * sin4l0 - 1.25 * e * e * sin2m
    
        Return Degrees(Etime) * 4.0
        ' in minutes of time
    End Function
    
    '***********************************************************************/
    '* Name: SunriseHourAngle   
    '* Type: Function   
    '* Purpose: calculate the hour angle of the sun at sunrise for the  
    '*   latitude   
    '* Arguments:   
    '* lat : latitude of observer in degrees    
    '*  solarDec : declination angle of sun in degrees  
    '* Return value:    
    '* hour angle of sunrise in radians 
    '***********************************************************************/
    
    Public Function SunriseHourAngle(lat As Double, solarDec As Double) As Double
        Dim latRad As Double = Radians(lat)
        Dim sdRad As Double = Radians(solarDec)
    
        Dim HAarg As Double = (Math.Cos(Radians(90.833)) / (Math.Cos(latRad) * Math.Cos(sdRad)) - Math.Tan(latRad) * Math.Tan(sdRad))
    
        Dim HA As Double = (Math.Acos(Math.Cos(Radians(90.833)) / (Math.Cos(latRad) * Math.Cos(sdRad)) - Math.Tan(latRad) * Math.Tan(sdRad)))
    
        Return HA
        ' in radians
    End Function
    
    '***********************************************************************/
    '* Name: SunsetHourAngle    
    '* Type: Function   
    '* Purpose: calculate the hour angle of the sun at sunset for the   
    '*   latitude   
    '* Arguments:   
    '* lat : latitude of observer in degrees    
    '*  solarDec : declination angle of sun in degrees  
    '* Return value:    
    '* hour angle of sunset in radians  
    '***********************************************************************/
    
    Public Function SunsetHourAngle(lat As Double, solarDec As Double) As Double
        Dim latRad As Double = Radians(lat)
        Dim sdRad As Double = Radians(solarDec)
    
        Dim HAarg As Double = (Math.Cos(Radians(90.833)) / (Math.Cos(latRad) * Math.Cos(sdRad)) - Math.Tan(latRad) * Math.Tan(sdRad))
    
        Dim HA As Double = (Math.Acos(Math.Cos(Radians(90.833)) / (Math.Cos(latRad) * Math.Cos(sdRad)) - Math.Tan(latRad) * Math.Tan(sdRad)))
    
        Return -HA
        ' in radians
    End Function
    
    
    '***********************************************************************/
    '* Name: SunRiseUTC 
    '* Type: Function   
    '* Purpose: calculate the Universal Coordinated Time (UTC) of sunrise   
    '*   for the given day at the given location on earth   
    '* Arguments:   
    '* julian : julian day  
    '* latitude : latitude of observer in degrees   
    '* longitude : longitude of observer in degrees 
    '* Return value:    
    '* time in minutes from zero Z  
    '***********************************************************************/
    
    'Public  Function SunRiseUTC(julian As Double, latitude As Double, longitude As Double) As Double
    '    Dim t As Double = JulianCenturies(julian)
    
    '    ' *** Find the time of solar noon at the location, and use
    '    ' that declination. This is better than start of the 
    '    ' Julian day
    
    '    Dim noonmin As Double = SolarNoonUTC(t, longitude)
    '    Dim tnoon As Double = JulianCenturies(julian + noonmin / 1440.0)
    
    '    ' *** First pass to approximate sunrise (using solar noon)
    
    '    Dim eqTime As Double = TrueSolarToMeanSolar(tnoon)
    '    Dim solarDec As Double = SunDeclination(tnoon)
    '    Dim hourAngle As Double = SunriseHourAngle(latitude, solarDec)
    
    '    Dim delta As Double = longitude - Degrees(hourAngle)
    '    Dim timeDiff As Double = 4 * delta
    '    ' in minutes of time
    '    Dim timeUTC As Double = 720 + timeDiff - eqTime
    '    ' in minutes
    '    ' alert("eqTime = " + eqTime + "\nsolarDec = " + solarDec + "\ntimeUTC = " + timeUTC);
    
    '    ' *** Second pass includes fractional julianay in gamma calc
    
    '    Dim newt As Double = JulianCenturies(JulianDayFromJulianCentury(t) + timeUTC / 1440.0)
    '    eqTime = TrueSolarToMeanSolar(newt)
    '    solarDec = SunDeclination(newt)
    '    hourAngle = SunriseHourAngle(latitude, solarDec)
    '    delta = longitude - Degrees(hourAngle)
    '    timeDiff = 4 * delta
    '    timeUTC = 720 + timeDiff - eqTime
    '    ' in minutes
    '    ' alert("eqTime = " + eqTime + "\nsolarDec = " + solarDec + "\ntimeUTC = " + timeUTC);
    
    '    Return timeUTC
    'End Function
    
    '***********************************************************************/
    '* Name: SolarNoonUTC   
    '* Type: Function   
    '* Purpose: calculate the Universal Coordinated Time (UTC) of solar 
    '*   noon for the given day at the given location on earth  
    '* Arguments:   
    '* t : number of Julian centuries since J2000.0 
    '* longitude : longitude of observer in degrees 
    '* Return value:    
    '* time in minutes from zero Z  
    '***********************************************************************/
    
    Public Function SolarNoonUTC(t As Double, longitude As Double) As Double
        ' First pass uses approximate solar noon to calculate eqtime
        Dim tnoon As Double = JulianCenturies(JulianDayFromJulianCentury(t) + longitude / 360.0)
        Dim eqTime As Double = TrueSolarToMeanSolar(tnoon)
        Dim solNoonUTC As Double = 720 + (longitude * 4) - eqTime
        ' min
        Dim newt As Double = JulianCenturies(JulianDayFromJulianCentury(t) - 0.5 + solNoonUTC / 1440.0)
    
        eqTime = TrueSolarToMeanSolar(newt)
        ' double solarNoonDec = SunDeclination(newt);
        solNoonUTC = 720 + (longitude * 4) - eqTime
        ' min
        Return solNoonUTC
    End Function
    
    '***********************************************************************/
    '* Name: SunSetUTC  
    '* Type: Function   
    '* Purpose: calculate the Universal Coordinated Time (UTC) of sunset    
    '*   for the given day at the given location on earth   
    '* Arguments:   
    '* julian : julian day  
    '* latitude : latitude of observer in degrees   
    '* longitude : longitude of observer in degrees 
    '* Return value:    
    '* time in minutes from zero Z  
    '***********************************************************************/
    
    Public Function SunSetUTC(julian As Double, latitude As Double, longitude As Double) As Double
        Dim t = JulianCenturies(julian)
        Dim eqTime = TrueSolarToMeanSolar(t)
        Dim solarDec = SunDeclination(t)
        Dim hourAngle = SunriseHourAngle(latitude, solarDec)
        hourAngle = -hourAngle
        Dim delta = longitude + Degrees(hourAngle)
        Dim timeUTC = 720 - (4.0 * delta) - eqTime
        ' in minutes
        Return timeUTC
    End Function
    
    Public Function SunRiseUTC(julian As Double, latitude As Double, longitude As Double) As Double
        Dim t = JulianCenturies(julian)
        Dim eqTime = TrueSolarToMeanSolar(t)
        Dim solarDec = SunDeclination(t)
        Dim hourAngle = SunriseHourAngle(latitude, solarDec)
        Dim delta = longitude + Degrees(hourAngle)
        Dim timeUTC = 720 - (4.0 * delta) - eqTime
        ' in minutes
        Return timeUTC
    End Function
    
    Public Function getTimeString(time As Double, timezone As Integer, julian As Double, dst As Boolean) As String
        Dim timeLocal = time + (timezone * 60.0)
        Dim riseT = JulianCenturies(julian + time / 1440.0)
        timeLocal += (If((dst), 60.0, 0.0))
        Return getTimeString(timeLocal)
    End Function
    
    Public Function getDateTime(time As Double, timezone As Integer, [date] As DateTime, dst As Boolean) As System.Nullable(Of DateTime)
        Dim julian As Double = JulianDay([date])
        Dim timeLocal = time + (timezone * 60.0)
        Dim riseT = JulianCenturies(julian + time / 1440.0)
        timeLocal += (If((dst), 60.0, 0.0))
        Return getDateTime(timeLocal, [date])
    End Function
    
    Private Function getTimeString(minutes As Double) As String
    
        Dim output As String = ""
    
        If (minutes >= 0) AndAlso (minutes < 1440) Then
            Dim floatHour = minutes / 60.0
            Dim hour = Math.Floor(floatHour)
            Dim floatMinute = 60.0 * (floatHour - Math.Floor(floatHour))
            Dim minute = Math.Floor(floatMinute)
            Dim floatSec = 60.0 * (floatMinute - Math.Floor(floatMinute))
            Dim second = Math.Floor(floatSec + 0.5)
            If second > 59 Then
                second = 0
                minute += 1
            End If
            If (second >= 30) Then
                minute += 1
            End If
            If minute > 59 Then
                minute = 0
                hour += 1
            End If
            output = [String].Format("{0:00}:{1:00}", hour, minute)
        Else
            Return "error"
        End If
    
        Return output
    End Function
    
    Private Function getDateTime(minutes As Double, [date] As DateTime) As System.Nullable(Of DateTime)
    
        Dim retVal As System.Nullable(Of DateTime) = Nothing
    
        If (minutes >= 0) AndAlso (minutes < 1440) Then
            Dim floatHour = minutes / 60.0
            Dim hour = Math.Floor(floatHour)
            Dim floatMinute = 60.0 * (floatHour - Math.Floor(floatHour))
            Dim minute = Math.Floor(floatMinute)
            Dim floatSec = 60.0 * (floatMinute - Math.Floor(floatMinute))
            Dim second = Math.Floor(floatSec + 0.5)
            If second > 59 Then
                second = 0
                minute += 1
            End If
            If (second >= 30) Then
                minute += 1
            End If
            If minute > 59 Then
                minute = 0
                hour += 1
            End If
            Return New DateTime([date].Year, [date].Month, [date].Day, CInt(hour), CInt(minute), CInt(second))
        Else
            Return retVal
        End If
    End Function
    End Module
    

    【讨论】:

      【解决方案6】:

      从以下信息开始:​​

      Sunrise_equation

      我正在使用它来编写一个仍在制作中的 ruby​​ 脚本。 我无法理解多部分的朱利安日期。

      有一点很清楚,您应该选择准确的太阳过境时间。 然后减去并添加基于的 semi_diurnal_arc = acos(cos_omega) 根据你的纬度和太阳赤纬。哦!并确保包括太阳能 中心和地球折射。看来这个地球真是个魔术师。

      【讨论】:

      【解决方案7】:

      您需要一个包含时间等式的公式,以允许地球月球系统围绕太阳运行的偏心轨道。您需要使用具有适当基准点的坐标,例如 WGS84 或 NAD27 或类似的东西。您需要使用 JULIAN 日历,而不是我们每天使用的日历,才能正确处理这些时间。在一秒钟之内猜测出来并不是一件容易的事情。我想在我的位置有时间,阴影长度等于任何高度。这应该每天发生两次,当太阳在中午前后升高到地平线以上 60 度时。另外,据我了解,您只需要每年增加一天即可获得恒星时间,因此如果您想将时钟频率提高 X 366.25/365.25,您现在可能有一个恒星时钟而不是民用时钟??? “数学是一个强大的人书写宇宙的语言”

      【讨论】:

        【解决方案8】:

        如果您更喜欢外部服务,您可以使用这个不错且免费的日出和日落时间 API:http://sunrise-sunset.org/api

        我已经在几个项目中使用它并且效果很好,数据似乎非常准确。只需向 http://api.sunrise-sunset.org/json 发出 HTTP GET 请求

        接受的参数:

        • lat:十进制度的纬度。必填。
        • lng:十进制度的经度。必填。
        • 日期:YYYY-MM-DD 格式的日期。还接受其他日期格式,甚至是相对日期格式。如果不存在,日期默认为当前日期。可选。
        • 回调:JSONP 响应的回调函数名称。可选。
        • 格式化:0 或 1(1 为默认值)。响应的时间值将按照 ISO 8601 表示,day_length 将以秒表示。可选。

        响应包括日出和日落时间以及黄昏时间。

        【讨论】:

        • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
        • 感谢您的评论伊恩。我编辑了我的答案以改进它。
        【解决方案9】:

        是的,放弃一些。

        一些模式链接。

        http://williams.best.vwh.net/sunrise_sunset_example.htm

        http://www.codeproject.com/Articles/29306/C-Class-for-Calculating-Sunrise-and-Sunset-Times

        https://social.msdn.microsoft.com/Forums/vstudio/en-US/a4fad4c3-6d18-41fc-82b7-1f3031349837/get-sunrise-and-sunset-time-based-on-latitude-and-longitude?forum=csharpgeneral

        https://gist.github.com/cstrahan/767532

        http://pointofint.blogspot.com/2014/06/sunrise-and-sunset-in-c.html

        http://yaddb.blogspot.com/2013/01/how-to-calculate-sunrise-and-sunset.html

        https://forums.asp.net/t/1810934.aspx?Sunrise+and+Sunset+timings+Calculation+

        http://www.ip2location.com/tutorials/display-sunrise-sunset-time-using-csharp-and-mysql-database

        http://en.pudn.com/downloads270/sourcecode/windows/csharp/detail1235934_en.html

        http://regator.com/p/25716249/c_class_for_calculating_sunrise_and_sunset_times

        http://forums.xkcd.com/viewtopic.php?t=102253

        http://www.redrok.com/solar_position_algorithm.pdf

        http://sidstation.loudet.org/sunazimuth-en.xhtml

        https://sourceforge.net/directory/os:windows/?q=sunrise/set%20times

        https://www.nuget.org/packages/SolarCalculator/

        http://www.grasshopper3d.com/forum/topics/solar-calculation-plugin

        这是我很久以前为 Planet Source Code 做的一个项目,但幸运的是我将它保存在其他地方,因为该站点丢失了数据。

        https://github.com/DouglasAllen/SunTimes.VSCS.Net

        使用这个 Gist plus

        https://gist.github.com/DouglasAllen/c682e4c412a0b9d8f536b014c1766f20

        现在简要解释一下实现这一点的技术。

        首先,您需要真正的太阳正午或您所在位置的交通。

        这会考虑到您当地的经度。只需将其除以 15 即可转换为时间。

        这是你距离祖鲁地区时间或零经度的时间。

        从中午 12:00 或中午开始。

        并根据经度计算您的时间。

        现在是困难的部分。你需要一种计算时间方程的方法。

        这是由地球倾斜和绕太阳运行引起的时差。

        这会给你一个想法...https://en.wikipedia.org/wiki/Equation_of_time

        但他们有一个更容易的公式......https://en.wikipedia.org/wiki/Sunrise_equation

        这家伙有一些书,很多人都会去或买。 :-D https://en.wikipedia.org/wiki/Jean_Meeus

        使用您的第一个计算来计算平均太阳凌日并计算 JDN...https://en.wikipedia.org/wiki/Julian_day

        这被所有角度公式用作儒略世纪的时间 https://en.wikipedia.org/wiki/Julian_year_(astronomy)

        https://en.wikipedia.org/wiki/Epoch_(astronomy)

        这基本上是您的 JDN 减去诸如 J2000 或 2451545.0 之类的纪元 全部除以 36525.0 得到儒略世纪或 t 它用于大多数以 t 作为参数的公式。有时 使用儒略千年。在这种情况下,它是 3652500.0

        诀窍是找到那些有助于解决时间方程的角度公式。

        然后你得到你真正的太阳过境并减去半天或增加你所在位置的半天阳光。您可以在答案和软件中找到这些内容。

        一旦事情进展顺利,您可以通过搜索时间或在线计算器来检查它。

        我希望这足以让你继续前进。到处都有图书馆,但制作自己的图书馆并不难。我做了,但它是在 Ruby 中的。 它可能很有用....https://github.com/DouglasAllen/gem-equationoftime

        祝你好运!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-08-16
          • 2011-07-03
          • 1970-01-01
          • 2013-09-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多