SAGA API  v9.7
datetime.cpp
Go to the documentation of this file.
1 
3 // //
4 // SAGA //
5 // //
6 // System for Automated Geoscientific Analyses //
7 // //
8 // Application Programming Interface //
9 // //
10 // Library: SAGA_API //
11 // //
12 //-------------------------------------------------------//
13 // //
14 // datetime.cpp //
15 // //
16 // Copyright (C) 2015 by Olaf Conrad //
17 // //
18 //-------------------------------------------------------//
19 // //
20 // This file is part of 'SAGA - System for Automated //
21 // Geoscientific Analyses'. //
22 // //
23 // This library is free software; you can redistribute //
24 // it and/or modify it under the terms of the GNU Lesser //
25 // General Public License as published by the Free //
26 // Software Foundation, either version 2.1 of the //
27 // License, or (at your option) any later version. //
28 // //
29 // This library is distributed in the hope that it will //
30 // be useful, but WITHOUT ANY WARRANTY; without even the //
31 // implied warranty of MERCHANTABILITY or FITNESS FOR A //
32 // PARTICULAR PURPOSE. See the GNU Lesser General Public //
33 // License for more details. //
34 // //
35 // You should have received a copy of the GNU Lesser //
36 // General Public License along with this program; if //
37 // not, see <http://www.gnu.org/licenses/>. //
38 // //
39 //-------------------------------------------------------//
40 // //
41 // contact: Olaf Conrad //
42 // Institute of Geography //
43 // University of Hamburg //
44 // Germany //
45 // //
46 // e-mail: oconrad@saga-gis.org //
47 // //
49 
50 //---------------------------------------------------------
51 #include <time.h>
52 
53 #include <wx/datetime.h>
54 
55 #include "datetime.h"
56 
57 
59 // //
60 // //
61 // //
63 
64 //---------------------------------------------------------
66 {
67  wxTimeSpan ts((wxLongLong(m_span)));
68 
69  wxString s = !Format.is_Empty() ? ts.Format(Format.c_str()) : ts.Format(wxDefaultTimeSpanFormat);
70 
71  return( CSG_String(&s) );
72 }
73 
74 
76 // //
77 // //
78 // //
80 
81 //---------------------------------------------------------
83 {
84  m_pDateTime = new wxDateTime(wxDateTime::Now());
85 }
86 
87 //---------------------------------------------------------
89 {
90  m_pDateTime = new wxDateTime(*DateTime.m_pDateTime);
91 }
92 
93 //---------------------------------------------------------
95 {
96  m_pDateTime = new wxDateTime(JDN);
97 }
98 
99 //---------------------------------------------------------
101 {
102  m_pDateTime = new wxDateTime(wxDateTime::Now());
103 
104  Set(ISODate);
105 }
106 
107 //---------------------------------------------------------
109 {
110  m_pDateTime = new wxDateTime(Hour, Minute, Second, Millisec);
111 }
112 
113 //---------------------------------------------------------
115 {
116  m_pDateTime = new wxDateTime(Day, (wxDateTime::Month)Month, Year, Hour, Minute, Second, Millisec);
117 }
118 
119 //---------------------------------------------------------
121 {
122  delete(m_pDateTime);
123 }
124 
125 
127 // //
129 
130 //---------------------------------------------------------
132 {
133  m_pDateTime->Set(DateTime.m_pDateTime->GetTm());
134 
135  return( *this );
136 }
137 
138 //---------------------------------------------------------
140 {
141  m_pDateTime->Set(JDN);
142 
143  return( *this );
144 }
145 
146 //---------------------------------------------------------
148 {
149  // 0123456789
150  // YYYY-MM-DD
151 
152  if( ISODate.Length() >= 10 && ISODate[4] == '-' && ISODate[7] == '-' )
153  {
154  int y = ISODate.Left ( 4).asInt();
155  int m = ISODate.Mid (5, 2).asInt();
156  int d = ISODate.Right( 2).asInt();
157 
158  Set((TSG_DateTime)d, (Month)(m - 1), y);
159  }
160 
161  return( *this );
162 }
163 
164 //---------------------------------------------------------
166 {
167  m_pDateTime->Set(Hour, Minute, Second, Millisec);
168 
169  return( *this );
170 }
171 
172 //---------------------------------------------------------
174 {
175  m_pDateTime->Set(Day, (wxDateTime::Month)Month, Year, Hour, Minute, Second, Millisec);
176 
177  return( *this );
178 }
179 
180 //---------------------------------------------------------
182 {
183  m_pDateTime->SetMillisecond(Value);
184 
185  return( *this );
186 }
187 
188 //---------------------------------------------------------
189 CSG_DateTime & CSG_DateTime::Set_Second(unsigned short Value)
190 {
191  m_pDateTime->SetSecond(Value);
192 
193  return( *this );
194 }
195 
196 //---------------------------------------------------------
197 CSG_DateTime & CSG_DateTime::Set_Minute(unsigned short Value)
198 {
199  m_pDateTime->SetMinute(Value);
200 
201  return( *this );
202 }
203 
204 //---------------------------------------------------------
205 CSG_DateTime & CSG_DateTime::Set_Hour(unsigned short Value)
206 {
207  m_pDateTime->SetHour(Value);
208 
209  return( *this );
210 }
211 
213 {
214  m_pDateTime->ResetTime();
215 
216  Value = fmod(Value, 24.0); if( Value < 0.0 ) Value += 24.0;
217 
218  m_pDateTime->SetHour ((wxDateTime::wxDateTime_t)Value); Value = (Value - (wxDateTime::wxDateTime_t)Value) * 60.0;
219  m_pDateTime->SetMinute ((wxDateTime::wxDateTime_t)Value); Value = (Value - (wxDateTime::wxDateTime_t)Value) * 60.0;
220  m_pDateTime->SetSecond ((wxDateTime::wxDateTime_t)Value); Value = (Value - (wxDateTime::wxDateTime_t)Value) * 1000.0;
221  m_pDateTime->SetMillisecond((wxDateTime::wxDateTime_t)Value);
222 
223  return( *this );
224 }
225 
226 //---------------------------------------------------------
227 CSG_DateTime & CSG_DateTime::Set_Day(unsigned short Value)
228 {
229  m_pDateTime->SetDay(Value);
230 
231  return( *this );
232 }
233 
234 //---------------------------------------------------------
235 CSG_DateTime & CSG_DateTime::Set_Month(unsigned short Value)
236 {
237  m_pDateTime->SetMonth((wxDateTime::Month)Value);
238 
239  return( *this );
240 }
241 
242 //---------------------------------------------------------
244 {
245  m_pDateTime->SetYear(Value);
246 
247  return( *this );
248 }
249 
250 //---------------------------------------------------------
252 {
253  m_pDateTime->SetToYearDay(Value);
254 
255  return( *this );
256 }
257 
258 //---------------------------------------------------------
260 {
261  m_pDateTime->SetToCurrent();
262 
263  return( *this );
264 }
265 
266 //---------------------------------------------------------
268 {
269  m_pDateTime->ResetTime();
270 
271  return( *this );
272 }
273 
274 
276 // //
278 
279 //---------------------------------------------------------
281 {
282  return( CSG_DateTime(m_pDateTime->FromUTC(noDST).GetJDN()) );
283 
284 // CSG_DateTime dt; dt.m_pDateTime->Set(m_pDateTime->FromUTC(noDST).GetTm()); return( dt );
285 }
286 
287 //---------------------------------------------------------
289 {
290  return( CSG_DateTime(m_pDateTime->ToUTC(noDST).GetJDN()) );
291 }
292 
293 //---------------------------------------------------------
295 {
296  m_pDateTime->MakeUTC(noDST);
297 
298  return( *this );
299 }
300 
301 //---------------------------------------------------------
302 bool CSG_DateTime::is_DST(void) const
303 {
304  return( m_pDateTime->IsDST() != 0 );
305 }
306 
307 
309 // //
311 
312 //---------------------------------------------------------
314 {
315  return( m_pDateTime->GetValue().GetValue() );
316 }
317 
318 
320 // //
322 
323 //---------------------------------------------------------
325 {
326  CSG_DateTime dt(*this);
327 
328  return( dt.Add(TimeSpan) );
329 }
330 
332 {
333  m_pDateTime->Add(wxTimeSpan((wxLongLong)TimeSpan.m_span));
334 
335  return( *this);
336 }
337 
338 //---------------------------------------------------------
340 {
341  CSG_DateTime dt(*this);
342 
343  return( dt.Subtract(TimeSpan) );
344 }
345 
347 {
348  m_pDateTime->Subtract(wxTimeSpan((wxLongLong)TimeSpan.m_span));
349 
350  return( *this);
351 }
352 
353 //---------------------------------------------------------
355 {
356  CSG_TimeSpan Span((sLong)m_pDateTime->Subtract(*DateTime.m_pDateTime).GetValue().GetValue());
357 
358  return( Span );
359 }
360 
361 
363 // //
365 
366 //---------------------------------------------------------
367 bool CSG_DateTime::is_Valid(void) const
368 {
369  return( m_pDateTime->IsValid() );
370 }
371 
372 //---------------------------------------------------------
373 unsigned short CSG_DateTime::Get_Millisecond(void) const { return( m_pDateTime->GetMillisecond() ); }
374 unsigned short CSG_DateTime::Get_Second (void) const { return( m_pDateTime->GetSecond () ); }
375 unsigned short CSG_DateTime::Get_Minute (void) const { return( m_pDateTime->GetMinute () ); }
376 unsigned short CSG_DateTime::Get_Hour (void) const { return( m_pDateTime->GetHour () ); }
377 unsigned short CSG_DateTime::Get_Day (void) const { return( m_pDateTime->GetDay () ); }
378 
380 {
381  return( (Month)m_pDateTime->GetMonth() );
382 }
383 
384 int CSG_DateTime::Get_Year(void) const
385 {
386  return( m_pDateTime->GetYear() );
387 }
388 
389 //---------------------------------------------------------
390 unsigned short CSG_DateTime::Get_DayOfYear(void) const
391 {
392  return( m_pDateTime->GetDayOfYear() );
393 }
394 
396 {
397  return( (WeekDay)m_pDateTime->GetWeekDay() );
398 }
399 
401 {
402  return( (TSG_DateTime)m_pDateTime->GetWeekOfMonth() );
403 }
404 
406 {
407  return( (TSG_DateTime)m_pDateTime->GetWeekOfYear() );
408 }
409 
410 //---------------------------------------------------------
411 double CSG_DateTime::Get_JDN(void) const
412 {
413  return( m_pDateTime->GetJDN() );
414 }
415 
416 double CSG_DateTime::Get_MJD(void) const
417 {
418  return( m_pDateTime->GetMJD() );
419 }
420 
421 
423 // //
425 
426 //---------------------------------------------------------
427 bool CSG_DateTime::is_EarlierThan (const CSG_DateTime &DateTime) const { return( m_pDateTime->IsEarlierThan(*DateTime.m_pDateTime) ); }
428 bool CSG_DateTime::is_EqualTo (const CSG_DateTime &DateTime) const { return( m_pDateTime->IsEqualTo (*DateTime.m_pDateTime) ); }
429 bool CSG_DateTime::is_LaterThan (const CSG_DateTime &DateTime) const { return( m_pDateTime->IsLaterThan (*DateTime.m_pDateTime) ); }
430 
431 //---------------------------------------------------------
432 bool CSG_DateTime::is_SameDate (const CSG_DateTime &DateTime) const { return( m_pDateTime->IsSameDate (*DateTime.m_pDateTime) ); }
433 bool CSG_DateTime::is_SameTime (const CSG_DateTime &DateTime) const { return( m_pDateTime->IsSameTime (*DateTime.m_pDateTime) ); }
434 
435 //---------------------------------------------------------
436 bool CSG_DateTime::is_Between (const CSG_DateTime &t1, const CSG_DateTime &t2) const { return( m_pDateTime->IsBetween (*t1.m_pDateTime, *t2.m_pDateTime) ); }
437 bool CSG_DateTime::is_StrictlyBetween(const CSG_DateTime &t1, const CSG_DateTime &t2) const { return( m_pDateTime->IsStrictlyBetween(*t1.m_pDateTime, *t2.m_pDateTime) ); }
438 
439 
441 // //
443 
444 //---------------------------------------------------------
446 {
447  wxString s(m_pDateTime->Format(Format.c_str())); CSG_String _s(&s); return( _s );
448 }
449 
451 {
452  wxString s(m_pDateTime->FormatDate()); CSG_String _s(&s); return( _s );
453 }
454 
456 {
457  wxString s(m_pDateTime->FormatTime()); CSG_String _s(&s); return( _s );
458 }
459 
461 {
462  wxString s(m_pDateTime->FormatISODate()); CSG_String _s(&s); return( _s );
463 }
464 
466 {
467  wxString s(m_pDateTime->FormatISOTime()); CSG_String _s(&s); return( _s );
468 }
469 
471 {
472  wxString s(m_pDateTime->FormatISOCombined(sep)); CSG_String _s(&s); return( _s );
473 }
474 
475 //---------------------------------------------------------
477 {
478  wxString::const_iterator end; return( m_pDateTime->ParseDate(date.c_str(), &end) );
479 }
480 
482 {
483  wxString::const_iterator end; return( m_pDateTime->ParseDateTime(datetime.c_str(), &end) );
484 }
485 
486 bool CSG_DateTime::Parse_Format(const CSG_String &date, const CSG_String &format, const CSG_DateTime &dateDef)
487 {
488  wxString::const_iterator end; return( m_pDateTime->ParseFormat(date.c_str(), format.c_str(), *dateDef.m_pDateTime, &end) );
489 }
490 
491 bool CSG_DateTime::Parse_Format(const CSG_String &date, const CSG_String &format)
492 {
493  wxString::const_iterator end; return( m_pDateTime->ParseFormat(date.c_str(), format.c_str(), &end) );
494 }
495 
497 {
498  wxString::const_iterator end; return( m_pDateTime->ParseFormat(date.c_str(), &end) );
499 }
500 
501 //---------------------------------------------------------
502 bool CSG_DateTime::Parse_ISOCombined(const CSG_String &date, char sep)
503 {
504  return( m_pDateTime->ParseISOCombined(date.c_str(), sep) );
505 }
506 
508 {
509  return( m_pDateTime->ParseISODate(date.c_str()) );
510 }
511 
513 {
514  return( m_pDateTime->ParseISOTime(date.c_str()) );
515 }
516 
517 
519 // //
521 
522 //---------------------------------------------------------
524 {
526 
528 
529  return( Now.Get_Day() );
530 }
531 
533 {
534  return( (Month)wxDateTime::GetCurrentMonth() );
535 }
536 
538 {
539  return( wxDateTime::GetCurrentYear() );
540 }
541 
542 //---------------------------------------------------------
544 {
545  wxString s(wxDateTime::GetMonthName ((wxDateTime::Month)month , (wxDateTime::NameFlags)flags)); CSG_String _s(&s); return( _s );
546 }
547 
549 {
550  wxString s(wxDateTime::GetEnglishMonthName ((wxDateTime::Month)month , (wxDateTime::NameFlags)flags)); CSG_String _s(&s); return( _s );
551 }
552 
554 {
555  wxString s(wxDateTime::GetWeekDayName ((wxDateTime::WeekDay)weekday, (wxDateTime::NameFlags)flags)); CSG_String _s(&s); return( _s );
556 }
557 
559 {
560  wxString s(wxDateTime::GetEnglishWeekDayName((wxDateTime::WeekDay)weekday, (wxDateTime::NameFlags)flags)); CSG_String _s(&s); return( _s );
561 }
562 
563 //---------------------------------------------------------
565 {
566  return( (TSG_DateTime)wxDateTime::GetNumberOfDays(year) );
567 }
568 
570 {
571  return( (TSG_DateTime)wxDateTime::GetNumberOfDays((wxDateTime::Month)month, year) );
572 }
573 
574 //---------------------------------------------------------
576 {
577  return( wxDateTime::IsLeapYear(year) );
578 }
579 
580 //---------------------------------------------------------
582 {
583  CSG_DateTime DateTime; *DateTime.m_pDateTime = wxDateTime::Now();
584 
585  return( DateTime );
586 }
587 
588 
590 // //
592 
593 //---------------------------------------------------------
595 {
596  time_t tUnix = Seconds;
597  struct tm t;
598 
599  #ifdef _SAGA_LINUX
600  t = *gmtime(&tUnix);
601  #else
602  gmtime_s(&t, &tUnix);
603  #endif
604 
605  Set(t.tm_mday, (CSG_DateTime::Month)(t.tm_mon), t.tm_year + 1900, t.tm_hour, t.tm_min, t.tm_sec);
606 
607  return( *this );
608 }
609 
610 //---------------------------------------------------------
612 {
613  long d, n;
614  double h;
615 
616  h = 1721424.0 + (Hours - 12.0) / 24.0;
617  d = (long)h; // Truncate to integral day
618  h = h - d + 0.5; // Fractional part of calendar day
619  if( h >= 1.0 ) // Is it really the next calendar day?
620  {
621  h--;
622  d++;
623  }
624 
625  int day, mon, year, hour, min, sec;
626 
627  h = 24.0 * (h);
628  hour = (int)h;
629  h = 60.0 * (h - hour);
630  min = (int)h;
631  h = 60.0 * (h - min);
632  sec = (int)h;
633 
634  d = d + 68569;
635  n = 4 * d / 146097;
636  d = d - (146097 * n + 3) / 4;
637  year = 4000 * (d + 1) / 1461001;
638  d = d - 1461 * year / 4 + 31; // 1461 = 365.25 * 4
639  mon = 80 * d / 2447;
640  day = d - 2447 * mon / 80;
641  d = mon / 11;
642  mon = mon + 2 - 12 * d;
643  year = 100 * (n - 49) + year + d;
644 
645  Set(day, (CSG_DateTime::Month)(mon - 1), year, hour, min, sec);
646 
647  return( *this );
648 }
649 
650 
652 // //
654 
655 //---------------------------------------------------------
657 {
658  CSG_String Choices;
659 
660  Choices.Printf("%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|",
661  _TL("January"), _TL("February"), _TL("March" ), _TL("April" ), _TL("May" ), _TL("June" ),
662  _TL("July" ), _TL("August" ), _TL("September"), _TL("October"), _TL("November"), _TL("December")
663  );
664 
665  return( Choices );
666 }
667 
668 
670 // //
672 
673 //---------------------------------------------------------
677 //---------------------------------------------------------
678 bool SG_JulianDayNumber_To_Date(double JDN, int &y, int &m, int &d)
679 {
680  double Z = floor(JDN + 0.5);
681  double F = JDN + 0.5 - Z;
682  double a = floor((Z - 1867216.25) / 36524.25);
683  double A = Z + 1 + a - floor(a / 4);
684  double B = A + 1524;
685  double C = floor((B - 122.1) / 365.25);
686  double D = floor(365.25 * C);
687  double E = floor((B - D) / 30.6001);
688 
689  d = int(B - D - floor(30.6001 * E) + F);
690 
691  if( E <= 13 )
692  {
693  m = E - 1; y = C - 4716;
694  }
695  else
696  {
697  m = E - 13; y = C - 4715;
698  }
699 
700  return( true );
701 }
702 
703 //---------------------------------------------------------
707 //---------------------------------------------------------
709 {
710  CSG_String Date; int y, m, d;
711 
712  if( SG_JulianDayNumber_To_Date(JDN, y, m, d) )
713  {
714  Date.Printf("%04d-%02d-%02d", y, m, d); // yyyy-mm-dd (ISO 8601)
715  }
716 
717  return( Date );
718 }
719 
720 //---------------------------------------------------------
724 //---------------------------------------------------------
726 {
727  return( SG_JulianDayNumber_To_Date(JDN + 0.5) );
728 }
729 
730 //---------------------------------------------------------
737 //---------------------------------------------------------
738 double SG_Date_To_JulianDayNumber(int Year, int Month, int Day)
739 {
740  if( Month <= 2 ) { Year--; Month += 12; }
741 
742  return( floor(365.25 * (Year + 4716)) + floor(30.6001 * (Month + 1)) + Day + 2. - floor(Year / 100) + floor(Year / 400) - 1524.5 );
743 }
744 
745 //---------------------------------------------------------
751 //---------------------------------------------------------
753 {
754  if( Date.Length() >= 10 )
755  {
756  bool BC = Date[0] == '-';
757 
758  CSG_Strings ymd(SG_String_Tokenize(BC ? Date.AfterFirst('-') : Date, "-./"));
759 
760  if( ymd.Get_Count() >= 3 )
761  {
762  bool inv = ymd[2].Length() == 4;
763 
764  int y = ymd[inv ? 2 : 0].asInt(); if( BC ) { y = -y; }
765  int m = ymd[ 1].asInt(); if( m < 1 ) { m = 1; } else if( m > 12 ) { m = 12; }
766  int d = ymd[inv ? 0 : 2].asInt(); if( d < 1 ) { d = 1; } else if( d > 31 ) { d = 31; }
767 
768  return( SG_Date_To_JulianDayNumber(y, m, d) );
769  }
770  }
771 
772  return( 0. );
773 }
774 
775 
777 // //
779 
780 //---------------------------------------------------------
785 //---------------------------------------------------------
786 int SG_Get_Day_MidOfMonth(int Month, bool bLeapYear)
787 {
788  static const int MidOfMonth[12] =
789  // JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC
790  // 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
791  // 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
792  { 15, 45, 74, 105, 135, 166, 196, 227, 258, 288, 319, 349 };
793 
794  int Day;
795 
796  if( Month < 0 )
797  {
798  Month = (Month % 12) + 12;
799  Day = MidOfMonth[Month] - 365;
800  }
801  else if( Month >= 12 )
802  {
803  Month = (Month % 12);
804  Day = MidOfMonth[Month] + 365;
805  }
806  else
807  {
808  Day = MidOfMonth[Month];
809  }
810 
811  if( bLeapYear && Month > 1 )
812  {
813  Day++;
814  }
815 
816  return( Day );
817 }
818 
819 
821 // //
822 // //
823 // //
825 
826 //---------------------------------------------------------
827 #include "mat_tools.h"
828 
829 //---------------------------------------------------------
836 //---------------------------------------------------------
837 bool SG_Get_Sun_Position(double JDN, double &RA, double &Dec)
838 {
839  double T = (JDN - 2451545.) / 36525.; // Number of Julian centuries since 2000-01-01 at 12 UT (JDN = 2451545.0)
840 
841  double M = 357.52910 + 35999.05030 * T - 0.0001559 * T*T - 0.00000048 * T*T*T; // mean anomaly
842 
843  M *= M_DEG_TO_RAD;
844 
845  double L = (280.46645 + 36000.76983 * T + 0.0003032 * T*T) // mean longitude
846  + ((1.914600 - 0.004817 * T - 0.000014 * T*T) * sin(M)
847  + (0.019993 - 0.000101 * T) * sin(2. * M) + 0.000290 * sin(3. * M)); // true longitude
848 
849  L *= M_DEG_TO_RAD;
850 
851  //-----------------------------------------------------
852  // convert ecliptic longitude to right ascension RA and declination delta
853 
854  static const double Ecliptic_Obliquity = M_DEG_TO_RAD * 23.43929111;
855 
856  double X = cos(L);
857  double Y = cos(Ecliptic_Obliquity) * sin(L);
858  double Z = sin(Ecliptic_Obliquity) * sin(L);
859  double R = sqrt(1. - Z*Z);
860 
861  Dec = atan2(Z, R);
862  RA = 2. * atan2(Y, (X + R));
863 
864  return( true );
865 }
866 
867 //---------------------------------------------------------
868 bool SG_Get_Sun_Position(const CSG_DateTime &Time, double &RA, double &Dec)
869 {
870  return( SG_Get_Sun_Position(Time.Get_JDN(), RA, Dec) );
871 }
872 
873 //---------------------------------------------------------
880 //---------------------------------------------------------
881 bool SG_Get_Sun_Position(double JDN, double Longitude, double Latitude, double &Height, double &Azimuth, bool bRefraction)
882 {
883  //-----------------------------------------------------
884  // 1. Get right ascension RA and declination delta
885 
886  double RA, Dec; SG_Get_Sun_Position(JDN, RA, Dec);
887 
888  //-----------------------------------------------------
889  // 2. compute sidereal time (radians) at Greenwich local sidereal time at longitude (radians)
890 
891  double T = (JDN - 2451545.) / 36525.;
892 
893  double Theta = Longitude + M_DEG_TO_RAD * (280.46061837 + 360.98564736629 * (JDN - 2451545.) + T*T * (0.000387933 - T / 38710000.));
894 
895  double HA = Theta - RA; // compute local hour angle (radians)
896 
897  //-----------------------------------------------------
898  // 3. convert (HA, Dec) to horizon coordinates (height, azimuth) of the observer
899 
900  Height = asin ( sin(Latitude) * sin(Dec) + cos(Latitude) * cos(Dec) * cos(HA));
901  Azimuth = atan2(-sin(HA) * cos(Dec), cos(Latitude) * sin(Dec) - sin(Latitude) * cos(Dec) * cos(HA));
902 // Azimuth = atan2(-sin(HA), cos(Latitude) * tan(Dec) - sin(Latitude) * cos(HA)); // previous formula gives same result but is better because of division by zero effects...
903 
904  if( bRefraction )
905  {
906  double Refraction = SG_Get_Sun_Refraction(Height, true);
907 
908  if( Refraction >= 0. )
909  {
910  Height += Refraction;
911  }
912  }
913 
914  return( Height > 0. );
915 }
916 
917 //---------------------------------------------------------
918 bool SG_Get_Sun_Position(const CSG_DateTime &Time, double Longitude, double Latitude, double &Height, double &Azimuth, bool bRefraction)
919 {
920  return( SG_Get_Sun_Position(Time.Get_JDN(), Longitude, Latitude, Height, Azimuth, bRefraction) );
921 }
922 
923 //---------------------------------------------------------
924 bool SG_Get_Sun_Position(double JDN, double Longitude, double Latitude, CSG_Vector &Position, bool bRefraction)
925 {
926  Position.Create(2); return( SG_Get_Sun_Position(JDN, Longitude, Latitude, Position[0], Position[1], bRefraction) );
927 }
928 
929 //---------------------------------------------------------
930 bool SG_Get_Sun_Position(const CSG_DateTime &Time, double Longitude, double Latitude, CSG_Vector &Position, bool bRefraction)
931 {
932  Position.Create(2); return( SG_Get_Sun_Position(Time.Get_JDN(), Longitude, Latitude, Position[0], Position[1], bRefraction) );
933 }
934 
935 //---------------------------------------------------------
942 //---------------------------------------------------------
943 double SG_Get_Sun_Refraction(double Height, bool bRadians)
944 {
945  // 3.51823 = 1013.25mb / 288K
946 
947  double z = bRadians ? M_RAD_TO_DEG * Height : Height;
948 
949  if( z > -0.766 )
950  {
951  if( z >= 19.225 )
952  {
953  z = 3.51823 * 0.00452 / tan(z * M_DEG_TO_RAD);
954  }
955  else
956  {
957  z = 3.51823 * (0.1594 + z * (0.0196 + 0.00002 * z) ) / (1. + z * (0.505 + 0.0845 * z));
958  }
959 
960  return( bRadians ? M_DEG_TO_RAD * z : z );
961  }
962 
963  return( -1. );
964 }
965 
966 
968 // //
970 
971 //---------------------------------------------------------
972 double SG_Get_Day_Length(int DayOfYear, double Latitude)
973 {
974  double tanLat = tan(Latitude * M_DEG_TO_RAD);
975 
976  double JD = DayOfYear * M_PI_360 / 365.;
977 
978  double SunDec = 0.4093 * sin(JD - 1.405); // solar declination
979 
980  double d = -tanLat * tan(SunDec); // sunset hour angle
981 
982  return( acos(d < -1 ? -1 : d < 1 ? d : 1) * 24. / M_PI );
983 }
984 
985 //---------------------------------------------------------
986 double SG_Get_Day_Length(const CSG_DateTime &Date, double Latitude)
987 {
988  return( SG_Get_Day_Length(Date.Get_DayOfYear(), Latitude) );
989 }
990 
991 
993 // //
994 // //
995 // //
997 
998 //---------------------------------------------------------
SG_Date_To_JulianDayNumber
double SG_Date_To_JulianDayNumber(int Year, int Month, int Day)
Definition: datetime.cpp:738
M_DEG_TO_RAD
#define M_DEG_TO_RAD
Definition: mat_tools.h:109
CSG_DateTime::Parse_Date
bool Parse_Date(const CSG_String &date)
Definition: datetime.cpp:476
CSG_DateTime::Set_Hour
CSG_DateTime & Set_Hour(unsigned short Value)
Definition: datetime.cpp:205
CSG_DateTime::Parse_ISOTime
bool Parse_ISOTime(const CSG_String &date)
Definition: datetime.cpp:512
CSG_DateTime::Set_Millisecond
CSG_DateTime & Set_Millisecond(unsigned short Value)
Definition: datetime.cpp:181
CSG_DateTime::Get_WeekOfMonth
TSG_DateTime Get_WeekOfMonth(void) const
Definition: datetime.cpp:400
CSG_DateTime::Set_Second
CSG_DateTime & Set_Second(unsigned short Value)
Definition: datetime.cpp:189
CSG_String::Printf
int Printf(const char *Format,...)
Definition: api_string.cpp:308
CSG_DateTime::Get_Millisecond
unsigned short Get_Millisecond(void) const
Definition: datetime.cpp:373
_TL
#define _TL(s)
Definition: api_core.h:1507
CSG_DateTime::From_UTC
CSG_DateTime From_UTC(bool noDST=false) const
Definition: datetime.cpp:280
CSG_DateTime::Get_EnglishWeekDayName
static CSG_String Get_EnglishWeekDayName(WeekDay weekday, NameFlags flags=Name_Full)
Definition: datetime.cpp:558
CSG_DateTime::Set_Month
CSG_DateTime & Set_Month(unsigned short Value)
Definition: datetime.cpp:235
SG_Get_Day_MidOfMonth
int SG_Get_Day_MidOfMonth(int Month, bool bLeapYear)
Definition: datetime.cpp:786
CSG_String::Length
size_t Length(void) const
Definition: api_string.cpp:172
CSG_DateTime::Now
static CSG_DateTime Now(void)
Definition: datetime.cpp:581
M_RAD_TO_DEG
#define M_RAD_TO_DEG
Definition: mat_tools.h:108
CSG_DateTime::Get_Current_Month
static Month Get_Current_Month(void)
Definition: datetime.cpp:532
A
#define A
CSG_String::Mid
CSG_String Mid(size_t first, size_t count=0) const
Definition: api_string.cpp:723
SG_Get_Sun_Position
bool SG_Get_Sun_Position(double JDN, double &RA, double &Dec)
Definition: datetime.cpp:837
CSG_DateTime::is_DST
bool is_DST(void) const
Definition: datetime.cpp:302
CSG_DateTime::Parse_ISODate
bool Parse_ISODate(const CSG_String &date)
Definition: datetime.cpp:507
CSG_DateTime::is_SameTime
bool is_SameTime(const CSG_DateTime &DateTime) const
Definition: datetime.cpp:433
CSG_DateTime::Get_Current_Day
static TSG_DateTime Get_Current_Day(void)
Definition: datetime.cpp:523
CSG_DateTime::Make_UTC
CSG_DateTime & Make_UTC(bool noDST=false)
Definition: datetime.cpp:294
CSG_String::asInt
int asInt(void) const
Definition: api_string.cpp:746
CSG_DateTime::NameFlags
NameFlags
Definition: datetime.h:211
C
#define C
CSG_DateTime::is_EarlierThan
bool is_EarlierThan(const CSG_DateTime &DateTime) const
Definition: datetime.cpp:427
CSG_DateTime::Set_Day
CSG_DateTime & Set_Day(unsigned short Value)
Definition: datetime.cpp:227
CSG_DateTime::is_LeapYear
static bool is_LeapYear(int year=Inv_Year)
Definition: datetime.cpp:575
CSG_DateTime::Format_Time
CSG_String Format_Time(void) const
Definition: datetime.cpp:455
CSG_DateTime::Get_Month_Choices
static CSG_String Get_Month_Choices(void)
Definition: datetime.cpp:656
CSG_DateTime::is_Between
bool is_Between(const CSG_DateTime &t1, const CSG_DateTime &t2) const
Definition: datetime.cpp:436
CSG_DateTime::is_EqualTo
bool is_EqualTo(const CSG_DateTime &DateTime) const
Definition: datetime.cpp:428
CSG_TimeSpan
Definition: datetime.h:91
CSG_DateTime::Get_Minute
unsigned short Get_Minute(void) const
Definition: datetime.cpp:375
CSG_DateTime::Set_Minute
CSG_DateTime & Set_Minute(unsigned short Value)
Definition: datetime.cpp:197
CSG_DateTime::Format_ISOTime
CSG_String Format_ISOTime(void) const
Definition: datetime.cpp:465
CSG_DateTime::Get_Year
int Get_Year(void) const
Definition: datetime.cpp:384
CSG_DateTime::To_UTC
CSG_DateTime To_UTC(bool noDST=false) const
Definition: datetime.cpp:288
CSG_DateTime::Set_Year
CSG_DateTime & Set_Year(int Value)
Definition: datetime.cpp:243
CSG_DateTime::Get_Second
unsigned short Get_Second(void) const
Definition: datetime.cpp:374
CSG_DateTime::Get_MJD
double Get_MJD(void) const
Definition: datetime.cpp:416
CSG_DateTime::is_Valid
bool is_Valid(void) const
Definition: datetime.cpp:367
mat_tools.h
CSG_DateTime::Format_ISODate
CSG_String Format_ISODate(void) const
Definition: datetime.cpp:460
CSG_DateTime::Get_Month
Month Get_Month(void) const
Definition: datetime.cpp:379
CSG_DateTime::Get_Current_Year
static int Get_Current_Year(void)
Definition: datetime.cpp:537
CSG_Vector
Definition: mat_tools.h:360
CSG_DateTime::Parse_Format
bool Parse_Format(const CSG_String &date, const CSG_String &format, const CSG_DateTime &dateDef)
Definition: datetime.cpp:486
CSG_DateTime::Set_Unix_Time
CSG_DateTime & Set_Unix_Time(sLong Seconds)
Definition: datetime.cpp:594
CSG_DateTime::Parse_DateTime
bool Parse_DateTime(const CSG_String &datetime)
Definition: datetime.cpp:481
CSG_TimeSpan::Format
CSG_String Format(const CSG_String &format="") const
Definition: datetime.cpp:65
CSG_DateTime::Set_Hours_AD
CSG_DateTime & Set_Hours_AD(int Hours)
Definition: datetime.cpp:611
CSG_DateTime::Get_DayOfYear
unsigned short Get_DayOfYear(void) const
Definition: datetime.cpp:390
CSG_Vector::Create
bool Create(const CSG_Vector &Vector)
Definition: mat_matrix.cpp:87
CSG_DateTime::Format
CSG_String Format(const CSG_String &Format="") const
Definition: datetime.cpp:445
CSG_DateTime::Set_To_Current
CSG_DateTime & Set_To_Current(void)
Definition: datetime.cpp:259
sLong
signed long long sLong
Definition: api_core.h:158
CSG_DateTime::is_SameDate
bool is_SameDate(const CSG_DateTime &DateTime) const
Definition: datetime.cpp:432
CSG_DateTime::TSG_DateTime
unsigned short TSG_DateTime
Definition: datetime.h:189
SG_Get_Day_Length
double SG_Get_Day_Length(int DayOfYear, double Latitude)
Definition: datetime.cpp:972
CSG_DateTime::Get_WeekDay
WeekDay Get_WeekDay(void) const
Definition: datetime.cpp:395
CSG_DateTime::is_StrictlyBetween
bool is_StrictlyBetween(const CSG_DateTime &t1, const CSG_DateTime &t2) const
Definition: datetime.cpp:437
CSG_DateTime::Get_JDN
double Get_JDN(void) const
Definition: datetime.cpp:411
CSG_DateTime::is_LaterThan
bool is_LaterThan(const CSG_DateTime &DateTime) const
Definition: datetime.cpp:429
SG_String_Tokenize
SAGA_API_DLL_EXPORT CSG_Strings SG_String_Tokenize(const CSG_String &String, const CSG_String &Delimiters=SG_DEFAULT_DELIMITERS, TSG_String_Tokenizer_Mode Mode=SG_TOKEN_DEFAULT)
Definition: api_string.cpp:1564
CSG_Strings
Definition: api_core.h:700
CSG_DateTime
Definition: datetime.h:183
CSG_DateTime::~CSG_DateTime
virtual ~CSG_DateTime(void)
Definition: datetime.cpp:120
CSG_DateTime::Get_Hour
unsigned short Get_Hour(void) const
Definition: datetime.cpp:376
CSG_DateTime::Subtract
CSG_DateTime Subtract(const CSG_TimeSpan &TimeSpan) const
Definition: datetime.cpp:339
CSG_String::Left
CSG_String Left(size_t count) const
Definition: api_string.cpp:729
CSG_String::AfterFirst
CSG_String AfterFirst(char Character) const
Definition: api_string.cpp:668
M_PI
#define M_PI
Definition: mat_tools.h:96
B
#define B
CSG_String
Definition: api_core.h:563
CSG_DateTime::Set_DayOfYear
CSG_DateTime & Set_DayOfYear(unsigned short Value)
Definition: datetime.cpp:251
CSG_DateTime::Year
Year
Definition: datetime.h:206
CSG_String::is_Empty
bool is_Empty(void) const
Definition: api_string.cpp:178
M_PI_360
#define M_PI_360
Definition: mat_tools.h:106
CSG_DateTime::Set
CSG_DateTime & Set(const CSG_DateTime &DateTime)
Definition: datetime.cpp:131
SG_JulianDayNumber_To_Date
bool SG_JulianDayNumber_To_Date(double JDN, int &y, int &m, int &d)
Definition: datetime.cpp:678
CSG_DateTime::Get_Day
unsigned short Get_Day(void) const
Definition: datetime.cpp:377
CSG_DateTime::Parse_ISOCombined
bool Parse_ISOCombined(const CSG_String &date, char sep='T')
Definition: datetime.cpp:502
CSG_DateTime::Get_WeekDayName
static CSG_String Get_WeekDayName(WeekDay weekday, NameFlags flags=Name_Full)
Definition: datetime.cpp:553
CSG_DateTime::Get_NumberOfDays
static TSG_DateTime Get_NumberOfDays(int year)
Definition: datetime.cpp:564
CSG_DateTime::Get_Value
sLong Get_Value(void) const
Definition: datetime.cpp:313
CSG_DateTime::Reset_Time
CSG_DateTime & Reset_Time(void)
Definition: datetime.cpp:267
SG_Get_Sun_Refraction
double SG_Get_Sun_Refraction(double Height, bool bRadians)
Definition: datetime.cpp:943
CSG_String::c_str
const SG_Char * c_str(void) const
Definition: api_string.cpp:236
CSG_DateTime::Get_EnglishMonthName
static CSG_String Get_EnglishMonthName(Month month, NameFlags flags=Name_Full)
Definition: datetime.cpp:548
CSG_DateTime::Format_ISOCombined
CSG_String Format_ISOCombined(char sep='T') const
Definition: datetime.cpp:470
CSG_Strings::Get_Count
int Get_Count(void) const
Definition: api_core.h:713
CSG_DateTime::Format_Date
CSG_String Format_Date(void) const
Definition: datetime.cpp:450
CSG_DateTime::Month
Month
Definition: datetime.h:196
CSG_String::Right
CSG_String Right(size_t count) const
Definition: api_string.cpp:717
CSG_DateTime::CSG_DateTime
CSG_DateTime(void)
Definition: datetime.cpp:82
CSG_DateTime::Get_WeekOfYear
TSG_DateTime Get_WeekOfYear(void) const
Definition: datetime.cpp:405
datetime.h
CSG_DateTime::WeekDay
WeekDay
Definition: datetime.h:201
CSG_DateTime::Add
CSG_DateTime Add(const CSG_TimeSpan &TimeSpan) const
Definition: datetime.cpp:324
CSG_DateTime::Get_MonthName
static CSG_String Get_MonthName(Month month, NameFlags flags=Name_Full)
Definition: datetime.cpp:543