time.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006 by Tommi Maekitalo
3  * Copyright (C) 2006-2008 by Marc Boris Duerner
4  * Copyright (C) 2006 by Stefan Bueder
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * As a special exception, you may use this file as part of a free
12  * software library without restriction. Specifically, if other files
13  * instantiate templates or use macros or inline functions from this
14  * file, or you compile this file and link it with other files to
15  * produce an executable, this file does not by itself cause the
16  * resulting executable to be covered by the GNU General Public
17  * License. This exception does not however invalidate any other
18  * reasons why the executable file might be covered by the GNU Library
19  * General Public License.
20  *
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24  * Lesser General Public License for more details.
25  *
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30 #ifndef CXXTOOLS_TIME_H
31 #define CXXTOOLS_TIME_H
32 
33 #include <cxxtools/api.h>
34 #include <cxxtools/timespan.h>
35 #include <string>
36 #include <stdexcept>
37 #include <stdint.h>
38 
39 namespace cxxtools
40 {
41 
42 class SerializationInfo;
43 
44 class CXXTOOLS_API InvalidTime : public std::invalid_argument
45 {
46  public:
47  InvalidTime();
48 
49  ~InvalidTime() throw()
50  {}
51 };
52 
56 class Time
57 {
58  public:
59  static const unsigned MaxHours = 23;
60  static const unsigned HoursPerDay = 24;
61  static const unsigned MaxMinutes = 59;
62  static const unsigned MinutesPerHour = 60;
63  static const unsigned MinutesPerDay = 1440;
64  static const unsigned MaxSeconds = 59;
65  static const unsigned SecondsPerDay = 86400;
66  static const unsigned SecondsPerHour = 3600;
67  static const unsigned SecondsPerMinute = 60;
68  static const unsigned MSecsPerDay = 86400000;
69  static const unsigned MSecsPerHour = 3600000;
70  static const unsigned MSecsPerMinute = 60000;
71  static const unsigned MSecsPerSecond = 1000;
72 
75  Time()
76  : _msecs(0)
77  {}
78 
83  inline Time(unsigned h, unsigned m, unsigned s = 0, unsigned ms = 0)
84  {
85  set(h, m, s, ms);
86  }
87 
90  unsigned hour() const
91  {
92  return _msecs / MSecsPerHour;
93  }
94 
97  unsigned minute() const
98  {
99  return (_msecs % MSecsPerHour) / MSecsPerMinute;
100  }
101 
104  unsigned second() const
105  {
106  return (_msecs / 1000) % SecondsPerMinute;
107  }
108 
111  unsigned msec() const
112  {
113  return _msecs % 1000;
114  }
115 
116  unsigned totalMSecs() const
117  { return _msecs; }
118 
119  void setTotalMSecs(unsigned msecs)
120  { _msecs = msecs; }
121 
127  void set(unsigned hour, unsigned min, unsigned sec, unsigned msec = 0)
128  {
129  if ( ! isValid(hour, min, sec , msec) )
130  {
131  throw InvalidTime();
132  }
133 
134  _msecs = (hour*SecondsPerHour + min*SecondsPerMinute + sec) * 1000 + msec;
135  }
136 
141  void get(unsigned& h, unsigned& m, unsigned& s, unsigned& ms) const
142  {
143  h = hour();
144  m = minute();
145  s = second();
146  ms = msec();
147  }
148 
154  Time addSecs(int secs) const
155  {
156  return addMSecs(secs * 1000);
157  }
158 
161  int secsTo(const Time &t) const
162  {
163  return static_cast<int>( msecsTo(t) / 1000 );
164  }
165 
171  inline Time addMSecs(int64_t ms) const
172  {
173  Time t;
174  if (ms < 0)
175  {
176  int64_t negdays = (MSecsPerDay - ms) / MSecsPerDay;
177  t._msecs = static_cast<unsigned>((_msecs + ms + negdays * MSecsPerDay) % MSecsPerDay);
178  }
179  else
180  {
181  t._msecs = static_cast<unsigned>((_msecs + ms) % MSecsPerDay);
182  }
183 
184  return t;
185  }
186 
189  int64_t msecsTo(const Time &t) const
190  {
191  if(t._msecs > _msecs)
192  return t._msecs - _msecs;
193 
194  return MSecsPerDay - (_msecs - t._msecs);
195  }
196 
199  Time& operator=(const Time& other)
200  { _msecs=other._msecs; return *this; }
201 
204  bool operator==(const Time& other) const
205  { return _msecs == other._msecs; }
206 
209  bool operator!=(const Time& other) const
210  { return _msecs != other._msecs; }
211 
214  bool operator<(const Time& other) const
215  { return _msecs < other._msecs; }
216 
219  bool operator<=(const Time& other) const
220  { return _msecs <= other._msecs; }
221 
224  bool operator>(const Time& other) const
225  { return _msecs > other._msecs; }
226 
229  bool operator>=(const Time& other) const
230  { return _msecs >= other._msecs; }
231 
235  {
236  int64_t msecs = ( _msecs + ts.totalMSecs() ) % MSecsPerDay;
237  msecs = msecs < 0 ? MSecsPerDay + msecs : msecs;
238  _msecs = static_cast<unsigned>(msecs);
239  return *this;
240  }
241 
245  {
246  int64_t msecs = ( _msecs - ts.totalMSecs() ) % MSecsPerDay;
247  msecs = msecs < 0 ? MSecsPerDay + msecs : msecs;
248  _msecs = static_cast<unsigned>(msecs);
249  return *this;
250  }
251 
254  friend Time operator+(const Time& time, const Timespan& ts)
255  {
256  return time.addMSecs( ts.totalMSecs() );
257  }
258 
261  friend Time operator-(const Time& time, const Timespan& ts)
262  {
263  return time.addMSecs( -ts.totalMSecs() );
264  }
265 
268  friend Timespan operator-(const Time& a, const Time& b)
269  {
270  return b.msecsTo(a) * 1000;
271  }
272 
275  std::string toIsoString() const;
276 
279  static bool isValid(unsigned h, unsigned m, unsigned s, unsigned ms)
280  {
281  return h < 24 && m < 60 && s < 60 && ms < 1000;
282  }
283 
290  static Time fromIsoString(const std::string& s);
291 
292  private:
294  unsigned _msecs;
295  };
296 
297  CXXTOOLS_API void operator >>=(const SerializationInfo& si, Time& time);
298 
299  CXXTOOLS_API void operator <<=(SerializationInfo& si, const Time& time);
300 
301  CXXTOOLS_API void convert(std::string& str, const cxxtools::Time& time);
302 
303  CXXTOOLS_API void convert(cxxtools::Time& time, const std::string& s);
304 
305  inline std::string Time::toIsoString() const
306  {
307  std::string str;
308  convert(str, *this);
309  return str;
310  }
311 
312  inline Time Time::fromIsoString(const std::string& s)
313  {
314  Time time;
315  convert(time, s);
316  return time;
317  }
318 }
319 
320 #endif // CXXTOOLS_TIME_H