CppEphem
CEDate.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * CEDate.cpp: CppEphem *
3  * ----------------------------------------------------------------------- *
4  * Copyright © 2016-2019 JCardenzana *
5  * ----------------------------------------------------------------------- *
6  * *
7  * This program is free software: you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation, either version 3 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * This program is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License *
18  * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19  * *
20  ***************************************************************************/
21 
32 #include <cmath>
33 #include <exception>
34 #include <stdio.h>
35 
36 #include "CEDate.h"
37 #include "CEException.h"
38 
39 /**********************************************************************/
46 CEDate::CEDate(double date, CEDateType date_format)
47 {
48  init_members();
49  // Use the SetDate function to set the actual time
50  CEDate::SetDate(date, date_format) ;
51 }
52 
53 /**********************************************************************/
61 CEDate::CEDate(std::vector<double> date)
62 {
63  init_members();
64  // First get the gregorian date double from the vector, then set the date
66 }
67 
68 /**********************************************************************/
71 CEDate::CEDate(const CEDate& other)
72 {
73  init_members();
74  copy_members(other);
75 }
76 
77 
78 /**********************************************************************/
82 {}
83 
84 
85 /**********************************************************************/
91 CEDate& CEDate::operator=(const CEDate& other)
92 {
93  if (this != &other) {
94  free_members();
95  init_members();
96  copy_members(other);
97  }
98  return *this;
99 }
100 
101 
102 /**********************************************************************/
108 void CEDate::SetDate(const double& date,
109  const CEDateType& time_format)
110 {
111  // Fill the internal date storage objects based on the format of the input "date"
112  if (time_format == CEDateType::JD) {
113  // Save information based on julian date input
114  julian_date_ = date ;
115  mod_julian_date_ = JD2MJD(date) ;
116  gregorian_date_ = JD2Gregorian(date) ;
118  } else if (time_format == CEDateType::MJD) {
119  // Save information based on modified julian date input
120  julian_date_ = MJD2JD(date) ;
121  mod_julian_date_ = date ;
124  } else if (time_format == CEDateType::GREGORIAN) {
125  // Save information based on gregorian date input
126  julian_date_ = Gregorian2JD(date) ;
128  gregorian_date_ = date ;
130  } else {
131  // Date type is invalid
132  throw CEException::invalid_value("CEDate::SetDate()",
133  "Invalid date type");
134  }
135 }
136 
137 /**********************************************************************/
146 void CEDate::SetDate(std::vector<double> date)
147 {
148  SetDate(GregorianVect2JD(date)) ;
149 }
150 
151 /**********************************************************************/
156 double CEDate::GetDate(CEDateType time_format) const
157 {
158  // Initialize the return date
159  double date(0);
160 
161  // Return the julian date if requested
162  if (time_format == CEDateType::JD) {
163  date = JD() ;
164  } else if (time_format == CEDateType::MJD) {
165  date = MJD() ;
166  } else if (time_format == CEDateType::GREGORIAN) {
167  date = Gregorian() ;
168  } else {
169  throw CEException::invalid_value("CEDate::GetDate()",
170  "Unrecognized time format!");
171  }
172 
173  return date;
174 }
175 
176 
177 /**********************************************************************/
183 double CEDate::JD2MJD(double jd)
184 {
185  return jd - GetMJD2JDFactor();
186 }
187 
188 /**********************************************************************/
194 double CEDate::JD2Gregorian(double jd)
195 {
196  // Fill a temporary gregorian vector
197  std::vector<double> temp_gregorian_vect = JD2GregorianVect(jd) ;
198  return GregorianVect2Gregorian(temp_gregorian_vect) ;
199 }
200 
201 /**********************************************************************/
212 std::vector<double> CEDate::JD2GregorianVect(double jd)
213 {
214  std::vector<double> full_gregorian_vect(4,0.0) ;
215  std::vector<int> gregorian_date(3,0.0) ;
216 
217  // Try to fill the gregorian_date vector
218  if (iauJd2cal(jd, 0, &gregorian_date[0], &gregorian_date[1],
219  &gregorian_date[2], &full_gregorian_vect[3])) {
220  std::cerr << "[WARNING] CEDate::JD2GregorianVect() :: Bad date (" << jd << ")!" << std::endl ;
221  return std::vector<double>(4,0.0) ;
222  } else {
223  // Fill the double vector from the integer values
224  full_gregorian_vect[0] = 1.0*gregorian_date[0] ;
225  full_gregorian_vect[1] = 1.0*gregorian_date[1] ;
226  full_gregorian_vect[2] = 1.0*gregorian_date[2] ;
227  }
228 
229  return full_gregorian_vect ;
230 }
231 
232 
233 // Note that the modified julian date converters first do a conversion
234 // to Julian Date and then call the Julian Date converters
235 
236 /**********************************************************************/
242 double CEDate::MJD2JD(double mjd)
243 {
244  return mjd + GetMJD2JDFactor();
245 }
246 
247 
248 /**********************************************************************/
254 double CEDate::MJD2Gregorian(double mjd)
255 {
256  // Convert the mjd to jd
257  double jd = MJD2JD(mjd) ;
258  // Now convert julian date to gregorian
259  return JD2Gregorian(jd) ;
260 }
261 
262 
263 /**********************************************************************/
273 std::vector<double> CEDate::MJD2GregorianVect(double mjd)
274 {
275  // Convert mjd to jd
276  double jd = MJD2JD(mjd) ;
277  // Now convert julian date to gregorian vector
278  return JD2GregorianVect(jd) ;
279 }
280 
281 
282 /**********************************************************************/
288 double CEDate::Gregorian2JD(double gregorian)
289 {
290  // First convert the gregorian double into a gregorian vector
291  std::vector<double> gregorian_vect = Gregorian2GregorianVect(gregorian) ;
292 
293  return GregorianVect2JD(gregorian_vect) ;
294 }
295 
296 
297 /**********************************************************************/
308 double CEDate::GregorianVect2JD(std::vector<double> gregorian)
309 {
310  // The following stores the two values needed to get the julian date
311  double mjd_factor(0.0);
312  double mjd(0.0);
313 
314  // Now use the sofa function for converting to julian date
315  int err_code = iauCal2jd(int(gregorian[0]), int(gregorian[1]),
316  int(gregorian[2]), &mjd_factor, &mjd) ;
317  if (err_code) {
318  std::cerr << "[WARNING] CEDate::GregorianVect2JD() :: Bad ";
319  if (err_code == -1) {
320  std::cerr << "year (" << gregorian[0] << "). Make sure the year is larger than -4800." << std::endl ;
321  return 0.0 ;
322  } else if (err_code == -2) {
323  std::cerr << "month (" << gregorian[1] << "). Make sure this number is in the range 1 -> 12." << std::endl ;
324  return 0.0 ;
325  } else if (err_code == -3) {
326  std::cerr << "day (" << gregorian[2] << ")" << std::endl ;
327  // Note that in this case, a julian date was still calculated
328  // so we can go ahead and return it
329  }
330  }
331 
332  // Return the sum of the two filled date values which represents
333  // the Julian date
334  return mjd_factor + mjd + gregorian[3] ;
335 }
336 
337 
338 /**********************************************************************/
344 double CEDate::Gregorian2MJD(double gregorian)
345 {
346  // First get the Julian Date
347  double jd = Gregorian2JD(gregorian) ;
348  // Now convert to Modified Julian Date
349  return JD2MJD(jd) ;
350 }
351 
352 
353 /**********************************************************************/
363 double CEDate::GregorianVect2MJD(std::vector<double> gregorian)
364 {
365  // First convert to JD
366  double jd = GregorianVect2JD(gregorian) ;
367  // Now convert to MJD
368  return JD2MJD(jd) ;
369 }
370 
371 
372 /**********************************************************************/
385 void CEDate::UTC2UT1(const double& mjd,
386  double* ut11,
387  double* ut12)
388 {
389  iauUtcut1(CEDate::GetMJD2JDFactor(), mjd, CppEphem::dut1(mjd), ut11, ut12);
390 }
391 
392 
393 /**********************************************************************/
406 void CEDate::UTC2TT(const double& mjd,
407  double* tt1,
408  double* tt2)
409 {
410  // Convert UTC to UT1
411  CEDate::UTC2UT1(mjd, tt1, tt2);
412  // Convert UT1 to TT
413  iauUt1tt(*tt1, *tt2, CppEphem::ttut1(mjd), tt1, tt2) ;
414 }
415 
416 
417 /**********************************************************************/
430 void CEDate::UTC2TDB(const double& mjd,
431  double* tdb1,
432  double* tdb2)
433 {
434  // Convert UTC to TT
435  CEDate::UTC2TT(mjd, tdb1, tdb2);
436  // Convert TT to TDB
437  iauTttdb(*tdb1, *tdb2, 0.0, tdb1, tdb2) ;
438 }
439 
440 
441 /**********************************************************************/
448 double CEDate::dut1(const double& date,
449  const CEDateType& date_type)
450 {
451  // Create an object from the date information
452  CEDate input_date(date, date_type) ;
453  // Return the DUT1 value at this date
454  return input_date.dut1() ;
455 }
456 
457 
458 /**********************************************************************/
463 double CEDate::dut1(void) const
464 {
465  // return the value associated with 'UT1-UTC'
467 }
468 
469 
470 // /**********************************************************************//**
471 // *************************************************************************/
472 // double CEDate::dut1Error(double date, CEDateType date_type)
473 // {
474 // CEDate input_date(date, date_type) ;
475 // return input_date.dut1Error() ;
476 // }
477 
478 
479 // /**********************************************************************//**
480 // *************************************************************************/
481 // double CEDate::dut1Error()
482 // {
483 // // Return the error on the dut1 value
484 // return CppEphem::dut1Error(mod_julian_date_) ;
485 // }
486 
487 
488 /**********************************************************************/
495 double CEDate::xpolar(const double& date,
496  const CEDateType& date_type)
497 {
498  CEDate input_date(date, date_type) ;
499  return CppEphem::xp( input_date.MJD() ) ;
500 }
501 
502 
503 /**********************************************************************/
508 double CEDate::xpolar(void) const
509 {
510  return CppEphem::xp( mod_julian_date_ ) ;
511 }
512 
513 
514 /**********************************************************************/
521 double CEDate::ypolar(const double& date,
522  const CEDateType& date_type)
523 {
524  CEDate input_date(date, date_type) ;
525  return CppEphem::yp( input_date.MJD() ) ;
526 }
527 
528 
529 /**********************************************************************/
534 double CEDate::ypolar(void) const
535 {
536  return CppEphem::yp( mod_julian_date_ ) ;
537 }
538 
539 
540 /**********************************************************************/
546 double CEDate::GregorianVect2Gregorian(std::vector<double> gregorian)
547 {
548  int sign = (gregorian[0] < 0) ? -1.0 : 1.0;
549  double ret = std::fabs(gregorian[0]) * 10000 +
550  gregorian[1] * 100 +
551  gregorian[2];
552  if (gregorian.size() == 4) {
553  ret += gregorian[3];
554  }
555  return sign * ret;
556 }
557 
558 
559 /**********************************************************************/
565 std::vector<double> CEDate::Gregorian2GregorianVect(double gregorian)
566 {
567  // Create a vector to hold the information
568  std::vector<double> gregorian_vect(4,0.0) ;
569  double greg = std::fabs(gregorian);
570 
571  // Get the day fraction
572  gregorian_vect[3] = greg - std::floor(greg);
573  // Get the day of the month
574  gregorian_vect[2] = int(std::floor(greg)) % 100 ;
575  // Get the month
576  gregorian_vect[1] = int(std::floor(greg - gregorian_vect[2])/100) % 100;
577  // Get the year
578  gregorian_vect[0] = int(std::floor(greg - gregorian_vect[2] - 100*gregorian_vect[1]) / 10000);
579  gregorian_vect[0] *= (gregorian < 0.0) ? -1.0 : 1.0;
580 
581  return gregorian_vect;
582 }
583 
584 
585 /**********************************************************************/
592 double CEDate::GetSecondsSinceMidnight(const double& utc_offset)
593 {
594  double mjd_offset = MJD();
595  mjd_offset -= std::floor(mjd_offset);
596  mjd_offset += utc_offset/24.0;
597  return CETime::UTC( mjd_offset ) ;
598 }
599 
600 
601 /**********************************************************************/
608 double CEDate::GetTime(const double& utc_offset) const
609 {
610  double mjd_offset = MJD();
611  mjd_offset -= std::floor(mjd_offset);
612  mjd_offset += utc_offset/24.0;
613  return CETime::TimeSec2Time( CETime::UTC( mjd_offset ) ) ;
614 }
615 
616 
617 /**********************************************************************/
622 double CEDate::GetTime_UTC() const
623 {
624  return GetTime(0.0) ;
625 }
626 
627 
628 /**********************************************************************/
633 double CEDate::CurrentJD()
634 {
635  // Get the current date information
636  time_t now ;
637  time (&now) ;
638  struct tm current_jd;
639  gmtime_r(&now, &current_jd) ;
640 
641  // Put this into a vector
642  std::vector<double> date_info = {current_jd.tm_year+1900.0,
643  current_jd.tm_mon+1.0,
644  current_jd.tm_mday*1.0,
645  CETime::CurrentUTC()/DAYSEC} ;
646 
647  // Convert the Gregorian date information into a Julian date
648  return GregorianVect2JD( date_info ) ;
649 }
650 
651 
652 /**********************************************************************/
656 CEDate::operator double()
657 {
658  // Return the date formatted according to the 'return_type_' variable
659  return GetDate(return_type_) ;
660 }
661 
662 /**********************************************************************/
666 CEDate::operator double() const
667 {
668  // Return the date formatted according to the 'return_type_' variable
669  return GetDate(return_type_) ;
670 }
671 
672 
673 /**********************************************************************/
676 void CEDate::free_members(void)
677 {
678  gregorian_date_vect_.clear();
679 }
680 
681 
682 /**********************************************************************/
687 void CEDate::copy_members(const CEDate& other)
688 {
690  julian_date_ = other.julian_date_;
693  return_type_ = other.return_type_;
694 }
695 
696 
697 /**********************************************************************/
700 void CEDate::init_members(void)
701 {
702  gregorian_date_vect_ = std::vector<double>(4, 0.0);
703  julian_date_ = 0.0;
704  mod_julian_date_ = 0.0;
705  gregorian_date_ = 0.0;
707 }
CEDate::GregorianVect2Gregorian
static double GregorianVect2Gregorian(std::vector< double > gregorian)
Helper method for converting from Gregorian vector format to the non-vector format.
Definition: CEDate.cpp:545
CEDate::init_members
void init_members(void)
Initialize the data members.
Definition: CEDate.cpp:699
CEDate::GetTime_UTC
virtual double GetTime_UTC() const
Method for getting the current UTC time.
Definition: CEDate.cpp:621
CEDate::gregorian_date_
double gregorian_date_
Gregorian calendar date. Format as YYYYMMDD.DD.
Definition: CEDate.h:133
CEDate
Definition: CEDate.h:43
CppEphem::yp
double yp(const double &mjd)
Polar motion (x) for a given modified julian date (radians)
Definition: CENamespace.cpp:160
CETime::UTC
static double UTC(const double &jd)
Get the current UTC time.
Definition: CETime.cpp:169
CEDate::CEDate
CEDate(double date=CurrentJD(), CEDateType date_format=CEDateType::JD)
Constructor from some date format.
Definition: CEDate.cpp:45
CEDateType
CEDateType
Date enum.
Definition: CEDate.h:38
CEDate::copy_members
void copy_members(const CEDate &other)
Copy data members from another date object.
Definition: CEDate.cpp:686
CEDate::GetTime
virtual double GetTime(const double &utc_offset=0.0) const
Method for getting the current time.
Definition: CEDate.cpp:607
CEDate.h
CEDate::Gregorian2GregorianVect
static std::vector< double > Gregorian2GregorianVect(double gregorian)
Helper method for converting from non-vector formatted Gregorian date to vector format Gregorian date...
Definition: CEDate.cpp:564
CEDate::xpolar
double xpolar(void) const
Polar motion (x) for a given date.
Definition: CEDate.cpp:507
CEDate::UTC2TDB
static void UTC2TDB(const double &mjd, double *tdb1, double *tdb2)
Convert the UTC MJD to TDB JD (useful for planet computations)
Definition: CEDate.cpp:429
CEDate::Gregorian2JD
static double Gregorian2JD(double gregorian)
Gregorian calendar date -> Julian date.
Definition: CEDate.cpp:287
CEException.h
CEDate::Gregorian2MJD
static double Gregorian2MJD(double gregorian)
Gregorian calendar formatted date -> Julian date converter.
Definition: CEDate.cpp:343
CEDate::free_members
void free_members(void)
Free data members.
Definition: CEDate.cpp:675
CEDate::mod_julian_date_
double mod_julian_date_
Modified Julian date formated.
Definition: CEDate.h:132
CEDate::GregorianVect2JD
static double GregorianVect2JD(std::vector< double > gregorian)
Gregorian calendar vector formatted date -> Julian date converter.
Definition: CEDate.cpp:307
CEDate::UTC2UT1
static void UTC2UT1(const double &mjd, double *ut11, double *ut12)
Convert the UTC MJD to UT1 JD.
Definition: CEDate.cpp:384
CEDate::MJD2GregorianVect
static std::vector< double > MJD2GregorianVect(double mjd)
Modified Julian date -> Gregorian calendar, vector formatted date.
Definition: CEDate.cpp:272
CEDate::julian_date_
double julian_date_
Julian date formated.
Definition: CEDate.h:131
JD
Julian Date.
Definition: CEDate.h:56
CEDate::gregorian_date_vect_
std::vector< double > gregorian_date_vect_
Vector containing the gregorian calendar date 0 - Year, 1 - Month, 2 - date, 3 - date fraction.
Definition: CEDate.h:134
CEDate::ypolar
double ypolar(void) const
Polar motion (y) for a given date.
Definition: CEDate.cpp:533
CEDate::~CEDate
virtual ~CEDate()
Destructor.
Definition: CEDate.cpp:80
CEDate::GetMJD2JDFactor
static double GetMJD2JDFactor()
Gets the stored SOFA Julian date to Mod Julian date factor 'DJM0'.
Definition: CEDate.h:236
CETime::TimeSec2Time
static double TimeSec2Time(const double &seconds)
Convert number of seconds since midnight to HHMMSS.S formatted double.
Definition: CETime.cpp:300
CETime::CurrentUTC
static double CurrentUTC()
Get the current UTC time as seconds since midnight.
Definition: CETime.cpp:124
CEDate::GregorianVect2MJD
static double GregorianVect2MJD(std::vector< double > gregorian)
Gregorian calendar vector formatted date -> Modified Julian date converter.
Definition: CEDate.cpp:362
CEDate::JD2GregorianVect
static std::vector< double > JD2GregorianVect(double jd)
Julian date -> modified Julian date conversion method.
Definition: CEDate.cpp:211
CEDate::GetDate
double GetDate(CEDateType time_format=CEDateType::JD) const
Return the date in a given format.
Definition: CEDate.cpp:155
MJD
Modified Julian Date.
Definition: CEDate.h:57
GREGORIAN
Gregorian calendar (year, month, day)
Definition: CEDate.h:58
CEDate::CurrentJD
static double CurrentJD()
Static method for getting the current Julian date.
Definition: CEDate.cpp:632
CEException::invalid_value
Definition: CEException.h:73
CEDate::SetDate
virtual void SetDate(const double &date=CurrentJD(), const CEDateType &time_format=CEDateType::JD)
Set the date based on an actual date and the desired time_format.
Definition: CEDate.cpp:107
CEDate::JD2Gregorian
static double JD2Gregorian(const double jd)
Julian date -> Gregorian calendar date conversion method.
Definition: CEDate.cpp:193
CEDate::MJD
virtual double MJD() const
Get the Modified Julian date represented by this object.
Definition: CEDate.h:160
CEDate::operator=
CEDate & operator=(const CEDate &other)
Copy assignent operator.
Definition: CEDate.cpp:90
CEDate::GetSecondsSinceMidnight
virtual double GetSecondsSinceMidnight(const double &utc_offset=0.0)
Method for getting the number of seconds since midnight.
Definition: CEDate.cpp:591
CEDate::Gregorian
virtual double Gregorian() const
Get the Gregorian calendar date formatted as a double.
Definition: CEDate.h:170
CppEphem::dut1
double dut1(const double &mjd)
Return dut1 based on a given modified julian date (seconds)
Definition: CENamespace.cpp:111
CEDate::dut1
double dut1(void) const
Return dut1 based on the date represented by this object.
Definition: CEDate.cpp:462
CEDate::UTC2TT
static void UTC2TT(const double &mjd, double *tt1, double *tt2)
Convert the UTC MJD to TT JD.
Definition: CEDate.cpp:405
CEDate::JD
virtual double JD() const
Get the Julian date represented by this object.
Definition: CEDate.h:150
CEDate::return_type_
CEDateType return_type_
what format the 'operator double' will return
Definition: CEDate.h:136
CEDate::MJD2JD
static double MJD2JD(double mjd)
Modified Julian date -> Julian date conversion method.
Definition: CEDate.cpp:241
CppEphem::ttut1
double ttut1(const double &mjd)
TT-UT1 correction for a given MJD (seconds)
Definition: CENamespace.cpp:196
CppEphem::xp
double xp(const double &mjd)
Polar motion (x) for a given modified julian date (radians)
Definition: CENamespace.cpp:148
CEDate::JD2MJD
static double JD2MJD(double jd)
Julian date -> modified Julian date conversion method.
Definition: CEDate.cpp:182
CEDate::MJD2Gregorian
static double MJD2Gregorian(double mjd)
Modified Julian date -> Gregorian calendar date conversion method.
Definition: CEDate.cpp:253