File indexing completed on 2024-04-14 14:11:32
0001 /* 0002 SPDX-FileCopyrightText: 2001 Jason Harris <jharris@30doradus.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include <QDateTime> 0010 0011 #define J2000 2451545.0 //Julian Date for noon on Jan 1, 2000 (epoch J2000) 0012 #define B1950 2433282.4235 // Julian date for Jan 0.9235, 1950 0013 #define SIDEREALSECOND 1.002737909 //number of sidereal seconds in one solar second 0014 0015 class dms; 0016 0017 /** @class KStarsDateTime 0018 *@short Extension of QDateTime for KStars 0019 *KStarsDateTime can represent the date/time as a Julian Day, using a long double, 0020 *in which the fractional portion encodes the time of day to a precision of a less than a second. 0021 *Also adds Greenwich Sidereal Time and "epoch", which is just the date expressed as a floating 0022 *point number representing the year, with the fractional part representing the date and time 0023 *(with poor time resolution; typically the Epoch is only taken to the hundredths place, which is 0024 *a few days). 0025 *@note Local time and Local sideral time are not handled here. Because they depend on the 0026 *geographic location, they are part of the GeoLocation class. 0027 *@note The default timespec is UTC unless the passed value has different timespec value. 0028 *@sa GeoLocation::GSTtoLST() 0029 *@sa GeoLocation::UTtoLT() 0030 *@author Jason Harris 0031 *@author Jasem Mutlaq 0032 *@version 1.1 0033 */ 0034 0035 class KStarsDateTime : public QDateTime 0036 { 0037 public: 0038 /** 0039 *@short Default constructor 0040 *Creates a date/time at J2000 (noon on Jan 1, 200) 0041 *@note This sets the timespec to UTC. 0042 */ 0043 KStarsDateTime(); 0044 0045 /** 0046 *@short Constructor 0047 *Creates a date/time at the specified Julian Day. 0048 *@p jd The Julian Day 0049 *@note This sets the timespec to UTC. 0050 */ 0051 explicit KStarsDateTime(long double djd); 0052 0053 /** 0054 *@short Copy constructor 0055 *@p kdt The KStarsDateTime object to copy. 0056 *@note The timespec is copied from kdt. 0057 */ 0058 /** @{ */ 0059 KStarsDateTime(const KStarsDateTime &kdt); 0060 KStarsDateTime &operator=(const KStarsDateTime &kdt) noexcept; 0061 /** @} */ 0062 0063 /** 0064 *@short Copy constructor 0065 *@p qdt The QDateTime object to copy. 0066 *@note The timespec is copied from qdt. 0067 */ 0068 explicit KStarsDateTime(const QDateTime &qdt); 0069 0070 /** 0071 *@short Constructor 0072 *Create a KStarsDateTimne based on the specified Date and Time. 0073 *@p _d The QDate to assign 0074 *@p _t The QTime to assign 0075 *@p timespec The desired timespec, UTC by default. 0076 */ 0077 KStarsDateTime(const QDate &_d, const QTime &_t, Qt::TimeSpec timeSpec = Qt::UTC); 0078 0079 /** 0080 *Assign the static_cast<long double> Julian Day value, which includes the time of day 0081 *encoded in the fractional portion. 0082 *@p jd the Julian Day value to assign. 0083 */ 0084 void setDJD(long double jd); 0085 0086 /** 0087 *Assign the Date according to a QDate object. 0088 *@p d the QDate to assign 0089 */ 0090 void setDate(const QDate &d); 0091 0092 /** 0093 *Assign the Time according to a QTime object. 0094 *@p t the QTime to assign 0095 *@note timespec is NOT changed even if the passed QTime has a different timespec than current. 0096 */ 0097 void setTime(const QTime &t); 0098 0099 /** 0100 *@return a KStarsDateTime that is the given number of seconds later 0101 *than this KStarsDateTime. 0102 *@p s the number of seconds to add. The number can be negative. 0103 */ 0104 KStarsDateTime addSecs(double s) const; 0105 0106 /** 0107 *Modify the Date/Time by adding a number of days. 0108 *@p nd the number of days to add. The number can be negative. 0109 */ 0110 inline KStarsDateTime addDays(int nd) const 0111 { 0112 KStarsDateTime kdt(djd() + static_cast<long double>(nd)); 0113 kdt.setTimeSpec(timeSpec()); 0114 return kdt; 0115 } 0116 0117 inline bool operator==(const KStarsDateTime &d) const 0118 { 0119 return DJD == d.djd(); 0120 } 0121 inline bool operator!=(const KStarsDateTime &d) const 0122 { 0123 return DJD != d.djd(); 0124 } 0125 inline bool operator<(const KStarsDateTime &d) const 0126 { 0127 return DJD < d.djd(); 0128 } 0129 inline bool operator<=(const KStarsDateTime &d) const 0130 { 0131 return DJD <= d.djd(); 0132 } 0133 inline bool operator>(const KStarsDateTime &d) const 0134 { 0135 return DJD > d.djd(); 0136 } 0137 inline bool operator>=(const KStarsDateTime &d) const 0138 { 0139 return DJD >= d.djd(); 0140 } 0141 0142 /** 0143 *@return the date and time according to the CPU clock 0144 */ 0145 static KStarsDateTime currentDateTime(); 0146 0147 /** 0148 *@return the UTC date and time according to the CPU clock 0149 */ 0150 static KStarsDateTime currentDateTimeUtc(); 0151 0152 /** 0153 *@return a KStarsDateTime object parsed from the given string. 0154 *@note This function is format-agnostic; it will try several formats 0155 *when parsing the string. 0156 *@param s the string expressing the date/time to be parsed. 0157 */ 0158 static KStarsDateTime fromString(const QString &s); 0159 0160 /** 0161 *@return the julian day as a long double, including the time as the fractional portion. 0162 */ 0163 inline long double djd() const 0164 { 0165 return DJD; 0166 } 0167 0168 /** 0169 *@return The Greenwich Sidereal Time 0170 *The Greenwich sidereal time is the Right Ascension coordinate that is currently transiting 0171 *the Prime Meridian at the Royal Observatory in Greenwich, UK (longitude=0.0) 0172 */ 0173 dms gst() const; 0174 0175 /** 0176 *Convert a given Greenwich Sidereal Time to Universal Time (=Greenwich Mean Time). 0177 *@p GST the Greenwich Sidereal Time to convert to Universal Time. 0178 */ 0179 QTime GSTtoUT(dms GST) const; // FIXME: Shouldn't this be static? 0180 0181 /** 0182 *@enum EpochType description options 0183 *@note After 1976, the IAU standard for epochs is Julian Years. 0184 */ 0185 enum EpochType 0186 { 0187 JULIAN, /**< Julian epoch (see http://scienceworld.wolfram.com/astronomy/JulianEpoch.html) */ 0188 BESSELIAN, /**< Besselian epoch (see http://scienceworld.wolfram.com/astronomy/BesselianEpoch.html) */ 0189 }; 0190 0191 /** 0192 *@return the (Julian) epoch value of the Date/Time. 0193 *@short This is (approximately) the year expressed as a floating-point value 0194 *@sa setFromEpoch() 0195 *@note The definition of Julian Epoch used here comes from http://scienceworld.wolfram.com/astronomy/JulianEpoch.html 0196 */ 0197 inline double epoch() const 0198 { 0199 return 2000.0 + (djd() - J2000) / 365.25; 0200 } 0201 0202 /** 0203 *Set the Date/Time from an epoch value, represented as a double. 0204 *@p e the epoch value 0205 *@sa epoch() 0206 */ 0207 bool setFromEpoch(double e, EpochType type); 0208 0209 /** 0210 *Set the Date/Time from an epoch value, represented as a string. 0211 *@p e the epoch value 0212 *@return true if date set successfully 0213 *@sa epoch() 0214 */ 0215 bool setFromEpoch(const QString &e); 0216 0217 /** 0218 *Set the Date/Time from an epoch value, represented as a double. 0219 *@p e the epoch value 0220 *@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. 0221 *@sa epoch() 0222 */ 0223 void setFromEpoch(double e); 0224 0225 /** 0226 *@short Takes in an epoch and returns a Julian Date 0227 *@return the Julian Date (date with fraction) 0228 *@param epoch A floating-point year value specifying the Epoch 0229 *@param type JULIAN or BESSELIAN depending on what convention the epoch is specified in 0230 */ 0231 static long double epochToJd(double epoch, EpochType type = JULIAN); 0232 0233 /** 0234 *@short Takes in a Julian Date and returns the corresponding epoch year in the given system 0235 *@return the epoch as a floating-point year value 0236 *@param jd Julian date 0237 *@param type Epoch system (KStarsDateTime::JULIAN or KStarsDateTime::BESSELIAN) 0238 */ 0239 static double jdToEpoch(long double jd, EpochType type = JULIAN); 0240 0241 /** 0242 *@short Takes in a string and returns a Julian epoch 0243 */ 0244 static double stringToEpoch(const QString &eName, bool &ok); 0245 0246 /** 0247 * The following values were obtained from Eric Weisstein's world of science: 0248 * http://scienceworld.wolfram.com/astronomy/BesselianEpoch.html 0249 */ 0250 constexpr static const double B1900 = 2415020.31352; // Julian date of B1900 epoch 0251 constexpr static const double JD_PER_BYEAR = 365.242198781; // Julian days in a Besselian year 0252 private: 0253 /** 0254 *@return the Greenwich Sidereal Time at 0h UT on this object's Date 0255 *@note used internally by gst() and GSTtoUT() 0256 */ 0257 dms GSTat0hUT() const; 0258 0259 long double DJD { 0 }; 0260 };