2010-01-13 35 views
22

¿Hay alguna forma en C# para calcular dada la latitud y la longitud cuando el sol se pone y se levanta para un día determinado?C# Amanecer/Atardecer con latitud/longitud

+1

Si ha hecho el trabajo, puede pensar en publicarlo aquí como respuesta para que otros no tengan que reproducirlo. – Pat

+0

No he probado esto, pero me encontré con este hilo en MSDN que se responde: [Obtener el tiempo de salida y puesta del sol en función de la latitud y la longitud] (http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/a4fad4c3-6d18-41fc-82b7-1f3031349837) –

+0

También eche un vistazo a este http://www.codeproject.com/KB/recipes/SolarCalculator.aspx – Patrick

Respuesta

15

Cálculos de Javascript here. Ahora solo necesitas portar.


Editar: los cálculos se encuentran en el código fuente de this page ahora.


Editar: here es un enlace directo al código fuente. No es necesario ir a buscar el html.

+0

Miré la calculadora solar que has vinculado, pero el código que usan es incómodo e irrecuperable (para mí, al menos) enredado con la lógica específica de la página. La matemática está en Wikipedia: http://en.wikipedia.org/wiki/Sunrise_equation#Complete_calculation_on_Earth He creado un código JavaScript independiente para manejar el cálculo y ser reutilizable, pero creo que he obtenido Algo está mal con los cálculos: https://github.com/mcordingley/sunrise/blob/master/sunrise.js –

+0

Otra implementación de Javascript https://github.com/mourner/suncalc – Epeli

+0

Si necesita más precisión, considere utilizando las bibliotecas SPICE: http://naif.jpl.nasa.gov/naif/tutorials.html – barrycarter

2

de inicio con esta información:

Sunrise_equation

estoy usando esto para Wright un script Ruby que todavía está en ciernes. Tengo problemas para entender las fechas julianas de varias partes.

Una cosa que está clara es que debes elegir el tiempo de tránsito solar exacto. Luego reste y agregue semi_diurnal_arc = acos (cos_omega) basado en según su latitud y la declinación solar. Oh! Y asegúrese de incluir el centro solar y la refracción de la tierra. Parece que esta tierra es bastante maga.

+0

Me olvidé de esto. Utiliza una biblioteca bastante buena que puedes encontrar en línea. Explore el código en busca de pistas. http://www.planetsourcecode.com/vb/scripts/ShowCode.asp?txtCodeId=8399&lngWId=10 –

1

Necesita una fórmula que incluya la ecuación del tiempo para permitir la órbita excéntrica del sistema de la Luna de la Tierra alrededor del sol. Necesita utilizar coordenadas con puntos de referencia adecuados, como WGS84 o NAD27, o algo así. Debe utilizar el calendario JULIAN y no el que usamos a diario para obtener estos tiempos correctos. No es algo fácil de adivinar en un segundo de tiempo. Me gustaría tener la hora en mi ubicación donde la longitud de la sombra es igual a la altura que sea. esto debería suceder dos veces por día cuando el sol se eleva 60 grados sobre el horizonte antes y después del mediodía. Además, por lo que yo entiendo, solo necesitas agregar exactamente un día por año para obtener tiempo sidéreo, así que si quieres aumentar tu frecuencia de reloj X 366.25/365.25, ¿ahora podrías tener un reloj sideral en lugar de un reloj civil? "MATEMÁTICAS es el IDIOMA en el que alguien poderoso ha escrito el universo"

1

Otra buena implementación de JS es suncalc.

El número de líneas de código es manejable, por lo que la transferencia a otros idiomas (C#) es ciertamente posible.

2

He hecho un script Python rápida de hacerlo: SunriseSunsetCalculator

todavía tengo que envuelve dentro de una clase pero puede ser útil para los demás.


Editar: El código abierto es impresionante, ya que comete el guión básico, alguien lo envolvió en un módulo y otro añadió una interfaz CLI! ¡Gracias a mbideau y nfischer por sus contribuciones!

4

La respuesta aceptada para esta era una implementación de JavaScript, que no se ajustaba a mi solicitud porque tenía que hacer el cálculo en C#.

He utilizado este código de C#: http://wiki.crowe.co.nz/Calculate%20Sunrise%2fSunset.ashx, que he validado frente a la hora de salida/puesta del sol aquí: http://www.timeanddate.com/astronomy/.

Si redondeo los segundos al minuto más cercano, los tiempos de salida y puesta del sol de la implementación de C# coinciden con los valores correspondientes que se muestran en timeanddate.com, incluidos los casos de ahorro de luz diurna. Sin embargo, el código es un poco abrumador (a menos que también desee datos de la fase lunar), por lo que lo refacturaré para que haga específicamente lo que necesito ahora, los números son correctos.

+1

Este me funcionó después de probar muchos ejemplos en la red. Pude convertir a VB en línea sin problemas. Le da el año 9999 si está en los círculos árticos en invierno, pero solo da un paso atrás un día o hacia adelante hasta que obtenga una respuesta que no sea 9999 y listo. – bendecko

1

Si prefiere un servicio externo podría utilizar este agradable y libre de API de la salida del sol y puesta del sol: http://sunrise-sunset.org/api

He estado usando durante varios proyectos y funciona muy bien, los datos parece ser muy precisa. Sólo hacer una solicitud GET HTTP a http://api.sunrise-sunset.org/json

parámetros aceptados:

  • Lat: Latitud en grados decimales. Necesario.
  • lng: Longitud en grados decimales. Necesario.
  • fecha: Fecha en formato AAAA-MM-DD. También acepta otros formatos de fecha e incluso formatos de fecha relativos. Si no está presente, la fecha predeterminada es la fecha actual. Opcional.
  • devolución de llamada: nombre de la función de devolución de llamada para respuesta JSONP. Opcional.
  • formateado: 0 o 1 (1 es el valor predeterminado). Los valores de tiempo en respuesta se expresarán siguiendo ISO 8601 y day_length se expresará en segundos. Opcional.

La respuesta incluye los horarios de salida y puesta del sol, así como los tiempos de penumbra.

+1

Si bien este enlace puede responder la pregunta, es mejor incluir las partes esenciales de la respuesta aquí y proporcionar el enlace de referencia. Las respuestas de solo enlace pueden dejar de ser válidas si la página vinculada cambia. –

+1

Gracias por su comentario Ian. Edité mi respuesta para mejorarla. –

1

versión VB.Net de la respuesta de dotsa, que también puede determinar zonas horarias de forma automática.

salida (comprobado por ver el atardecer de esta noche):

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 

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 
0

Sí dejar de fumar unos pocos .

Algunos enlaces para patrones.

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

y esto fue un proyecto que hice para el código fuente planeta hace mucho tiempo pero por suerte he guardado en otro lugar, porque ese sitio los datos perdidos.

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

utiliza este Gist más

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

Ahora, para una breve explicación de la técnica de hacer eso.

Lo primero para cualquier día que necesite verdadero mediodía solar o tránsito para su ubicación.

Eso toma en cuenta su longitud local. Se puede convertir en un tiempo dividiéndolo por 15.

Eso es cuanto tiempo más tarde pasará de Zulu zone time o zero longitude.

Eso comienza a las 12:00 p. M. O al mediodía.

Y en su tiempo calculado a partir de la longitud.

Ahora la parte difícil. Necesitas una forma de calcular la ecuación del tiempo.

Esa es una diferencia horaria causada por la inclinación de la Tierra y su órbita alrededor del Sol.

Esto le dará una idea ... https://en.wikipedia.org/wiki/Equation_of_time

Pero tienen una fórmula que es mucho más fácil ....https://en.wikipedia.org/wiki/Sunrise_equation

Este tipo tiene algunos libros que mucha gente va o compra. :-D https://en.wikipedia.org/wiki/Jean_Meeus

Use su primer cálculo para su tránsito solar media y calcular un JDN ... https://en.wikipedia.org/wiki/Julian_day

Esto es utilizada por todas las fórmulas del ángulo como una vez en el siglo Julian https://en.wikipedia.org/wiki/Julian_year_(astronomy)

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

es básicamente JDN menos la época tales como J2000 o 2.451.545,0 todo dividido por 36.525,0 para darle el siglo Julian o t que se usa para la mayoría de las fórmulas que tienen t como parámetro. A veces se usa Julian milenios. En ese caso es 3652500.0

El truco está en encontrar esas fórmulas angulares que te ayudan a resolver la ecuación del tiempo.

Luego obtiene su verdadero tránsito solar y resta el medio día o agrega el medio día de luz solar para su ubicación. Encontrarás a quienes te rodean en las respuestas y el software.

Una vez que tenga algo en marcha, puede consultarlo en la búsqueda de los tiempos o las calculadoras en línea.

Espero que esto sea suficiente para ponerlo en marcha. Hay bibliotecas por todos lados pero no es tan difícil hacer la tuya. Lo hice, pero está en Ruby. Podría ser útil .... https://github.com/DouglasAllen/gem-equationoftime

buena suerte!

2

Sé que este post es viejo, pero por si alguien todavía está buscando ...

CoordinateSharp está disponible como un paquete Nuget. Es un paquete independiente que puede manejar tanto el sol como la luna. Es preciso en unos minutos.

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

Nota:

Asume DateTime siempre están en GMT.

Por último, es posible que deba hacer referencia a los objetos celestes Sun/Moon .Condition si una fecha devuelve nulo. Esto ocurre cuando el sol está arriba/abajo todo el día.

1

He probado este paquete nuget en UWP.

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

La documentación es un poco rara, y es aquí:

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

Puede utilizar esto para conseguir la salida del sol, dado

la = latitud; y lo = longitud; para su área:

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

Se puede instalar en Visual Studio usando el gestor PM

Install-Package SolarCalculator -Version 2.0.2 

o buscando SolarCalculator en la biblioteca de Visual Studio "Administrar paquetes NuGet".