FACT++  1.0
Time.cc
Go to the documentation of this file.
1 // **************************************************************************
26 // **************************************************************************
27 #include "Time.h"
28 
29 #ifdef HAVE_LIBNOVA
30 #include "../externals/nova.h"
31 #endif
32 
33 using namespace std;
34 using namespace boost::posix_time;
35 
36 const boost::gregorian::date Time::fUnixOffset(1970, 1, 1);
37 
39 
40 // strftime
41 const _time_format Time::reset = 0;
42 const _time_format Time::def = "%c";
43 const _time_format Time::std = "%x %X%F";
44 const _time_format Time::sql = "%Y-%m-%d %H:%M:%S.%f";
45 const _time_format Time::ssql = "%Y-%m-%d %H:%M:%S";
46 const _time_format Time::iso = "%Y-%m-%dT%H:%M:%S%F%q";
47 const _time_format Time::magic = "%Y %m %d %H %M %S %f";
48 const _time_format Time::smagic = "%Y %m %d %H %M %S";
49 
50 // --------------------------------------------------------------------------
51 //
57 //
58 Time::Time(enum init_t typ)
59 {
60  switch (typ)
61  {
62  case utc:
63  *this = microsec_clock::universal_time();
64  break;
65  case local:
66  *this = microsec_clock::local_time();
67  break;
68  case none:
69  break;
70  }
71 }
72 
73 
74 // --------------------------------------------------------------------------
75 //
87 //
88 Time::Time(const boost::date_time::special_values &val) : ptime(val)
89 {
90 }
91 
92 // --------------------------------------------------------------------------
93 //
102 //
103 Time::Time(const time_t &tm, const suseconds_t &usec)
104 : ptime(fUnixOffset, time_duration(0, 0, tm, usec*pow(10, time_duration::num_fractional_digits()-6)))
105 {
106 }
107 
108 // --------------------------------------------------------------------------
109 //
115 Time::Time(const timeval &tv)
116 : ptime(fUnixOffset, time_duration(0, 0, tv.tv_sec, tv.tv_usec*pow(10, time_duration::num_fractional_digits()-6)))
117 {
118 }
119 
120 // --------------------------------------------------------------------------
121 //
128 Time::Time(short year, unsigned char month, unsigned char day,
129  unsigned char hh, unsigned char mm, unsigned char ss, unsigned int microsec)
130 // Last argument is fractional_seconds ( correct with num_fractional_digits() )
131 : ptime(boost::gregorian::date(year, month, day),
132  time_duration(hh, mm, ss, microsec*pow(10, time_duration::num_fractional_digits()-6)))
133 {
134 }
135 
136 // --------------------------------------------------------------------------
137 //
145 void Time::Mjd(double mjd)
146 {
147  if (mjd > 2400000.5)
148  mjd -= 2400000.5;
149 
150  // Convert MJD to ticks since offset
151  mjd -= 40587;
152  mjd *= 24*60*60*time_duration::ticks_per_second();
153 
154  *this = ptime(fUnixOffset, time_duration(0, 0, 0, mjd));
155 }
156 
157 // --------------------------------------------------------------------------
158 //
161 double Time::SecondsOfDay() const
162 {
163  const time_duration tod = time_of_day();
164 
165  const double frac = double(tod.fractional_seconds())/time_duration::ticks_per_second();
166  const double sec = tod.total_seconds()+frac;
167 
168  return sec;
169 }
170 
171 // --------------------------------------------------------------------------
172 //
180 double Time::Mjd() const
181 {
182  return date().modjulian_day()+SecondsOfDay()/(24*60*60);
183 
184  /*
185  const time_duration mjd = *this - ptime(fUnixOffset);
186  const double sec = mjd.total_seconds()+mjd.fractional_seconds()/1e6;
187  return sec/(24*60*60)+40587;
188  */
189 }
190 
191 // --------------------------------------------------------------------------
192 //
193 // @returns seconds since 1970/1/1
194 //
195 double Time::UnixTime() const
196 {
197  return (date().modjulian_day()-40587)*24*60*60 + SecondsOfDay();
198 }
199 
200 // --------------------------------------------------------------------------
201 //
202 // @returns days since 1970/1/1
203 //
204 double Time::UnixDate() const
205 {
206  return (date().modjulian_day()-40587) + SecondsOfDay()/(24*60*60);
207 }
208 
209 // --------------------------------------------------------------------------
210 //
211 // @returns seconds since 1970/1/1
212 //
213 time_t Time::Time_t() const
214 {
215  return (date().modjulian_day()-40587)*24*60*60 + time_of_day().total_seconds();
216 }
217 
218 // --------------------------------------------------------------------------
219 //
222 double Time::RootTime() const
223 {
224  return (date().modjulian_day()-49718)*24*60*60 + SecondsOfDay();
225 }
226 
227 // --------------------------------------------------------------------------
228 //
239 //
240 string Time::GetAsStr(const char *format) const
241 {
242  stringstream out;
243  out << Time::fmt(format) << *this;
244  return out.str();
245 }
246 
247 // --------------------------------------------------------------------------
248 //
252 //
253 string Time::Iso() const
254 {
255  stringstream out;
256  out << Time::iso << *this;
257  return out.str();
258 }
259 
260 // --------------------------------------------------------------------------
261 //
273 void Time::SetFromStr(const string &str, const char *format)
274 {
275  // FIXME: exception handline
276  stringstream stream;
277  stream << str;
278  stream >> Time::fmt(format) >> *this;
279 }
280 
281 string Time::MinutesTo(const Time &time) const
282 {
283  ostringstream str;
284  if (time>*this)
285  str << time-*this;
286  else
287  str << *this-time;
288  return str.str().substr(0, 5);
289 }
290 
291 string Time::SecondsTo(const Time &time) const
292 {
293  ostringstream str;
294  if (time>*this)
295  str << time-*this;
296  else
297  str << *this-time;
298  return str.str().substr(str.str().substr(0, 3)=="00:" ? 3 : 0, 5);
299 }
300 
301 // --------------------------------------------------------------------------
302 //
312 //
313 Time Time::GetPrevSunRise(double horizon) const
314 {
315 #ifdef HAVE_LIBNOVA
316  Nova::LnLatPosn obs = Nova::ORM();
317 
318  ln_rst_time sun_day;
319  if (ln_get_solar_rst_horizon(JD()-0.5, &obs, horizon, &sun_day)==1)
320  throw runtime_error("ln_get_solar_rst_horizon reported the sun to be circumpolar at the coordinates of La Palma!");
321 
322  if (Time(sun_day.rise)<*this)
323  return Time(sun_day.rise);
324 
325  if (ln_get_solar_rst_horizon(JD()-1.5, &obs, horizon, &sun_day)==1)
326  throw runtime_error("ln_get_solar_rst_horizon reported the sun to be circumpolar at the coordinates of La Palma!");
327 
328  return Time(sun_day.rise);
329 #else
330  return Time(floor(Mjd()-0.5)+0.5);
331 #endif
332 }
333 
334 // --------------------------------------------------------------------------
335 //
345 //
346 Time Time::GetNextSunRise(double horizon) const
347 {
348 #ifdef HAVE_LIBNOVA
349  Nova::LnLatPosn obs = Nova::ORM();
350 
351  ln_rst_time sun_day;
352  if (ln_get_solar_rst_horizon(JD()-0.5, &obs, horizon, &sun_day)==1)
353  throw runtime_error("ln_get_solar_rst_horizon reported the sun to be circumpolar at the coordinates of La Palma!");
354 
355  if (Time(sun_day.rise)>=*this)
356  return Time(sun_day.rise);
357 
358  if (ln_get_solar_rst_horizon(JD()+0.5, &obs, horizon, &sun_day)==1)
359  throw runtime_error("ln_get_solar_rst_horizon reported the sun to be circumpolar at the coordinates of La Palma!");
360 
361  return Time(sun_day.rise);
362 #else
363  return Time(floor(Mjd()+0.5))+0.5;
364 #endif
365 }
366 
367 // --------------------------------------------------------------------------
368 //
370 //
372 {
373  return GetPrevSunRise(LN_SOLAR_STANDART_HORIZON);
374 }
375 
376 // --------------------------------------------------------------------------
377 //
379 //
381 {
382  return GetNextSunRise(LN_SOLAR_STANDART_HORIZON);
383 }
384 
385 // --------------------------------------------------------------------------
386 //
396 //
397 uint32_t Time::NightAsInt() const
398 {
399  const Time tm = GetPrevSunRise();
400  return tm.Y()*10000 + tm.M()*100 + tm.D();
401 }
402 
403 // --------------------------------------------------------------------------
404 //
415 const _time_format Time::fmt(const char *format)
416 {
417  return format;
418 }
419 
420 // --------------------------------------------------------------------------
421 //
440 ostream &operator<<(ostream &out, const _time_format &f)
441 {
442  const locale loc(locale::classic(),
443  f.ptr==0 ? 0 : new time_facet(f.ptr));
444 
445  out.imbue(loc);
446 
447  return out;
448 }
449 
450 // --------------------------------------------------------------------------
451 //
473 istream &operator>>(istream &in, const _time_format &f)
474 {
475  const locale loc(locale::classic(),
476  f.ptr==0 ? 0 : new time_input_facet(f.ptr));
477 
478  in.imbue(loc);
479 
480  return in;
481 }
unsigned short M() const
Definition: Time.h:95
static const _time_format sql
set to format to the iso standard
Definition: Time.h:42
Time(enum init_t type=utc)
Definition: Time.cc:58
std::string Iso() const
Definition: Time.cc:253
const LnLatPosn & ORM()
Definition: nova.h:66
Adds some functionality to boost::posix_time::ptime for our needs.
Definition: Time.h:30
char str[80]
Definition: test_client.c:7
const char * ptr
Definition: Time.h:22
uint32_t NightAsInt() const
Definition: Time.cc:397
static const _time_format iso
set to format to the sql format (without the fraction of seconds)
Definition: Time.h:44
STL namespace.
static const _time_format reset
Definition: Time.h:39
unsigned short Y() const
Definition: Time.h:94
std::string SecondsTo(const Time &=Time()) const
Definition: Time.cc:291
double SecondsOfDay() const
Definition: Time.cc:161
static const _time_format ssql
set to format to the sql format
Definition: Time.h:43
static const _time_format magic
set to format to the extended iso standard
Definition: Time.h:45
double JD() const
Definition: Time.h:87
Time GetPrevSunRise() const
Calls GetPrevSunRise(LN_SOLAR_STANDART_HORIZON)
Definition: Time.cc:371
Helper to manipulate the input and output format of a time in a stream.
Definition: Time.h:17
time_t Time_t() const
Definition: Time.cc:213
std::string str() const
Definition: Time.h:27
static const boost::gregorian::date fUnixOffset
Points to the famous 1/1/1970, the standard offset for unix times.
Definition: Time.h:58
double Mjd() const
Definition: Time.cc:180
static const _time_format def
Remove the format description from the stream.
Definition: Time.h:40
double UnixTime() const
Definition: Time.cc:195
double RootTime() const
Definition: Time.cc:222
Warning because the service this data corrsponds to might have been last updated longer ago than Local time
Definition: smartfact.txt:92
ostream & operator<<(ostream &out, const _time_format &f)
Definition: Time.cc:440
static const Time None
A none-time, this can be used as a simple representation of an invalid time.
Definition: Time.h:34
static const _time_format fmt(const char *txt=0)
A stream manipulator to set the output/input format.
Definition: Time.cc:415
double UnixDate() const
Definition: Time.cc:204
void SetFromStr(const std::string &str, const char *fmt="%Y-%m-%d %H:%M:%S")
Definition: Time.cc:273
unsigned short D() const
Definition: Time.h:96
ln_lnlat_posn LnLatPosn
Definition: nova.h:12
static const _time_format std
set to format to the locale default
Definition: Time.h:41
Time GetNextSunRise() const
Calls GetNextSunRise(LN_SOLAR_STANDART_HORIZON)
Definition: Time.cc:380
istream & operator>>(istream &in, const _time_format &f)
Definition: Time.cc:473
std::string MinutesTo(const Time &=Time()) const
Definition: Time.cc:281
std::string GetAsStr(const char *fmt="%Y-%m-%d %H:%M:%S") const
Definition: Time.cc:240
static const _time_format smagic
set to format to the MAGIC report format
Definition: Time.h:46
Do not initialize the time.
Definition: Time.h:51
init_t
set to format to the MAGIC report format (without the fraction of seconds)
Definition: Time.h:49