在我的C应用程序中,我想计算给定日期,纬度和经度的日出/日落时间。我一直在网上搜索,但我找不到工作样本。
我试图实现这个示例: http://souptonuts.sourceforge.net/code/sunrise.c.html
但这个样本没有正常工作。
是否有一个简单的C源代码或方法,我可以在我的应用程序中轻松实现?
修改:
我在这个link上实现了代码,但它给了我错误的日落/日出值。我也尝试了Saul的链接here,但它也给了我错误的结果。
我有41N,28E的位置。当我尝试这些代码时,两个样本都说日出值大约是10:13而日落是23:24。但正确的值是06:06,20:13
我无法理解这个问题。
答案 0 :(得分:8)
在给定日期,纬度和经度的情况下,计算sunrise / sunset time的十个简单步骤
首先计算一年中的某一天
N1 =楼层(275 *月/ 9) N2 =楼层((月+ 9)/ 12) N3 =(1 +楼层((年 - 4 *楼(年/ 4)+ 2)/ 3)) N = N1 - (N2 * N3)+天 - 30
将经度转换为小时值并计算大致时间
lngHour =经度/ 15
如果需要上升时间: t = N +((6 - lngHour)/ 24) 如果需要设定时间: t = N +((18-lngHour)/ 24)
计算太阳的平均异常值
M =(0.9856 * t) - 3.289
计算太阳的真实经度
L = M +(1.916 * sin(M))+(0.020 * sin(2 * M))+ 282.634 注意:L可能需要通过添加/减去360来调整到[0,360]范围
5a上。计算太阳的正确提升
RA = atan(0.91764 * tan(L))
NOTE: RA potentially needs to be adjusted into the range [0,360) by adding/subtracting 360
5b中。右提升值需要与L
在同一象限Lquadrant = (floor( L/90)) * 90
RAquadrant = (floor(RA/90)) * 90
RA = RA + (Lquadrant - RAquadrant)
图5c。正确的提升值需要转换成小时
RA = RA / 15
计算太阳的赤纬
sinDec = 0.39782 * sin(L) cosDec = cos(asin(sinDec))
7a中。计算太阳的当地小时角
cosH = (cos(zenith) - (sinDec * sin(latitude))) / (cosDec * cos(latitude))
if (cosH > 1)
the sun never rises on this location (on the specified date)
if (cosH < -1)
the sun never sets on this location (on the specified date)
7b中。完成计算H并转换成小时
if if rising time is desired:
H = 360 - acos(cosH)
if setting time is desired:
H = acos(cosH)
H = H / 15
计算上升/设置的本地平均时间
T = H + RA - (0.06571 * t) - 6.622
调整回UTC
UT = T - lngHour 注意:UT可能需要通过添加/减去24来调整到[0,24]范围
将UT值转换为纬度/经度的本地时区
localT = UT + localOffset
答案 1 :(得分:5)
答案 2 :(得分:2)
有一个c解决方案,其中包含日出/设置的目标c包装:https://github.com/berkley/ObjectiveCUtil
答案 3 :(得分:2)
使用这个guide(由@BenjaminMonate首次发布,我假设是@Geetha使用的那个),我构建了这个C函数,它似乎正常工作。
#include <math.h>
#define PI 3.1415926
#define ZENITH -.83
float calculateSunrise(int year,int month,int day,float lat, float lng,int localOffset, int daylightSavings) {
/*
localOffset will be <0 for western hemisphere and >0 for eastern hemisphere
daylightSavings should be 1 if it is in effect during the summer otherwise it should be 0
*/
//1. first calculate the day of the year
float N1 = floor(275 * month / 9);
float N2 = floor((month + 9) / 12);
float N3 = (1 + floor((year - 4 * floor(year / 4) + 2) / 3));
float N = N1 - (N2 * N3) + day - 30;
//2. convert the longitude to hour value and calculate an approximate time
float lngHour = lng / 15.0;
float t = N + ((6 - lngHour) / 24); //if rising time is desired:
//float t = N + ((18 - lngHour) / 24) //if setting time is desired:
//3. calculate the Sun's mean anomaly
float M = (0.9856 * t) - 3.289;
//4. calculate the Sun's true longitude
float L = fmod(M + (1.916 * sin((PI/180)*M)) + (0.020 * sin(2 *(PI/180) * M)) + 282.634,360.0);
//5a. calculate the Sun's right ascension
float RA = fmod(180/PI*atan(0.91764 * tan((PI/180)*L)),360.0);
//5b. right ascension value needs to be in the same quadrant as L
float Lquadrant = floor( L/90) * 90;
float RAquadrant = floor(RA/90) * 90;
RA = RA + (Lquadrant - RAquadrant);
//5c. right ascension value needs to be converted into hours
RA = RA / 15;
//6. calculate the Sun's declination
float sinDec = 0.39782 * sin((PI/180)*L);
float cosDec = cos(asin(sinDec));
//7a. calculate the Sun's local hour angle
float cosH = (sin((PI/180)*ZENITH) - (sinDec * sin((PI/180)*lat))) / (cosDec * cos((PI/180)*lat));
/*
if (cosH > 1)
the sun never rises on this location (on the specified date)
if (cosH < -1)
the sun never sets on this location (on the specified date)
*/
//7b. finish calculating H and convert into hours
float H = 360 - (180/PI)*acos(cosH); // if if rising time is desired:
//float H = acos(cosH) // if setting time is desired:
H = H / 15;
//8. calculate local mean time of rising/setting
float T = H + RA - (0.06571 * t) - 6.622;
//9. adjust back to UTC
float UT = fmod(T - lngHour,24.0);
//10. convert UT value to local time zone of latitude/longitude
return UT + localOffset + daylightSavings;
}
void printSunrise() {
float localT = calculateSunrise(/*args*/);
double hours;
float minutes = modf(localT,&hours)*60;
printf("%.0f:%.0f",hours,minutes);
}
答案 4 :(得分:2)
干杯 马立克
答案 5 :(得分:2)
也许试试这段代码。它经过测试和运作。 希望你喜欢它......
#include "stdafx.h"
#include <iostream>
#include <math.h>
#include <time.h>
using namespace std;
//STANDARD CONSTANTS
double pi = 3.1415926535; // Pi
double solarConst = 1367; // solar constant W.m-2
// Function to convert radian to hours
double RadToHours (double tmp)
{
//double pi = 3.1415926535; // Pi
return (tmp * 12 / pi);
}
// Function to convert hours to radians
double HoursToRads (double tmp)
{
//double pi = 3.1415926535; // Pi
return (tmp * pi / 12);
}
// Function to calculate the angle of the day
double AngleOfDay (int day, // number of the day
int month, // number of the month
int year // year
)
{ // local vars
int i, leap;
int numOfDays = 0; // number of Day 13 Nov=317
int numOfDaysofMonths[12] = {0,31,28,31,30,31,30,31,31,30,31,30}; // Number of days per month
int AllYearDays; // Total number of days in a year 365 or 366
double DayAngle; // angle of the day (radian)
//double pi = 3.1415926535; // Pi
// leap year ??
leap = 0;
if ((year % 400)==0)
{ AllYearDays = 366;
leap = 1;
}
else if ((year % 100)==0) AllYearDays = 365;
else if ((year % 4)==0)
{ AllYearDays = 366;
leap = 1;
}
else AllYearDays = 365;
// calculate number of day
for (i=0;i<month;i++) numOfDays += numOfDaysofMonths[i];
if ( (month > 2) && leap) numOfDays++;
numOfDays += day;
// calculate angle of day
DayAngle = (2*pi*(numOfDays-1)) / AllYearDays;
return DayAngle;
}
// Function to calculate declination - in radian
double Declination (double DayAngle // angle day in radian
)
{
double SolarDeclination;
// Solar declination (radian)
SolarDeclination = 0.006918
- 0.399912 * cos (DayAngle)
+ 0.070257 * sin (DayAngle)
- 0.006758 * cos (2*DayAngle)
+ 0.000907 * sin (2*DayAngle)
- 0.002697 * cos (3*DayAngle)
+ 0.00148 * sin (3*DayAngle);
return SolarDeclination;
}
// Function to calculate Equation of time ( et = TSV - TU )
double EqOfTime (double DayAngle // angle day (radian)
)
{
double et;
// Equation of time (radian)
et = 0.000075
+ 0.001868 * cos (DayAngle)
- 0.032077 * sin (DayAngle)
- 0.014615 * cos (2*DayAngle)
- 0.04089 * sin (2*DayAngle);
// Equation of time in hours
et = RadToHours(et);
return et;
}
// Calculation of the duration of the day in radian
double DayDurationRadian (double _declination, // _declination in radian
double lat // latitude in radian
)
{
double dayDurationj;
dayDurationj = 2 * acos( -tan(lat) * tan(_declination) );
return dayDurationj;
}
// Function to calculate Day duration in Hours
double DayDuratInHours (double _declination // _declination in radian
, double lat // latitude in radian
)
{
double dayDurationj;
dayDurationj = DayDurationRadian(_declination, lat);
dayDurationj = RadToHours(dayDurationj);
return dayDurationj;
}
// Function to calculate the times TSV-UTC
double Tsv_Tu (double rlong // longitude en radian positive a l est.
,double eqOfTime // Equation of times en heure
)
{
double diffUTC_TSV; double pi = 3.1415926535; // Pi
// diffUTC_TSV Solar time as a function of longitude and the eqation of time
diffUTC_TSV = rlong * (12 / pi) + eqOfTime;
// difference with local time
return diffUTC_TSV;
}
// Calculations of the orbital excentricity
double Excentricity(int day,
int month,
int year)
{
double dayAngleRad, E0;
// calculate the angle of day in radian
dayAngleRad = AngleOfDay(day, month, year);
// calculate the excentricity
E0 = 1.000110 + 0.034221 * cos(dayAngleRad)
+ 0.001280 * sin(dayAngleRad)
+0.000719 * cos(2*dayAngleRad)
+0.000077 * sin(2*dayAngleRad);
return E0;
}
// Calculate the theoretical energy flux for the day radiation
double TheoreticRadiation(int day, int month, int year,
double lat // Latitude in radian !
)
{
double RGth; // Theoretical radiation
double decli; // Declination
double E0;
double sunriseHourAngle; // Hour angle of sunset
// Calculation of the declination in radian
decli = Declination (AngleOfDay(day, month, year));
// Calcuate excentricity
E0 = Excentricity(day, month, year);
// Calculate hour angle in radian
sunriseHourAngle = DayDurationRadian(decli, lat) / 2;
// Calculate Theoretical radiation en W.m-2
RGth = solarConst * E0 * (cos(decli)*cos(lat)*sin(sunriseHourAngle)/sunriseHourAngle + sin(decli)*sin(lat));
return RGth;
}
// Function to calculate decimal hour of sunrise: result in local hour
double CalclulateSunriseLocalTime(int day,
int month,
int year,
double rlong,
double rlat)
{
// local variables
int h1, h2;
time_t hour_machine;
struct tm *local_hour, *gmt_hour;
double result;
// Calculate the angle of the day
double DayAngle = AngleOfDay(day, month, year);
// Declination
double SolarDeclination = Declination(DayAngle);
// Equation of times
double eth = EqOfTime(DayAngle);
// True solar time
double diffUTC_TSV = Tsv_Tu(rlong,eth);
// Day duration
double dayDurationj = DayDuratInHours(SolarDeclination,rlat);
// local time adjust
time( &hour_machine ); // Get time as long integer.
gmt_hour = gmtime( &hour_machine );
h1 = gmt_hour->tm_hour;
local_hour = localtime( &hour_machine ); // local time.
h2 = local_hour->tm_hour;
// final result
result = 12 - fabs(dayDurationj / 2) - diffUTC_TSV + h2-h1;
return result;
}
// Function to calculate decimal hour of sunset: result in local hour
double CalculateSunsetLocalTime(int day,
int month,
int year,
double rlong,
double rlat)
{
// local variables
int h1, h2;
time_t hour_machine;
struct tm *local_hour, *gmt_hour;
double result;
// Calculate the angle of the day
double DayAngle = AngleOfDay(day, month, year);
// Declination
double SolarDeclination = Declination(DayAngle);
// Equation of times
double eth = EqOfTime(DayAngle);
// True solar time
double diffUTC_TSV = Tsv_Tu(rlong,eth);
// Day duration
double dayDurationj = DayDuratInHours(SolarDeclination,rlat);
// local time adjust
time( &hour_machine ); // Get time as long integer.
gmt_hour = gmtime( &hour_machine );
h1 = gmt_hour->tm_hour;
local_hour = localtime( &hour_machine ); // local time.
h2 = local_hour->tm_hour;
// resultat
result = 12 + fabs(dayDurationj / 2) - diffUTC_TSV + h2-h1;
return result;
}
// Function to calculate decimal hour of sunrise: result universal time
double CalculateSunriseUniversalTime(int day,
int month,
int year,
double rlong,
double rlat)
{
double result;
// Calculate the angle of the day
double DayAngle = AngleOfDay(day, month, year);
// Declination
double SolarDeclination = Declination(DayAngle);
// Equation of times
double eth = EqOfTime(DayAngle);
// True solar time
double diffUTC_TSV = Tsv_Tu(rlong,eth);
// Day duration
double dayDurationj = DayDuratInHours(SolarDeclination,rlat);
// resultat
result = 12 - fabs(dayDurationj / 2) - diffUTC_TSV;
return result;
}
// Function to calculate decimal hour of sunset: result in universal time
double CalculateSunsetUniversalTime(int day,
int month,
int year,
double rlong,
double rlat)
{
double result;
// Calculate the angle of the day
double DayAngle = AngleOfDay(day, month, year);
// Declination
double SolarDeclination = Declination(DayAngle);
// Equation of times
double eth = EqOfTime(DayAngle);
// True solar time
double diffUTC_TSV = Tsv_Tu(rlong,eth);
// Day duration
double dayDurationj = DayDuratInHours(SolarDeclination,rlat);
// resultat
result = 12 + fabs(dayDurationj / 2) - diffUTC_TSV;
return result;
}
// Function to calculate the height of the sun in radians the day to day j and hour TU
double SolarHeight (int tu, // universal times (0,1,2,.....,23)
int day,
int month,
int year,
double lat, // latitude in radian
double rlong // longitude in radian
)
{
// local variables
double pi = 3.1415926535; // Pi
double result, tsvh;
// angle of the day
double DayAngle = AngleOfDay(day, month, year);
// _declination
double decli = Declination(DayAngle);
// eq of time
double eq = EqOfTime(DayAngle);
// calculate the tsvh with rlong positiv for the east and negative for the west
tsvh = tu + rlong*180/(15*pi) + eq;
// hour angle per hour
double ah = acos( -cos((pi/12)*tsvh) );
// final result
result = asin( sin(lat)*sin(decli) + cos(lat)*cos(decli)*cos(ah) );
return result;
}
///////////EXTRA FUNCTIONS/////////////////////////////
//Julian day conversion for days calculations
//Explanation for this sick formula...for the curious guys...
//http://www.cs.utsa.edu/~cs1063/projects/Spring2011/Project1/jdn-explanation.html
int julian(int year, int month, int day) {
int a = (14 - month) / 12;
int y = year + 4800 - a;
int m = month + 12 * a - 3;
if (year > 1582 || (year == 1582 && month > 10) || (year == 1582 && month == 10 && day >= 15))
return day + (153 * m + 2) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 32045;
else
return day + (153 * m + 2) / 5 + 365 * y + y / 4 - 32083;
}
int _tmain(int argc, _TCHAR* argv[])
{
int day = 14;
int month = 11;
int year = 2013;
double lat = 39.38;
double lon = 22.75;
double rlat = 39.38 * pi/180;
double rlong = 22.75 * pi/180;
double _AngleOfDay = AngleOfDay ( day , month , year );
cout << "Angle of day: " << _AngleOfDay << "\n";
double _Declinaison = Declination (_AngleOfDay);
cout << "Declination (Delta): " << _Declinaison << "\n";
double _EqOfTime = EqOfTime (_AngleOfDay);
cout << "Declination (Delta): " << _EqOfTime << "\n";
double _DayDuratInHours = DayDuratInHours (_Declinaison, rlat);
cout << "Day duration: " << _DayDuratInHours << "\n";
double _Excentricity = Excentricity(day, month, year);
cout << "Excentricity: " << _Excentricity << "\n";
double _TheoreticRadiation = TheoreticRadiation(day, month, year, rlat);
cout << "Theoretical radiation: " << _TheoreticRadiation << "\n";
double _CalclulateSunriseLocalTime = CalclulateSunriseLocalTime
(day, month, year, rlong, rlat);
cout << "Sunrise Local Time: " << _CalclulateSunriseLocalTime << "\n";
double _CalculateSunsetLocalTime = CalculateSunsetLocalTime
(day, month, year, rlong, rlat);
cout << "Sunrise Local Time: " << _CalculateSunsetLocalTime << "\n";
return 0;
}
答案 6 :(得分:1)
纯C
实施显然很少,但如果您愿意从C++
或C#
移植,那么有几种选择:
答案 7 :(得分:1)
示例代码似乎在VC ++ 2010中有一些小的改动:
#include <sys/time.h>
行。#define _USE_MATH_DEFINES
,以便定义M_PI。%T
来电中的两个strftime()
更改为%X
。现在您有一个工作示例,您可以调试工作版本和您的版本,以查看计算开始不同的地方并缩小问题范围。无论是单步执行程序还是自由使用临时printf()
调用,就像样本一样。
如果您需要特定帮助,则必须发布您的代码(指向整个文件的链接或您需要帮助的特定代码段)。
答案 8 :(得分:1)
我将Tomoyose的C代码移植到C#。虽然需要手动补偿,但由于与在线资源的差异大约为4分钟,因此工作正常。这可能是由于日落或上升的构成存在差异,但正式情况下应该是当太阳从它下方触及地平线时。我希望细节隐藏在某个地方的常数参数中 - 超出我的范围,尝试正确的修复。如果其他人管理它,我想知道; - )
它使用NodaTime,这是Jon Skeet对Java JodaTime的实现。 NodaTime可以在nuGet中找到。
using System;
using NodaTime;
namespace YourNamespaceHere
{
public static class MySunset
{
// Based on Tomoyose's
// http://stackoverflow.com/questions/7064531/sunrise-sunset-times-in-c
private static DateTimeZone mUtcZone = DateTimeZoneProviders.Tzdb["Etc/UTC"];
private static int mSecondsInDay = 24 * 60 * 60;
// Convert radian to hours
private static double RadiansToHours(double radians)
{
return (radians * 12.0 / Math.PI);
}
// Convert hours to radians
private static double HoursToRadians(double hours)
{
return (hours * Math.PI / 12.0);
}
// Calculate the angle of the day
private static double AngleOfDay(int year, int month, int day)
{
DateTime date = new DateTime(year, month, day);
int daysInYear = DateTime.IsLeapYear(year) ? 366 : 365;
// Return angle of day in radians
return (2.0 * Math.PI * ((double)date.DayOfYear - 1.0)) / (double)daysInYear;
}
// Calculate declination in radians
private static double SolarDeclination(double angleOfDayRadians)
{
// Return solar declination in radians
return 0.006918
- 0.399912 * Math.Cos(angleOfDayRadians)
+ 0.070257 * Math.Sin(angleOfDayRadians)
- 0.006758 * Math.Cos(2.0 * angleOfDayRadians)
+ 0.000907 * Math.Sin(2.0 * angleOfDayRadians)
- 0.002697 * Math.Cos(3.0 * angleOfDayRadians)
+ 0.00148 * Math.Sin(3.0 * angleOfDayRadians);
}
// Calculate Equation of time ( eot = TSV - TU )
private static double EquationOfTime(double angleOfDayRadians)
{
// Equation of time (radians)
double et = 0.000075
+ 0.001868 * Math.Cos(angleOfDayRadians)
- 0.032077 * Math.Sin(angleOfDayRadians)
- 0.014615 * Math.Cos(2.0 * angleOfDayRadians)
- 0.04089 * Math.Sin(2.0 * angleOfDayRadians);
// Return equation-of-time in hours
return RadiansToHours(et);
}
// Calculate the duration of the day in radians
private static double DayDurationRadians(double declinationRadians, double latitudeRadians)
{
return 2.0 * Math.Acos(-Math.Tan(latitudeRadians) * Math.Tan(declinationRadians));
}
// Calculate day duration in hours
private static double DayDurationHours(double declinationRadians, double latitudeRadians)
{
return RadiansToHours(
DayDurationRadians(declinationRadians, latitudeRadians)
);
}
// Calculate the times TSV-UTC
private static double Tsv_Tu(double longitudeRadians, double equationOfTime)
{
// Solar time as a function of longitude and the equation of time
return longitudeRadians * (12.0 / Math.PI) + equationOfTime;
}
private static void GetDayParameters(int year, int month, int day, double latitude, double longitude,
out double dayDuration, out double diffUTC_TSV)
{
double latitudeRadians = latitude * Math.PI / 180.0;
double longitudeRadians = longitude * Math.PI / 180.0;
// Calculate the angle of the day
double dayAngle = AngleOfDay(year, month, day);
// Declination
double solarDeclination = SolarDeclination(dayAngle);
// Equation of times
double equationOfTime = EquationOfTime(dayAngle);
// True solar time
diffUTC_TSV = Tsv_Tu(longitudeRadians, equationOfTime);
// Day duration
dayDuration = DayDurationHours(solarDeclination, latitudeRadians);
}
// Calculate decimal UTC hour of sunrise.
private static double CalculateSunriseUTC(int year, int month, int day, double latitude, double longitude)
{
double dayDuration;
double diffUTC_TSV;
GetDayParameters(year, month, day, latitude, longitude, out dayDuration, out diffUTC_TSV);
return 12.0 - Math.Abs(dayDuration / 2.0) - diffUTC_TSV;
}
// Calculate decimal UTC hour of sunset.
private static double CalculateSunsetUTC(int year, int month, int day, double latitude, double longitude)
{
double dayDuration;
double diffUTC_TSV;
GetDayParameters(year, month, day, latitude, longitude, out dayDuration, out diffUTC_TSV);
return 12.0 + Math.Abs(dayDuration / 2.0) - diffUTC_TSV;
}
// Public methods to return sun rise and set times.
public static Tuple<ZonedDateTime, ZonedDateTime> GetSunRiseSet(LocalDate dateAtLocation, DateTimeZone locationZone, double latitude, double longitude)
{
// latitude-longitude must lie within zone of locationZone
// Get UTC rise and set
double dayDuration;
double diffUTC_TSV;
GetDayParameters(dateAtLocation.Year, dateAtLocation.Month, dateAtLocation.Day, latitude, longitude, out dayDuration, out diffUTC_TSV);
double sunriseUtcDecimal = 12.0 - Math.Abs(dayDuration / 2.0) - diffUTC_TSV;
double sunsetUtcDecimal = 12.0 + Math.Abs(dayDuration / 2.0) - diffUTC_TSV;
// Convert decimal UTC to UTC dates
// If a UTC time is negative then it means the date before in the UTC timezone.
// So if negative need to minus 1 day from date and set time as 24 - decimal_time.
LocalDateTime utcRiseLocal;
LocalDateTime utcSetLocal;
if (sunriseUtcDecimal < 0)
{
LocalDate utcDateAdjusted = dateAtLocation.PlusDays(-1);
// Normalize() is important here; otherwise only have access to seconds.
Period utcTimeAdjusted = Period.FromSeconds((long)((24.0 + sunriseUtcDecimal) / 24.0 * mSecondsInDay)).Normalize(); // + a negative
utcRiseLocal = new LocalDateTime(utcDateAdjusted.Year, utcDateAdjusted.Month, utcDateAdjusted.Day,
(int)utcTimeAdjusted.Hours, (int)utcTimeAdjusted.Minutes, (int)utcTimeAdjusted.Seconds);
}
else
{
Period utcTime = Period.FromSeconds((long)(sunriseUtcDecimal / 24.0 * mSecondsInDay)).Normalize();
utcRiseLocal = new LocalDateTime(dateAtLocation.Year, dateAtLocation.Month, dateAtLocation.Day,
(int)utcTime.Hours, (int)utcTime.Minutes, (int)utcTime.Seconds);
}
if (sunsetUtcDecimal < 0) // Maybe not possible?
{
LocalDate utcDateAdjusted = dateAtLocation.PlusDays(-1);
Period utcTimeAdjusted = Period.FromSeconds((long)((24.0 + sunsetUtcDecimal) / 24.0 * mSecondsInDay)).Normalize();
utcSetLocal = new LocalDateTime(utcDateAdjusted.Year, utcDateAdjusted.Month, utcDateAdjusted.Day,
(int)utcTimeAdjusted.Hours, (int)utcTimeAdjusted.Minutes, (int)utcTimeAdjusted.Seconds);
}
else
{
Period utcTime = Period.FromSeconds((long)(sunsetUtcDecimal / 24.0 * mSecondsInDay)).Normalize();
utcSetLocal = new LocalDateTime(dateAtLocation.Year, dateAtLocation.Month, dateAtLocation.Day,
(int)utcTime.Hours, (int)utcTime.Minutes, (int)utcTime.Seconds);
}
// FIX: always about 4 minutes later/earlier than other sources
utcRiseLocal = utcRiseLocal.PlusMinutes(-4);
utcSetLocal = utcSetLocal.PlusMinutes(4);
// Get zoned datetime from UTC local datetimes
ZonedDateTime utcRiseZoned = new LocalDateTime(utcRiseLocal.Year, utcRiseLocal.Month, utcRiseLocal.Day, utcRiseLocal.Hour, utcRiseLocal.Minute, utcRiseLocal.Second).InZoneLeniently(mUtcZone);
ZonedDateTime utcSetZoned = new LocalDateTime(utcSetLocal.Year, utcSetLocal.Month, utcSetLocal.Day, utcSetLocal.Hour, utcSetLocal.Minute, utcSetLocal.Second).InZoneLeniently(mUtcZone);
// Return zoned UTC to zoned local
return new Tuple<ZonedDateTime, ZonedDateTime>
(
new ZonedDateTime(utcRiseZoned.ToInstant(), locationZone),
new ZonedDateTime(utcSetZoned.ToInstant(), locationZone)
);
}
public static Tuple<ZonedDateTime, ZonedDateTime> GetSunRiseSet(int year, int month, int day, string locationZone, double latitude, double longitude)
{
return GetSunRiseSet(new LocalDate(year, month, day), DateTimeZoneProviders.Tzdb[locationZone], latitude, longitude);
}
public static Tuple<ZonedDateTime, ZonedDateTime> GetSunRiseSet(ZonedDateTime zonedDateAtLocation, double latitude, double longitude)
{
return GetSunRiseSet(zonedDateAtLocation.LocalDateTime.Date, zonedDateAtLocation.Zone, latitude, longitude);
}
}
}
答案 9 :(得分:1)
我最近写了一个库来做到这一点。它同时公开了C和Python API-https://github.com/adonmo/daylight
以下是日出时间的计算摘录:
time_t Sunclock::sunrise(time_t date) {
date = date + tz_offset * 60 * 60;
struct tm *t = gmtime(&date);
double _time_of_day = time_of_day(date);
double _julian_day = julian_day(t, _time_of_day, tz_offset);
double _julian_century = julian_century(_julian_day);
double _mean_obliq_ecliptic = mean_obliq_ecliptic(_julian_century);
double _mean_long_sun = mean_long_sun(_julian_century);
double _mean_anom_sun = mean_anom_sun(_julian_century);
double _sun_eq_of_centre = sun_eq_of_centre(_mean_anom_sun, _julian_century);
double _sun_true_long = sun_true_long(_mean_long_sun, _sun_eq_of_centre);
double _obliq_corr = obliq_corr(_mean_obliq_ecliptic, _julian_century);
double _sun_app_long = sun_app_long(_sun_true_long, _julian_century);
double _eccent_earth_orbit = eccent_earth_orbit(_julian_century);
double _var_y = var_y(_obliq_corr);
double _eq_of_time =
eq_of_time(_var_y, _mean_long_sun, _eccent_earth_orbit, _mean_anom_sun);
double _declination = declination(_obliq_corr, _sun_app_long);
double _hour_angle_sunrise = hour_angle_sunrise(_declination);
double noon_decimal_day =
(720 - 4 * longitude - _eq_of_time + tz_offset * 60) / 1440;
double decimal_day = noon_decimal_day - _hour_angle_sunrise * 4 / 1440;
return time_from_decimal_day(date, decimal_day) - tz_offset * 60 * 60;
}
上面的代码应该给出一个大概的概念,但是其他功能的代码以及实际上的完整代码可以从此处读取:https://github.com/adonmo/daylight/blob/master/source/Sunclock.cpp
答案 10 :(得分:0)
这是适应性的,非常准确。您将获得所有组件,然后您需要计算的是Zenith到Horizon角度的反余弦。是的,有更简单的方法但你不想跟踪太阳吗?它有朝一日会派上用场。 http://www.nrel.gov/midc/spa/