C # Восход / Заход солнца с указанием широты / долготы

StackOverflow https://stackoverflow.com/questions/2056555

  •  20-09-2019
  •  | 
  •  

Вопрос

Есть ли в C # способ вычислить заданные широту и долготу, когда солнце сядет и взойдет в течение данного дня?

Это было полезно?

Решение

Вычисления на Javascript здесь.Теперь вам просто нужно выполнить перенос.


Редактировать:вычисления приведены в исходном коде эта страница сейчас же.


Редактировать: здесь это прямая ссылка на исходный код.Нет необходимости рыться в html.

Другие советы

Я знаю, что этот пост старый, но на случай, если кто-то все еще ищет...

Координатно - резкий доступен в виде пакета Nuget.Это автономный пакет, который может работать как в солнечное, так и в лунное время.

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

Примечание:

Предполагается, что даты и время всегда указаны в UTC.

Наконец, вам, возможно, потребуется сослаться на небесные объекты Солнце / Луну .Condition если дата возвращает значение null.Это происходит, когда солнце светит весь день.

РЕДАКТИРОВАТЬ 1/9/2019

Библиотека кардинально изменилась с момента публикации этого поста.Теперь он также может обрабатывать местное время.

Я использовал NAA javascript и c # для создания этой библиотеки на C #.

Восход и заход солнца в C#

Я протестировал его на этих двух сайтах, и он показывает время точно так же, как и сами сайты.

http://www.timeanddate.com/sun/usa/seattle

http://www.esrl.noaa.gov/gmd/grad/solcalc/

Этот API, кажется, работает для меня:

http://sunrise-sunset.org/api

Принятым ответом на это была реализация JavaScript, которая не подходила моему приложению, потому что мне нужно было выполнить вычисления на C #.

Я использовал этот код на C #: http://wiki.crowe.co.nz/Calculate%20Sunrise%2fSunset.ashx, который я проверил на соответствие времени восхода / захода солнца здесь: http://www.timeanddate.com/astronomy/.

Если я округлю секунды до ближайшей минуты, время восхода и захода солнца в реализации C # совпадет с соответствующими значениями, отображаемыми в timeanddate.com, включая случаи перехода на летнее время.Однако код немного перегружен (если только вам не нужны данные о фазе Луны), поэтому я проведу рефакторинг, чтобы сделать именно то, что мне требуется, теперь, когда цифры верны.

Начните с этой информации:

Восходящее Уравнение

Я использую это для создания сценария ruby, который все еще находится в стадии разработки.У меня возникли проблемы с пониманием состоящих из нескольких частей юлианских дат.

Ясно одно, что вы должны ориентироваться на точное время прохождения солнца.Затем вычтите и добавьте значение semi_diurnal_arc = acos(cos_omega), которое основано на вашей широте и солнечном склонении.О!И обязательно включите солнечное преломление в центре и на земле.Похоже, эта земля настоящий волшебник.

VB.Net версия ответа dotsa, которая также может автоматически определять часовые пояса.

Результат (проверено наблюдением за закатом этим вечером):

Output

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

Вс.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

Я создал быстрый скрипт на Python для этого : Вычислитель SunriseSunsetCalculator

Мне еще предстоит обернуть это внутри класса, но это может быть полезно для других.


Редактировать :Открытый исходный код - это потрясающе, поскольку, выполнив базовый скрипт, кто-то вложил его в модуль, а другой добавил интерфейс cli!Спасибо mbideau и nfischer за их вклад!

Вам нужна формула, которая включает уравнение времени, чтобы учесть эксцентричную орбиту системы Земля-Луна вокруг Солнца.Вам нужно использовать координаты с соответствующими базовыми точками, такими как WGS84 или NAD27 или что-то в этом роде.Вам нужно использовать юлианский календарь, а не тот, которым мы пользуемся ежедневно, чтобы правильно определить 5 это время.Об этом нелегко догадаться за секунду времени.Я хотел бы иметь время в моем местоположении, где длина тени равна любой высоте.это должно происходить дважды в день, когда солнце находится на высоте 60 градусов над горизонтом до и после полудня.Кроме того, насколько я понимаю, вам просто нужно добавить ровно один день в год, чтобы получить звездное время, поэтому, если вы хотите увеличить свою тактовую частоту на 366,25 / 365,25, возможно, теперь у вас будут звездные часы вместо гражданских???"МАТЕМАТИКА - это ЯЗЫК, на котором кто-то могущественный написал вселенную"

Еще одной хорошей реализацией JS является suncalc ( солнечный кальций ).

Количеством строк кода можно управлять, поэтому перенос на другие языки (C #), безусловно, возможен.

Если вы предпочитаете внешний сервис, вы могли бы использовать этот приятный и бесплатный API для определения времени восхода и захода солнца: http://sunrise-sunset.org/api

Я использовал его для нескольких проектов, и он работает очень хорошо, данные кажутся очень точными.Просто выполните HTTP GET-запрос, чтобы http://api.sunrise-sunset.org/json

Принятые Параметры:

  • лат:Широта в десятичных градусах.Требуется.
  • сжиженный природный газ:Долгота в десятичных градусах.Требуется.
  • Дата:Дата в формате ГГГГ-ММ-ДД.Также принимает другие форматы дат и даже относительные форматы дат.Если дата отсутствует, по умолчанию используется текущая дата.Необязательно.
  • обратный вызов:Имя функции обратного вызова для ответа JSONP.Необязательно.
  • отформатированный:0 или 1 (по умолчанию используется 1).Значения времени в ответе будут выражены в соответствии с ISO 8601, а day_length будет выражен в секундах.Необязательно.

Ответ включает время восхода и захода солнца, а также время наступления сумерек.

Я протестировал этот пакет nuget в UWP.

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

Документация немного отрывочна и находится здесь:

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

Вы можете использовать это, чтобы получить восход солнца, учитывая

la = latitude;и 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");

Вы можете установить его в Visual Studio с помощью PM manager

Install-Package SolarCalculator -Version 2.0.2 

или поискав SolarCalculator в библиотеке Visual Studio "Управление пакетами NuGet".

Да, уволились несколько.

Несколько ссылок на шаблоны.

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?форум=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 ?Восход + и+ Закат+времени+Вычисления+

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

использует эту суть плюс

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_ (астрономия)

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

По сути, это ваше JDN за вычетом эпохи, такой как J2000 или 2451545.0 все делится на 36525,0, чтобы получить юлианское столетие или t которое используется для большинства формул, содержащих t в качестве параметра.Иногда Используется юлианское тысячелетие.В таком случае это 3652500.0

Хитрость заключается в том, чтобы найти те угловые формулы, которые помогут вам решить уравнение времени.

Затем вы получаете свой истинный солнечный транзит и вычитаете половину дня солнечного света или добавляете половину дня солнечного света для вашего местоположения.Вы найдете их в ответах и программном обеспечении.

Как только у вас что-то получается, вы можете проверить это с помощью поиска the times или онлайн-калькуляторов.

Я надеюсь, этого достаточно, чтобы заставить вас двигаться дальше.Библиотеки есть повсюду, но создать свою собственную не так уж сложно.Я сделал, но это на Ruby.Это могло бы оказаться полезным....https://github.com/DouglasAllen/gem-equationoftime

удачи!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top