diff --git a/kstars/time/kstarsdatetime.cpp b/kstars/time/kstarsdatetime.cpp index 41ad980c3..60f553b65 100644 --- a/kstars/time/kstarsdatetime.cpp +++ b/kstars/time/kstarsdatetime.cpp @@ -1,312 +1,313 @@ /*************************************************************************** kstarsdatetime.cpp - K Desktop Planetarium ------------------- begin : Tue 05 May 2004 copyright : (C) 2004 by Jason Harris email : jharris@30doradus.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "kstarsdatetime.h" #include "dms.h" #include "ksnumbers.h" #include #include KStarsDateTime::KStarsDateTime() : QDateTime() { + setTimeSpec(Qt::UTC); setDJD(J2000); } KStarsDateTime::KStarsDateTime(const KStarsDateTime &kdt) : QDateTime() { setDJD(kdt.djd()); setTimeSpec(kdt.timeSpec()); //utcoffset deprecated //setUtcOffset(kdt.utcOffset()); } /*KStarsDateTime::KStarsDateTime( const QDateTime &kdt ) : QDateTime( kdt ) { //don't call setDJD() because we don't need to compute the time; just set DJD directly QTime _t = kdt.time(); QDate _d = kdt.date(); long double jdFrac = ( _t.hour()-12 + ( _t.minute() + ( _t.second() + _t.msec()/1000.)/60.)/60.)/24.; - DJD = (long double)( _d.toJulianDay() ) + jdFrac; + DJD = static_cast( _d.toJulianDay() ) + jdFrac; }*/ KStarsDateTime::KStarsDateTime(const QDateTime &qdt) : QDateTime(qdt) //, QDateTime::Spec::UTC() ) { // FIXME: This method might be buggy. Need to write some tests -- asimha (Oct 2016) QTime _t = qdt.time(); QDate _d = qdt.date(); long double jdFrac = (_t.hour() - 12 + (_t.minute() + (_t.second() + _t.msec() / 1000.) / 60.) / 60.) / 24.; - DJD = (long double)(_d.toJulianDay()) + jdFrac; + DJD = static_cast(_d.toJulianDay()) + jdFrac; setTimeSpec(qdt.timeSpec()); //setUtcOffset(qdt.utcOffset()); } KStarsDateTime::KStarsDateTime(const QDate &_d, const QTime &_t, Qt::TimeSpec timeSpec) : //QDateTime( _d, _t, QDateTime::Spec::UTC() ) QDateTime(_d, _t, timeSpec) { //don't call setDJD() because we don't need to compute the time; just set DJD directly long double jdFrac = (_t.hour() - 12 + (_t.minute() + (_t.second() + _t.msec() / 1000.) / 60.) / 60.) / 24.; - DJD = (long double)(_d.toJulianDay()) + jdFrac; + DJD = static_cast(_d.toJulianDay()) + jdFrac; } KStarsDateTime::KStarsDateTime(long double _jd) : QDateTime() { - setDJD(_jd); setTimeSpec(Qt::UTC); + setDJD(_jd); } //KStarsDateTime KStarsDateTime::currentDateTime( QDateTime::Spec spec ) { KStarsDateTime KStarsDateTime::currentDateTime() { KStarsDateTime dt(QDateTime::currentDateTime()); // if ( dt.time().hour()==0 && dt.time().minute()==0 ) // midnight or right after? // dt.setDate( QDateTime::currentDateTime(spec).date() ); // fetch date again return dt; } KStarsDateTime KStarsDateTime::currentDateTimeUtc() { KStarsDateTime dt(QDateTime::currentDateTimeUtc()); //if ( dt.time().hour()==0 && dt.time().minute()==0 ) // midnight or right after? // dt.setDate( QDateTime::currentDateTime(spec).date() ); // fetch date again return dt; } KStarsDateTime KStarsDateTime::fromString(const QString &s) { //DEBUG qCDebug(KSTARS) << "Date string: " << s; KStarsDateTime dtResult(QDateTime::fromString(s, Qt::TextDate)); if (dtResult.isValid()) return dtResult; dtResult = KStarsDateTime(QDateTime::fromString(s, Qt::ISODate)); if (dtResult.isValid()) return dtResult; //dtResult = QDateTime::fromString( s, QDateTime::RFCDate ); dtResult = KStarsDateTime(QDateTime::fromString(s, Qt::RFC2822Date)); if (dtResult.isValid()) return dtResult; qCWarning(KSTARS) << "Could not parse Date/Time string:" << s; qCWarning(KSTARS) << "Valid date formats:"; qCWarning(KSTARS) << " 1950-02-25 ; 1950-02-25T05:30:00"; qCWarning(KSTARS) << " 25 Feb 1950 ; 25 Feb 1950 05:30:00"; qCWarning(KSTARS) << " Sat Feb 25 1950 ; Sat Feb 25 05:30:00 1950"; return KStarsDateTime(QDateTime()); //invalid } void KStarsDateTime::setDJD(long double _jd) { //QDateTime::setTimeSpec( QDateTime::Spec::UTC() ); - QDateTime::setTimeSpec(Qt::UTC); + //QDateTime::setTimeSpec(Qt::UTC); DJD = _jd; long int ijd = (long int)_jd; double dayfrac = _jd - (double)ijd + 0.5; if (dayfrac > 1.0) { ijd++; dayfrac -= 1.0; } QDate dd = QDate::fromJulianDay(ijd); QDateTime::setDate(dd); double hour = 24. * dayfrac; int h = int(hour); int m = int(60. * (hour - h)); int s = int(60. * (60. * (hour - h) - m)); int ms = int(1000. * (60. * (60. * (hour - h) - m) - s)); QDateTime::setTime(QTime(h, m, s, ms)); } void KStarsDateTime::setDate(const QDate &_d) { //Save the JD fraction - long double jdFrac = djd() - (long double)(date().toJulianDay()); + long double jdFrac = djd() - static_cast(date().toJulianDay()); //set the integer portion of the JD and add back the JD fraction: - setDJD((long double)_d.toJulianDay() + jdFrac); + setDJD(static_cast(_d.toJulianDay()) + jdFrac); } KStarsDateTime KStarsDateTime::addSecs(double s) const { - long double ds = (long double)s / 86400.; + long double ds = static_cast(s) / 86400.; KStarsDateTime kdt(djd() + ds); kdt.setTimeSpec(timeSpec()); return kdt; } void KStarsDateTime::setTime(const QTime &_t) { - KStarsDateTime _dt(date(), _t); + KStarsDateTime _dt(date(), _t, timeSpec()); setDJD(_dt.djd()); } dms KStarsDateTime::gst() const { dms gst0 = GSTat0hUT(); - double hr = double(time().hour() - offsetFromUtc()/3600.0); + double hr = double(time().hour() - offsetFromUtc() / 3600.0); double mn = double(time().minute()); double sc = double(time().second()) + double(0.001 * time().msec()); double st = (hr + (mn + sc / 60.0) / 60.0) * SIDEREALSECOND; dms gst = dms(gst0.Degrees() + st * 15.0).reduce(); return gst; } dms KStarsDateTime::GSTat0hUT() const { double sinOb, cosOb; // Mean greenwich sidereal time KStarsDateTime t0(date(), QTime(0, 0, 0)); long double s = t0.djd() - J2000; double t = s / 36525.0; double t1 = 6.697374558 + 2400.051336 * t + 0.000025862 * t * t + 0.000000002 * t * t * t; // To obtain the apparent sidereal time, we have to correct the // mean greenwich sidereal time with nutation in longitude multiplied // by the cosine of the obliquity of the ecliptic. This correction // is called nutation in right ascention, and may amount to 0.3 secs. KSNumbers num(t0.djd()); num.obliquity()->SinCos(sinOb, cosOb); // nutLong has to be in hours of time since t1 is hours of time. double nutLong = num.dEcLong() * cosOb / 15.0; t1 += nutLong; dms gst; gst.setH(t1); return gst.reduce(); } QTime KStarsDateTime::GSTtoUT(dms GST) const { dms gst0 = GSTat0hUT(); //dt is the number of sidereal hours since UT 0h. double dt = GST.Hours() - gst0.Hours(); while (dt < 0.0) dt += 24.0; while (dt >= 24.0) dt -= 24.0; //convert to solar time. dt is now the number of hours since 0h UT. dt /= SIDEREALSECOND; int hr = int(dt); int mn = int(60.0 * (dt - double(hr))); int sc = int(60.0 * (60.0 * (dt - double(hr)) - double(mn))); int ms = int(1000.0 * (60.0 * (60.0 * (dt - double(hr)) - double(mn)) - double(sc))); return (QTime(hr, mn, sc, ms)); } void KStarsDateTime::setFromEpoch(double epoch) { if (epoch == 1950.0) // Assume Besselian setFromEpoch(epoch, BESSELIAN); else setFromEpoch(epoch, JULIAN); // Assume Julian } bool KStarsDateTime::setFromEpoch(double epoch, EpochType type) { if (type != JULIAN && type != BESSELIAN) return false; else setDJD(epochToJd(epoch, type)); return true; } bool KStarsDateTime::setFromEpoch(const QString &eName) { bool result; double epoch; epoch = stringToEpoch(eName, result); if (!result) return false; return setFromEpoch(epoch, JULIAN); // We've already converted } long double KStarsDateTime::epochToJd(double epoch, EpochType type) { switch (type) { case BESSELIAN: return B1900 + (epoch - 1900.0) * JD_PER_BYEAR; case JULIAN: return J2000 + (epoch - 2000.0) * 365.25; default: return NaN::d; } } double KStarsDateTime::jdToEpoch(long double jd, KStarsDateTime::EpochType type) { // Definitions for conversion formulas are from: // // * http://scienceworld.wolfram.com/astronomy/BesselianEpoch.html // * http://scienceworld.wolfram.com/astronomy/JulianEpoch.html // switch (type) { case KStarsDateTime::BESSELIAN: return 1900.0 + (jd - KStarsDateTime::B1900) / KStarsDateTime::JD_PER_BYEAR; case KStarsDateTime::JULIAN: return 2000.0 + (jd - J2000) / 365.24; default: return NaN::d; } } double KStarsDateTime::stringToEpoch(const QString &eName, bool &ok) { double epoch = J2000; ok = false; if (eName.isEmpty()) // By default, assume J2000 return epoch; if (eName.startsWith('J')) epoch = eName.midRef(1).toDouble(&ok); else if (eName.startsWith('B')) { epoch = eName.midRef(1).toDouble(&ok); epoch = jdToEpoch(epochToJd(epoch, BESSELIAN), JULIAN); // Convert Besselian epoch to Julian epoch } // Assume it's Julian else epoch = eName.toDouble(&ok); return epoch; } diff --git a/kstars/time/kstarsdatetime.h b/kstars/time/kstarsdatetime.h index a538a8931..835c9d6c2 100644 --- a/kstars/time/kstarsdatetime.h +++ b/kstars/time/kstarsdatetime.h @@ -1,231 +1,266 @@ /*************************************************************************** kstarsdatetime.h - K Desktop Planetarium ------------------- begin : Tue 05 May 2004 copyright : (C) 2001 by Jason Harris email : jharris@30doradus.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #pragma once #include #define J2000 2451545.0 //Julian Date for noon on Jan 1, 2000 (epoch J2000) #define B1950 2433282.4235 // Julian date for Jan 0.9235, 1950 #define SIDEREALSECOND 1.002737909 //number of sidereal seconds in one solar second class dms; /** @class KStarsDateTime *@short Extension of QDateTime for KStars *KStarsDateTime can represent the date/time as a Julian Day, using a long double, *in which the fractional portion encodes the time of day to a precision of a less than a second. *Also adds Greenwich Sidereal Time and "epoch", which is just the date expressed as a floating *point number representing the year, with the fractional part representing the date and time *(with poor time resolution; typically the Epoch is only taken to the hundredths place, which is *a few days). *@note Local time and Local sideral time are not handled here. Because they depend on the *geographic location, they are part of the GeoLocation class. + *@note The default timespec is UTC unless the passed value has different timespec value. *@sa GeoLocation::GSTtoLST() *@sa GeoLocation::UTtoLT() *@author Jason Harris - *@version 1.0 + *@author Jasem Mutlaq + *@version 1.1 */ class KStarsDateTime : public QDateTime { - public: - /** - *@short Default constructor - *Creates a date/time at J2000 (noon on Jan 1, 200) - */ - KStarsDateTime(); - - /** - *@short Constructor - *Creates a date/time at the specified Julian Day. - *@p jd The Julian Day - */ - explicit KStarsDateTime(long double djd); - - /** - *@short Copy constructor - *@p kdt The KStarsDateTime object to copy. - */ - KStarsDateTime(const KStarsDateTime &kdt); - - /** - *@short Copy constructor - *@p qdt The QDateTime object to copy. - */ - explicit KStarsDateTime(const QDateTime &qdt); - - /** - *@short Constructor - *Create a KStarsDateTimne based on the specified Date and Time. - *@p _d The QDate to assign - *@p _t The QTime to assign - */ - KStarsDateTime(const QDate &_d, const QTime &_t, Qt::TimeSpec timeSpec = Qt::UTC); - - /** - *Assign the (long double) Julian Day value, which includes the time of day - *encoded in the fractional portion. - *@p jd the Julian Day value to assign. - */ - void setDJD(long double jd); - - /** - *Assign the Date according to a QDate object. - *@p d the QDate to assign - */ - void setDate(const QDate &d); - - /** - *Assign the Time according to a QTime object. - *@p t the QTime to assign - */ - void setTime(const QTime &t); - - /** - *@return a KStarsDateTime that is the given number of seconds later - *than this KStarsDateTime. - *@p s the number of seconds to add. The number can be negative. - */ - KStarsDateTime addSecs(double s) const; - - /** - *Modify the Date/Time by adding a number of days. - *@p nd the number of days to add. The number can be negative. - */ - inline KStarsDateTime addDays(int nd) const { return KStarsDateTime(djd() + (long double)nd); } - - inline bool operator==(const KStarsDateTime &d) const { return DJD == d.djd(); } - inline bool operator!=(const KStarsDateTime &d) const { return DJD != d.djd(); } - inline bool operator<(const KStarsDateTime &d) const { return DJD < d.djd(); } - inline bool operator<=(const KStarsDateTime &d) const { return DJD <= d.djd(); } - inline bool operator>(const KStarsDateTime &d) const { return DJD > d.djd(); } - inline bool operator>=(const KStarsDateTime &d) const { return DJD >= d.djd(); } - - /** - *@return the date and time according to the CPU clock - */ - static KStarsDateTime currentDateTime(); - - /** - *@return the UTC date and time according to the CPU clock - */ - static KStarsDateTime currentDateTimeUtc(); - - /** - *@return a KStarsDateTime object parsed from the given string. - *@note This function is format-agnostic; it will try several formats - *when parsing the string. - *@param s the string expressing the date/time to be parsed. - */ - static KStarsDateTime fromString(const QString &s); - - /** - *@return the julian day as a long double, including the time as the fractional portion. - */ - inline long double djd() const { return DJD; } - - /** - *@return The Greenwich Sidereal Time - *The Greenwich sidereal time is the Right Ascension coordinate that is currently transiting - *the Prime Meridian at the Royal Observatory in Greenwich, UK (longitude=0.0) - */ - dms gst() const; - - /** - *Convert a given Greenwich Sidereal Time to Universal Time (=Greenwich Mean Time). - *@p GST the Greenwich Sidereal Time to convert to Universal Time. - */ - QTime GSTtoUT(dms GST) const; // FIXME: Shouldn't this be static? - - /** - *@enum EpochType description options - *@note After 1976, the IAU standard for epochs is Julian Years. - */ - enum EpochType - { - JULIAN, /**< Julian epoch (see http://scienceworld.wolfram.com/astronomy/JulianEpoch.html) */ - BESSELIAN, /**< Besselian epoch (see http://scienceworld.wolfram.com/astronomy/BesselianEpoch.html) */ - }; - - /** - *@return the (Julian) epoch value of the Date/Time. - *@short This is (approximately) the year expressed as a floating-point value - *@sa setFromEpoch() - *@note The definition of Julian Epoch used here comes from http://scienceworld.wolfram.com/astronomy/JulianEpoch.html - */ - inline double epoch() const { return 2000.0 + (djd() - J2000) / 365.25; } - - /** - *Set the Date/Time from an epoch value, represented as a double. - *@p e the epoch value - *@sa epoch() - */ - bool setFromEpoch(double e, EpochType type); - - /** - *Set the Date/Time from an epoch value, represented as a string. - *@p e the epoch value - *@return true if date set successfully - *@sa epoch() - */ - bool setFromEpoch(const QString &e); - - /** - *Set the Date/Time from an epoch value, represented as a double. - *@p e the epoch value - *@note This method assumes that the epoch 1950.0 is Besselian, otherwise assumes that the epoch is a Julian epoch. This is provided for backward compatibility, and because custom catalogs may still use 1950.0 to mean B1950.0 despite the IAU standard for epochs being Julian. - *@sa epoch() - */ - void setFromEpoch(double e); - - /** - *@short Takes in an epoch and returns a Julian Date - *@return the Julian Date (date with fraction) - *@param epoch A floating-point year value specifying the Epoch - *@param type JULIAN or BESSELIAN depending on what convention the epoch is specified in - */ - static long double epochToJd(double epoch, EpochType type = JULIAN); - - /** - *@short Takes in a Julian Date and returns the corresponding epoch year in the given system - *@return the epoch as a floating-point year value - *@param jd Julian date - *@param type Epoch system (KStarsDateTime::JULIAN or KStarsDateTime::BESSELIAN) - */ - static double jdToEpoch(long double jd, EpochType type = JULIAN); - - /** - *@short Takes in a string and returns a Julian epoch - */ - static double stringToEpoch(const QString &eName, bool &ok); - - /** - * The following values were obtained from Eric Weisstein's world of science: - * http://scienceworld.wolfram.com/astronomy/BesselianEpoch.html - */ - constexpr static const double B1900 = 2415020.31352; // Julian date of B1900 epoch - constexpr static const double JD_PER_BYEAR = 365.242198781; // Julian days in a Besselian year - private: - /** - *@return the Greenwich Sidereal Time at 0h UT on this object's Date - *@note used internally by gst() and GSTtoUT() - */ - dms GSTat0hUT() const; - - long double DJD { 0 }; + public: + /** + *@short Default constructor + *Creates a date/time at J2000 (noon on Jan 1, 200) + *@note This sets the timespec to UTC. + */ + KStarsDateTime(); + + /** + *@short Constructor + *Creates a date/time at the specified Julian Day. + *@p jd The Julian Day + *@note This sets the timespec to UTC. + */ + explicit KStarsDateTime(long double djd); + + /** + *@short Copy constructor + *@p kdt The KStarsDateTime object to copy. + *@note The timespec is copied from kdt. + */ + KStarsDateTime(const KStarsDateTime &kdt); + + /** + *@short Copy constructor + *@p qdt The QDateTime object to copy. + *@note The timespec is copied from qdt. + */ + explicit KStarsDateTime(const QDateTime &qdt); + + /** + *@short Constructor + *Create a KStarsDateTimne based on the specified Date and Time. + *@p _d The QDate to assign + *@p _t The QTime to assign + *@p timespec The desired timespec, UTC by default. + */ + KStarsDateTime(const QDate &_d, const QTime &_t, Qt::TimeSpec timeSpec = Qt::UTC); + + /** + *Assign the static_cast Julian Day value, which includes the time of day + *encoded in the fractional portion. + *@p jd the Julian Day value to assign. + */ + void setDJD(long double jd); + + /** + *Assign the Date according to a QDate object. + *@p d the QDate to assign + */ + void setDate(const QDate &d); + + /** + *Assign the Time according to a QTime object. + *@p t the QTime to assign + *@note timespec is NOT changed even if the passed QTime has a different timespec than current. + */ + void setTime(const QTime &t); + + /** + *@return a KStarsDateTime that is the given number of seconds later + *than this KStarsDateTime. + *@p s the number of seconds to add. The number can be negative. + */ + KStarsDateTime addSecs(double s) const; + + /** + *Modify the Date/Time by adding a number of days. + *@p nd the number of days to add. The number can be negative. + */ + inline KStarsDateTime addDays(int nd) const + { + return KStarsDateTime(djd() + static_cast(nd)); + } + + inline bool operator==(const KStarsDateTime &d) const + { + return DJD == d.djd(); + } + inline bool operator!=(const KStarsDateTime &d) const + { + return DJD != d.djd(); + } + inline bool operator<(const KStarsDateTime &d) const + { + return DJD < d.djd(); + } + inline bool operator<=(const KStarsDateTime &d) const + { + return DJD <= d.djd(); + } + inline bool operator>(const KStarsDateTime &d) const + { + return DJD > d.djd(); + } + inline bool operator>=(const KStarsDateTime &d) const + { + return DJD >= d.djd(); + } + + /** + *@return the date and time according to the CPU clock + */ + static KStarsDateTime currentDateTime(); + + /** + *@return the UTC date and time according to the CPU clock + */ + static KStarsDateTime currentDateTimeUtc(); + + /** + *@return a KStarsDateTime object parsed from the given string. + *@note This function is format-agnostic; it will try several formats + *when parsing the string. + *@param s the string expressing the date/time to be parsed. + */ + static KStarsDateTime fromString(const QString &s); + + /** + *@return the julian day as a long double, including the time as the fractional portion. + */ + inline long double djd() const + { + return DJD; + } + + /** + *@return The Greenwich Sidereal Time + *The Greenwich sidereal time is the Right Ascension coordinate that is currently transiting + *the Prime Meridian at the Royal Observatory in Greenwich, UK (longitude=0.0) + */ + dms gst() const; + + /** + *Convert a given Greenwich Sidereal Time to Universal Time (=Greenwich Mean Time). + *@p GST the Greenwich Sidereal Time to convert to Universal Time. + */ + QTime GSTtoUT(dms GST) const; // FIXME: Shouldn't this be static? + + /** + *@enum EpochType description options + *@note After 1976, the IAU standard for epochs is Julian Years. + */ + enum EpochType + { + JULIAN, /**< Julian epoch (see http://scienceworld.wolfram.com/astronomy/JulianEpoch.html) */ + BESSELIAN, /**< Besselian epoch (see http://scienceworld.wolfram.com/astronomy/BesselianEpoch.html) */ + }; + + /** + *@return the (Julian) epoch value of the Date/Time. + *@short This is (approximately) the year expressed as a floating-point value + *@sa setFromEpoch() + *@note The definition of Julian Epoch used here comes from http://scienceworld.wolfram.com/astronomy/JulianEpoch.html + */ + inline double epoch() const + { + return 2000.0 + (djd() - J2000) / 365.25; + } + + /** + *Set the Date/Time from an epoch value, represented as a double. + *@p e the epoch value + *@sa epoch() + */ + bool setFromEpoch(double e, EpochType type); + + /** + *Set the Date/Time from an epoch value, represented as a string. + *@p e the epoch value + *@return true if date set successfully + *@sa epoch() + */ + bool setFromEpoch(const QString &e); + + /** + *Set the Date/Time from an epoch value, represented as a double. + *@p e the epoch value + *@note This method assumes that the epoch 1950.0 is Besselian, otherwise assumes that the epoch is a Julian epoch. This is provided for backward compatibility, and because custom catalogs may still use 1950.0 to mean B1950.0 despite the IAU standard for epochs being Julian. + *@sa epoch() + */ + void setFromEpoch(double e); + + /** + *@short Takes in an epoch and returns a Julian Date + *@return the Julian Date (date with fraction) + *@param epoch A floating-point year value specifying the Epoch + *@param type JULIAN or BESSELIAN depending on what convention the epoch is specified in + */ + static long double epochToJd(double epoch, EpochType type = JULIAN); + + /** + *@short Takes in a Julian Date and returns the corresponding epoch year in the given system + *@return the epoch as a floating-point year value + *@param jd Julian date + *@param type Epoch system (KStarsDateTime::JULIAN or KStarsDateTime::BESSELIAN) + */ + static double jdToEpoch(long double jd, EpochType type = JULIAN); + + /** + *@short Takes in a string and returns a Julian epoch + */ + static double stringToEpoch(const QString &eName, bool &ok); + + /** + * The following values were obtained from Eric Weisstein's world of science: + * http://scienceworld.wolfram.com/astronomy/BesselianEpoch.html + */ + constexpr static const double B1900 = 2415020.31352; // Julian date of B1900 epoch + constexpr static const double JD_PER_BYEAR = 365.242198781; // Julian days in a Besselian year + private: + /** + *@return the Greenwich Sidereal Time at 0h UT on this object's Date + *@note used internally by gst() and GSTtoUT() + */ + dms GSTat0hUT() const; + + long double DJD { 0 }; };