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

Last change on this file since 10183 was 10183, checked in by tbretz, 10 years ago
New import.
File size: 7.5 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::iso   = "%Y%m%dT%H%M%S%F%q";
42const _time_format Time::magic = "%Y %m %d %H %M %S %f";
43
44/*
45 using date_time::special_values;
46 using date_time::not_special;
47 using date_time::neg_infin;
48 using date_time::pos_infin;
49 using date_time::not_a_date_time;
50 using date_time::max_date_time;
51 using date_time::min_date_time;
52 */
53
54// --------------------------------------------------------------------------
55//
56//! Construct a Time object with either UTC or local time, or without any
57//! particular time.
58//!
59//! @param typ
60//!    enum as defined in Time::init_t
61//
62Time::Time(enum init_t typ)
63{
64    switch (typ)
65    {
66    case utc:
67        *this = microsec_clock::universal_time();
68        break;
69    case local:
70        *this = microsec_clock::local_time();
71        break;
72    case none:
73        break;
74    }
75}
76
77// --------------------------------------------------------------------------
78//
79//! Construct a Time object from seconds since 1970/1/1 and number of
80//! milliseconds, as for example returned by gettimeofday()
81//!
82//! @param tm
83//!    seconds since 1970/1/1
84//!
85//! @param millisec
86//!    number of milliseconds
87//
88Time::Time(const time_t &tm, const int &millisec)
89: ptime(fUnixOffset, time_duration(0, 0, tm, millisec))
90{
91}
92
93// --------------------------------------------------------------------------
94//
95//! Construct a Time from a date and time.
96//!
97//! @param year, month, day, hh, mm, ss, microsec
98//!    A full date and time down to microsecond precision. From the end
99//!    arguments can be omitted.
100//!
101Time::Time(short year, unsigned char month, unsigned char day,
102           unsigned char hh, unsigned char mm, unsigned char ss, unsigned int microsec)
103// Last argument is fractional_seconds ( correct with num_fractional_digits() )
104: ptime(boost::gregorian::date(year, month, day),
105        time_duration(hh, mm, ss, microsec*pow(10, time_of_day().num_fractional_digits()-6)))
106{
107}
108
109// --------------------------------------------------------------------------
110//
111//! Set the Time object to a given MJD. Note that this involves
112//! conversion from double. So converting forth and back many many
113//! times might results in drifts.
114//!
115//! @param mjd
116//!    Modified Julian Date
117//!
118void Time::Mjd(double mjd)
119{
120    mjd -= 40587;
121    mjd *= 24*60*60;
122
123    const int exp = time_of_day().num_fractional_digits();
124    const double frac = fmod(mjd, 1)*pow(10, exp);
125
126    *this = ptime(fUnixOffset, time_duration(0, 0, mjd, frac));
127}
128
129// --------------------------------------------------------------------------
130//
131//! Get the current MJD. Note that this involves
132//! conversion to double. So converting forth and back many many
133//! times might results in drifts.
134//!
135//! @returns
136//!    Modified Julian Date
137//!
138double Time::Mjd() const
139{
140    const time_duration tod = time_of_day();
141
142    const int exp = tod.num_fractional_digits();
143    const double sec = tod.fractional_seconds()/pow(10, exp);
144
145    return date().modjulian_day()+sec/(24*60*60);
146
147    /*
148     const time_duration mjd = *this - ptime(fUnixOffset);
149     const double sec = mjd.total_seconds()+mjd.fractional_seconds()/1e6;
150     return sec/(24*60*60)+40587;
151     */
152}
153
154// --------------------------------------------------------------------------
155//
156//! Returns a string with the contents of the Time object formated
157//! as defined in format.
158//!
159//! @param format
160//!    format description of the string to be returned. For details
161//!    see the boost documentation or the man page of strftime
162//!
163//! @returns
164//!    A string with the time formatted as requested. Note some special
165//!    strings might be returned in case the time is invalid.
166//
167string Time::GetAsStr(const char *format) const
168{
169    stringstream out;
170    out << Time::fmt(format) << *this;
171    return out.str();
172}
173
174// --------------------------------------------------------------------------
175//
176//! Sets the time of the Time object to a time corresponding to
177//! the one given as argument. It is evaluated according to the given
178//! format.
179//!
180//! @param str
181//!    The time as a string which should be converted to the Time object
182//!
183//! @param format
184//!    format description of the string to be returned. For details
185//!    see the boost documentation or the man page of strftime
186//!
187void Time::SetFromStr(const string &str, const char *format)
188{
189    // FIXME: exception handline
190    stringstream stream;
191    stream << str;
192    stream >> Time::fmt(format) >> *this;
193}
194
195// --------------------------------------------------------------------------
196//
197//! A stream manipulator which sets the streams Time output format
198//! as defined in the argument.
199//!
200//! @param format
201//!    format description of the manipulator be returned. For details
202//!    see the boost documentation or the man page of strftime
203//!
204//! @returns
205//!    a stream manipulator for the given format
206//!
207const _time_format Time::fmt(const char *format)
208{
209    return format;
210}
211
212// --------------------------------------------------------------------------
213//
214//! Sets the locale discription of the stream (the way how a time is
215//! output) to the format defined by the given manipulator.
216//!
217//! Example:
218//! \code
219//!    Time t();
220//!    cout << Time::fmt("%Y:%m:%d %H:%M:%S.%f") << t << endl;
221//! \endcode
222//!
223//! @param out
224//!    Reference to the stream
225//!
226//! @param f
227//!    Time format described by a manipulator
228//!
229//! @returns
230//!    A reference to the stream
231//!
232ostream &operator<<(ostream &out, const _time_format &f)
233{
234    const locale loc(locale::classic(),
235                     f.ptr==0 ? 0 : new time_facet(f.ptr));
236
237    out.imbue(loc);
238
239    return out;
240}
241
242// --------------------------------------------------------------------------
243//
244//! Sets the locale discription of the stream (the way how a time is
245//! input) to the format defined by the given manipulator.
246//!
247//! Example:
248//! \code
249//!    stringstream s;
250//!    s << "09.09.1974 21:59";
251//!
252//!    Time t;
253//!    s >> Time::fmt("%d.%m.%Y %H:%M") >> t;
254//! \endcode
255//!
256//! @param in
257//!    Reference to the stream
258//!
259//! @param f
260//!    Time format described by a manipulator
261//!
262//! @returns
263//!    A reference to the stream
264//!
265istream &operator>>(istream &in, const _time_format &f)
266{
267    const locale loc(locale::classic(),
268                     f.ptr==0 ? 0 : new time_input_facet(f.ptr));
269
270    in.imbue(loc);
271
272    return in;
273}
Note: See TracBrowser for help on using the repository browser.