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

Last change on this file since 10619 was 10469, checked in by tbretz, 14 years ago
Fixed a typo. I have no idea why that compiled here.
File size: 8.4 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//! @returns the seconds of the day including the fractional seconds.
135//!
136double Time::SecondsOfDay() const
137{
138 const time_duration tod = time_of_day();
139
140 const int exp = tod.num_fractional_digits();
141
142 const double frac = tod.fractional_seconds()/pow(10, exp);
143 const double sec = tod.total_seconds()+frac;
144
145 return sec;
146}
147
148// --------------------------------------------------------------------------
149//
150//! Get the current MJD. Note that this involves
151//! conversion to double. So converting forth and back many many
152//! times might results in drifts.
153//!
154//! @returns
155//! Modified Julian Date
156//!
157double Time::Mjd() const
158{
159 return date().modjulian_day()+SecondsOfDay()/(24*60*60);
160
161 /*
162 const time_duration mjd = *this - ptime(fUnixOffset);
163 const double sec = mjd.total_seconds()+mjd.fractional_seconds()/1e6;
164 return sec/(24*60*60)+40587;
165 */
166}
167
168// --------------------------------------------------------------------------
169//
170// @returns seconds since 1970/1/1
171//
172double Time::UnixTime() const
173{
174 return (date().modjulian_day()-40587)*24*60*60 + SecondsOfDay();
175}
176
177// --------------------------------------------------------------------------
178//
179//! @returns the time in a format needed for root's TAxis
180//!
181double Time::RootTime() const
182{
183 return (date().modjulian_day()-49718)*24*60*60 + SecondsOfDay();
184}
185
186// --------------------------------------------------------------------------
187//
188//! Returns a string with the contents of the Time object formated
189//! as defined in format.
190//!
191//! @param format
192//! format description of the string to be returned. For details
193//! see the boost documentation or the man page of strftime
194//!
195//! @returns
196//! A string with the time formatted as requested. Note some special
197//! strings might be returned in case the time is invalid.
198//
199string Time::GetAsStr(const char *format) const
200{
201 stringstream out;
202 out << Time::fmt(format) << *this;
203 return out.str();
204}
205
206// --------------------------------------------------------------------------
207//
208//! Sets the time of the Time object to a time corresponding to
209//! the one given as argument. It is evaluated according to the given
210//! format.
211//!
212//! @param str
213//! The time as a string which should be converted to the Time object
214//!
215//! @param format
216//! format description of the string to be returned. For details
217//! see the boost documentation or the man page of strftime
218//!
219void Time::SetFromStr(const string &str, const char *format)
220{
221 // FIXME: exception handline
222 stringstream stream;
223 stream << str;
224 stream >> Time::fmt(format) >> *this;
225}
226
227// --------------------------------------------------------------------------
228//
229//! A stream manipulator which sets the streams Time output format
230//! as defined in the argument.
231//!
232//! @param format
233//! format description of the manipulator be returned. For details
234//! see the boost documentation or the man page of strftime
235//!
236//! @returns
237//! a stream manipulator for the given format
238//!
239const _time_format Time::fmt(const char *format)
240{
241 return format;
242}
243
244// --------------------------------------------------------------------------
245//
246//! Sets the locale discription of the stream (the way how a time is
247//! output) to the format defined by the given manipulator.
248//!
249//! Example:
250//! \code
251//! Time t();
252//! cout << Time::fmt("%Y:%m:%d %H:%M:%S.%f") << t << endl;
253//! \endcode
254//!
255//! @param out
256//! Reference to the stream
257//!
258//! @param f
259//! Time format described by a manipulator
260//!
261//! @returns
262//! A reference to the stream
263//!
264ostream &operator<<(ostream &out, const _time_format &f)
265{
266 const locale loc(locale::classic(),
267 f.ptr==0 ? 0 : new time_facet(f.ptr));
268
269 out.imbue(loc);
270
271 return out;
272}
273
274// --------------------------------------------------------------------------
275//
276//! Sets the locale discription of the stream (the way how a time is
277//! input) to the format defined by the given manipulator.
278//!
279//! Example:
280//! \code
281//! stringstream s;
282//! s << "09.09.1974 21:59";
283//!
284//! Time t;
285//! s >> Time::fmt("%d.%m.%Y %H:%M") >> t;
286//! \endcode
287//!
288//! @param in
289//! Reference to the stream
290//!
291//! @param f
292//! Time format described by a manipulator
293//!
294//! @returns
295//! A reference to the stream
296//!
297istream &operator>>(istream &in, const _time_format &f)
298{
299 const locale loc(locale::classic(),
300 f.ptr==0 ? 0 : new time_input_facet(f.ptr));
301
302 in.imbue(loc);
303
304 return in;
305}
306
Note: See TracBrowser for help on using the repository browser.