source: trunk/FACT++/src/Time.cc @ 10454

Last change on this file since 10454 was 10454, checked in by tbretz, 9 years ago
Added GetUnixTime
File size: 8.0 KB
Line 
1// **************************************************************************
2/** @class Time
3
4@brief Adds some functionality to boost::posix_time::ptime for our needs
5
6This is basically a wrapper around boost::posix_time::ptime which is made
7to adapt the functionality to our needs. Time can store the current
8data and time with a precision up to nanoseconds if provided by the
9undrlaying system, otherwise microsecond precision is used.
10
11It main purpose is to provide needed constructors and simplyfy the
12conversion of dates and times from and to a string/stream.
13
14Note that posix_time (as Posix times have) has a limited range. You cannot
15use it for example for very early years of the last century.
16
17@section Examples
18
19 - An example can be found in \ref time.cc
20
21@section References
22
23 - <A HREF="http://www.boost.org/doc/libs/1_45_0/doc/html/date_time.html">BOOST++ date_time (V1.45.0)</A>
24
25**/
26// **************************************************************************
27#include "Time.h"
28
29using namespace std;
30using namespace boost::posix_time;
31
32const boost::gregorian::date Time::fUnixOffset(1970, 1, 1);
33
34const Time Time::None(Time::none);
35
36// strftime
37const _time_format Time::reset  = 0;
38const _time_format Time::def    = "%c";
39const _time_format Time::std    = "%x %X%F";
40const _time_format Time::sql    = "%Y-%m-%d %H:%M:%S.%f";
41const _time_format Time::ssql   = "%Y-%m-%d %H:%M:%S";
42const _time_format Time::iso    = "%Y%m%dT%H%M%S%F%q";
43const _time_format Time::magic  = "%Y %m %d %H %M %S %f";
44const _time_format Time::smagic = "%Y %m %d %H %M %S";
45
46/*
47 using date_time::special_values;
48 using date_time::not_special;
49 using date_time::neg_infin;
50 using date_time::pos_infin;
51 using date_time::not_a_date_time;
52 using date_time::max_date_time;
53 using date_time::min_date_time;
54 */
55
56// --------------------------------------------------------------------------
57//
58//! Construct a Time object with either UTC or local time, or without any
59//! particular time.
60//!
61//! @param typ
62//!    enum as defined in Time::init_t
63//
64Time::Time(enum init_t typ)
65{
66    switch (typ)
67    {
68    case utc:
69        *this = microsec_clock::universal_time();
70        break;
71    case local:
72        *this = microsec_clock::local_time();
73        break;
74    case none:
75        break;
76    }
77}
78
79// --------------------------------------------------------------------------
80//
81//! Construct a Time object from seconds since 1970/1/1 and number of
82//! milliseconds, as for example returned by gettimeofday()
83//!
84//! @param tm
85//!    seconds since 1970/1/1
86//!
87//! @param millisec
88//!    number of milliseconds
89//
90Time::Time(const time_t &tm, const int &millisec)
91: ptime(fUnixOffset, time_duration(0, 0, tm, millisec))
92{
93}
94
95// --------------------------------------------------------------------------
96//
97//! Construct a Time from a date and time.
98//!
99//! @param year, month, day, hh, mm, ss, microsec
100//!    A full date and time down to microsecond precision. From the end
101//!    arguments can be omitted.
102//!
103Time::Time(short year, unsigned char month, unsigned char day,
104           unsigned char hh, unsigned char mm, unsigned char ss, unsigned int microsec)
105// Last argument is fractional_seconds ( correct with num_fractional_digits() )
106: ptime(boost::gregorian::date(year, month, day),
107        time_duration(hh, mm, ss, microsec*pow(10, time_of_day().num_fractional_digits()-6)))
108{
109}
110
111// --------------------------------------------------------------------------
112//
113//! Set the Time object to a given MJD. Note that this involves
114//! conversion from double. So converting forth and back many many
115//! times might results in drifts.
116//!
117//! @param mjd
118//!    Modified Julian Date
119//!
120void Time::Mjd(double mjd)
121{
122    // Convert MJD to seconds since offset
123    mjd -= 40587;
124    mjd *= 24*60*60;
125
126    const int exp = time_of_day().num_fractional_digits();
127    const double frac = fmod(mjd, 1)*pow(10, exp);
128
129    *this = ptime(fUnixOffset, time_duration(0, 0, mjd, frac));
130}
131
132// --------------------------------------------------------------------------
133//
134//! Get the current MJD. Note that this involves
135//! conversion to double. So converting forth and back many many
136//! times might results in drifts.
137//!
138//! @returns
139//!    Modified Julian Date
140//!
141double Time::Mjd() const
142{
143    const time_duration tod = time_of_day();
144
145    const int exp = tod.num_fractional_digits();
146
147    const double frac = tod.fractional_seconds()/pow(10, exp);
148    const double sec  = tod.total_seconds()+frac;
149
150    return date().modjulian_day()+sec/(24*60*60);
151
152    /*
153     const time_duration mjd = *this - ptime(fUnixOffset);
154     const double sec = mjd.total_seconds()+mjd.fractional_seconds()/1e6;
155     return sec/(24*60*60)+40587;
156     */
157}
158
159// --------------------------------------------------------------------------
160//
161// Return seconds since 1970/1/1
162//
163time_t Time::GetUnixTime() const
164{
165    const time_duration unx = *this - ptime(fUnixOffset);
166    return unx.total_seconds();
167}
168
169// --------------------------------------------------------------------------
170//
171//! Returns a string with the contents of the Time object formated
172//! as defined in format.
173//!
174//! @param format
175//!    format description of the string to be returned. For details
176//!    see the boost documentation or the man page of strftime
177//!
178//! @returns
179//!    A string with the time formatted as requested. Note some special
180//!    strings might be returned in case the time is invalid.
181//
182string Time::GetAsStr(const char *format) const
183{
184    stringstream out;
185    out << Time::fmt(format) << *this;
186    return out.str();
187}
188
189// --------------------------------------------------------------------------
190//
191//! Sets the time of the Time object to a time corresponding to
192//! the one given as argument. It is evaluated according to the given
193//! format.
194//!
195//! @param str
196//!    The time as a string which should be converted to the Time object
197//!
198//! @param format
199//!    format description of the string to be returned. For details
200//!    see the boost documentation or the man page of strftime
201//!
202void Time::SetFromStr(const string &str, const char *format)
203{
204    // FIXME: exception handline
205    stringstream stream;
206    stream << str;
207    stream >> Time::fmt(format) >> *this;
208}
209
210// --------------------------------------------------------------------------
211//
212//! A stream manipulator which sets the streams Time output format
213//! as defined in the argument.
214//!
215//! @param format
216//!    format description of the manipulator be returned. For details
217//!    see the boost documentation or the man page of strftime
218//!
219//! @returns
220//!    a stream manipulator for the given format
221//!
222const _time_format Time::fmt(const char *format)
223{
224    return format;
225}
226
227// --------------------------------------------------------------------------
228//
229//! Sets the locale discription of the stream (the way how a time is
230//! output) to the format defined by the given manipulator.
231//!
232//! Example:
233//! \code
234//!    Time t();
235//!    cout << Time::fmt("%Y:%m:%d %H:%M:%S.%f") << t << endl;
236//! \endcode
237//!
238//! @param out
239//!    Reference to the stream
240//!
241//! @param f
242//!    Time format described by a manipulator
243//!
244//! @returns
245//!    A reference to the stream
246//!
247ostream &operator<<(ostream &out, const _time_format &f)
248{
249    const locale loc(locale::classic(),
250                     f.ptr==0 ? 0 : new time_facet(f.ptr));
251
252    out.imbue(loc);
253
254    return out;
255}
256
257// --------------------------------------------------------------------------
258//
259//! Sets the locale discription of the stream (the way how a time is
260//! input) to the format defined by the given manipulator.
261//!
262//! Example:
263//! \code
264//!    stringstream s;
265//!    s << "09.09.1974 21:59";
266//!
267//!    Time t;
268//!    s >> Time::fmt("%d.%m.%Y %H:%M") >> t;
269//! \endcode
270//!
271//! @param in
272//!    Reference to the stream
273//!
274//! @param f
275//!    Time format described by a manipulator
276//!
277//! @returns
278//!    A reference to the stream
279//!
280istream &operator>>(istream &in, const _time_format &f)
281{
282    const locale loc(locale::classic(),
283                     f.ptr==0 ? 0 : new time_input_facet(f.ptr));
284
285    in.imbue(loc);
286
287    return in;
288}
289
Note: See TracBrowser for help on using the repository browser.