Kstars

kstarsdatetime.cpp
1 /*
2  SPDX-FileCopyrightText: 2004 Jason Harris <[email protected]>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include "kstarsdatetime.h"
8 
9 #include "dms.h"
10 #include "ksnumbers.h"
11 
12 #include <KLocalizedString>
13 
14 #include <kstars_debug.h>
15 
17 {
19  setDJD(J2000);
20 }
21 
23 {
24  *this = kdt;
25 }
26 
27 KStarsDateTime& KStarsDateTime::operator=(const KStarsDateTime &kdt) noexcept
28 {
29  setDJD(kdt.djd());
30  setTimeSpec(kdt.timeSpec());
31  //utcoffset deprecated
32  //setUtcOffset(kdt.utcOffset());
33  return *this;
34 }
35 
36 /*KStarsDateTime::KStarsDateTime( const QDateTime &kdt ) :
37  QDateTime( kdt )
38 {
39  //don't call setDJD() because we don't need to compute the time; just set DJD directly
40  QTime _t = kdt.time();
41  QDate _d = kdt.date();
42  long double jdFrac = ( _t.hour()-12 + ( _t.minute() + ( _t.second() + _t.msec()/1000.)/60.)/60.)/24.;
43  DJD = static_cast<long double>( _d.toJulianDay() ) + jdFrac;
44 }*/
45 
46 KStarsDateTime::KStarsDateTime(const QDateTime &qdt) : QDateTime(qdt) //, QDateTime::Spec::UTC() )
47 {
48  // FIXME: This method might be buggy. Need to write some tests -- asimha (Oct 2016)
49  QTime _t = qdt.time();
50  QDate _d = qdt.date();
51  long double jdFrac = (_t.hour() - 12 + (_t.minute() + (_t.second() + _t.msec() / 1000.) / 60.) / 60.) / 24.;
52  DJD = static_cast<long double>(_d.toJulianDay()) + jdFrac;
53  setTimeSpec(qdt.timeSpec());
54  //setUtcOffset(qdt.utcOffset());
55 }
56 
57 KStarsDateTime::KStarsDateTime(const QDate &_d, const QTime &_t, Qt::TimeSpec timeSpec)
58  : //QDateTime( _d, _t, QDateTime::Spec::UTC() )
59  QDateTime(_d, _t, timeSpec)
60 {
61  //don't call setDJD() because we don't need to compute the time; just set DJD directly
62  long double jdFrac = (_t.hour() - 12 + (_t.minute() + (_t.second() + _t.msec() / 1000.) / 60.) / 60.) / 24.;
63  DJD = static_cast<long double>(_d.toJulianDay()) + jdFrac;
64 }
65 
67 {
69  setDJD(_jd);
70 }
71 
72 //KStarsDateTime KStarsDateTime::currentDateTime( QDateTime::Spec spec ) {
74 {
76  // if ( dt.time().hour()==0 && dt.time().minute()==0 ) // midnight or right after?
77  // dt.setDate( QDateTime::currentDateTime(spec).date() ); // fetch date again
78 
79  return dt;
80 }
81 
83 {
85  //if ( dt.time().hour()==0 && dt.time().minute()==0 ) // midnight or right after?
86  // dt.setDate( QDateTime::currentDateTime(spec).date() ); // fetch date again
87 
88  return dt;
89 }
90 
92 {
93  //DEBUG
94  qCDebug(KSTARS) << "Date string: " << s;
95 
97 
98  if (dtResult.isValid())
99  return dtResult;
100 
102  if (dtResult.isValid())
103  return dtResult;
104 
105  //dtResult = QDateTime::fromString( s, QDateTime::RFCDate );
107  if (dtResult.isValid())
108  return dtResult;
109 
110  qCWarning(KSTARS) << "Could not parse Date/Time string:" << s;
111  qCWarning(KSTARS) << "Valid date formats:";
112  qCWarning(KSTARS) << " 1950-02-25 ; 1950-02-25T05:30:00";
113  qCWarning(KSTARS) << " 25 Feb 1950 ; 25 Feb 1950 05:30:00";
114  qCWarning(KSTARS) << " Sat Feb 25 1950 ; Sat Feb 25 05:30:00 1950";
115  return KStarsDateTime(QDateTime()); //invalid
116 }
117 
118 void KStarsDateTime::setDJD(long double _jd)
119 {
120  //QDateTime::setTimeSpec( QDateTime::Spec::UTC() );
121  //QDateTime::setTimeSpec(Qt::UTC);
122 
123  DJD = _jd;
124  long int ijd = (long int)_jd;
125  double dayfrac = _jd - (double)ijd + 0.5;
126  if (dayfrac > 1.0)
127  {
128  ijd++;
129  dayfrac -= 1.0;
130  }
131 
132  QDate dd = QDate::fromJulianDay(ijd);
133  QDateTime::setDate(dd);
134 
135  double hour = 24. * dayfrac;
136  int h = int(hour);
137  int m = int(60. * (hour - h));
138  int s = int(60. * (60. * (hour - h) - m));
139  int ms = int(1000. * (60. * (60. * (hour - h) - m) - s));
140 
141  QDateTime::setTime(QTime(h, m, s, ms));
142 }
143 
145 {
146  //Save the JD fraction
147  long double jdFrac = djd() - static_cast<long double>(date().toJulianDay());
148 
149  //set the integer portion of the JD and add back the JD fraction:
150  setDJD(static_cast<long double>(_d.toJulianDay()) + jdFrac);
151 }
152 
154 {
155  long double ds = static_cast<long double>(s) / 86400.;
156  KStarsDateTime kdt(djd() + ds);
157  kdt.setTimeSpec(timeSpec());
158  return kdt;
159 }
160 
162 {
163  KStarsDateTime _dt(date(), _t, timeSpec());
164  setDJD(_dt.djd());
165 }
166 
168 {
169  dms gst0 = GSTat0hUT();
170 
171  double hr = double(time().hour() - offsetFromUtc() / 3600.0);
172  double mn = double(time().minute());
173  double sc = double(time().second()) + double(0.001 * time().msec());
174  double st = (hr + (mn + sc / 60.0) / 60.0) * SIDEREALSECOND;
175 
176  dms gst = dms(gst0.Degrees() + st * 15.0).reduce();
177  return gst;
178 }
179 
180 dms KStarsDateTime::GSTat0hUT() const
181 {
182  double sinOb, cosOb;
183 
184  // Mean greenwich sidereal time
185  KStarsDateTime t0(date(), QTime(0, 0, 0));
186  long double s = t0.djd() - J2000;
187  double t = s / 36525.0;
188  double t1 = 6.697374558 + 2400.051336 * t + 0.000025862 * t * t + 0.000000002 * t * t * t;
189 
190  // To obtain the apparent sidereal time, we have to correct the
191  // mean greenwich sidereal time with nutation in longitude multiplied
192  // by the cosine of the obliquity of the ecliptic. This correction
193  // is called nutation in right ascention, and may amount to 0.3 secs.
194  KSNumbers num(t0.djd());
195  num.obliquity()->SinCos(sinOb, cosOb);
196 
197  // nutLong has to be in hours of time since t1 is hours of time.
198  double nutLong = num.dEcLong() * cosOb / 15.0;
199  t1 += nutLong;
200 
201  dms gst;
202  gst.setH(t1);
203  return gst.reduce();
204 }
205 
207 {
208  dms gst0 = GSTat0hUT();
209 
210  //dt is the number of sidereal hours since UT 0h.
211  double dt = GST.Hours() - gst0.Hours();
212  while (dt < 0.0)
213  dt += 24.0;
214  while (dt >= 24.0)
215  dt -= 24.0;
216 
217  //convert to solar time. dt is now the number of hours since 0h UT.
218  dt /= SIDEREALSECOND;
219 
220  int hr = int(dt);
221  int mn = int(60.0 * (dt - double(hr)));
222  int sc = int(60.0 * (60.0 * (dt - double(hr)) - double(mn)));
223  int ms = int(1000.0 * (60.0 * (60.0 * (dt - double(hr)) - double(mn)) - double(sc)));
224 
225  return (QTime(hr, mn, sc, ms));
226 }
227 
229 {
230  if (epoch == 1950.0) // Assume Besselian
232  else
233  setFromEpoch(epoch, JULIAN); // Assume Julian
234 }
235 
236 bool KStarsDateTime::setFromEpoch(double epoch, EpochType type)
237 {
238  if (type != JULIAN && type != BESSELIAN)
239  return false;
240  else
241  setDJD(epochToJd(epoch, type));
242  return true;
243 }
244 
246 {
247  bool result;
248  double epoch;
249  epoch = stringToEpoch(eName, result);
250 
251  if (!result)
252  return false;
253  return setFromEpoch(epoch, JULIAN); // We've already converted
254 }
255 
256 long double KStarsDateTime::epochToJd(double epoch, EpochType type)
257 {
258  switch (type)
259  {
260  case BESSELIAN:
261  return B1900 + (epoch - 1900.0) * JD_PER_BYEAR;
262  case JULIAN:
263  return J2000 + (epoch - 2000.0) * 365.25;
264  default:
265  return NaN::d;
266  }
267 }
268 
270 {
271  // Definitions for conversion formulas are from:
272  //
273  // * http://scienceworld.wolfram.com/astronomy/BesselianEpoch.html
274  // * http://scienceworld.wolfram.com/astronomy/JulianEpoch.html
275  //
276 
277  switch (type)
278  {
280  return 1900.0 + (jd - KStarsDateTime::B1900) / KStarsDateTime::JD_PER_BYEAR;
282  return 2000.0 + (jd - J2000) / 365.24;
283  default:
284  return NaN::d;
285  }
286 }
287 
288 double KStarsDateTime::stringToEpoch(const QString &eName, bool &ok)
289 {
290  double epoch = J2000;
291  ok = false;
292 
293  if (eName.isEmpty()) // By default, assume J2000
294  return epoch;
295 
296  if (eName.startsWith('J'))
297  epoch = eName.midRef(1).toDouble(&ok);
298  else if (eName.startsWith('B'))
299  {
300  epoch = eName.midRef(1).toDouble(&ok);
301  epoch = jdToEpoch(epochToJd(epoch, BESSELIAN), JULIAN); // Convert Besselian epoch to Julian epoch
302  }
303  // Assume it's Julian
304  else
305  epoch = eName.toDouble(&ok);
306 
307  return epoch;
308 }
KStarsDateTime()
Default constructor Creates a date/time at J2000 (noon on Jan 1, 200)
static KStarsDateTime currentDateTime()
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
long double djd() const
QDateTime currentDateTime()
QStringRef midRef(int position, int n) const const
QTime time() const const
@ BESSELIAN
Besselian epoch (see http://scienceworld.wolfram.com/astronomy/BesselianEpoch.html)
static KStarsDateTime fromString(const QString &s)
QDateTime currentDateTimeUtc()
static KStarsDateTime currentDateTimeUtc()
constexpr static const double B1900
The following values were obtained from Eric Weisstein's world of science: http://scienceworld....
KStarsDateTime addSecs(double s) const
void setDate(const QDate &date)
void setTime(const QTime &t)
Assign the Time according to a QTime object.
virtual void setH(const double &x)
Sets floating-point value of angle, in hours.
Definition: dms.h:210
bool setFromEpoch(double e, EpochType type)
Set the Date/Time from an epoch value, represented as a double.
double epoch() const
This is (approximately) the year expressed as a floating-point value.
Store several time-dependent astronomical quantities.
Definition: ksnumbers.h:42
double toDouble(bool *ok) const const
static double jdToEpoch(long double jd, EpochType type=JULIAN)
Takes in a Julian Date and returns the corresponding epoch year in the given system.
static double stringToEpoch(const QString &eName, bool &ok)
Takes in a string and returns a Julian epoch.
bool isEmpty() const const
void setTimeSpec(Qt::TimeSpec spec)
int msec() const const
qint64 toJulianDay() const const
QDateTime fromString(const QString &string, Qt::DateFormat format)
static long double epochToJd(double epoch, EpochType type=JULIAN)
Takes in an epoch and returns a Julian Date.
int hour() const const
double toDouble(bool *ok) const const
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
void setDate(const QDate &d)
Assign the Date according to a QDate object.
An angle, stored as degrees, but expressible in many ways.
Definition: dms.h:37
int second() const const
@ JULIAN
Julian epoch (see http://scienceworld.wolfram.com/astronomy/JulianEpoch.html)
const double & Degrees() const
Definition: dms.h:141
int offsetFromUtc() const const
Qt::TimeSpec timeSpec() const const
QDate date() const const
bool isValid() const const
QDate fromJulianDay(qint64 jd)
const dms reduce() const
return the equivalent angle between 0 and 360 degrees.
Definition: dms.cpp:251
QTime GSTtoUT(dms GST) const
Convert a given Greenwich Sidereal Time to Universal Time (=Greenwich Mean Time).
int minute() const const
void setTime(const QTime &time)
double Hours() const
Definition: dms.h:168
TextDate
void setDJD(long double jd)
Assign the static_cast<long double> Julian Day value, which includes the time of day encoded in the f...
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Jun 5 2023 03:56:17 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.