date.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004-2008 Marc Boris Duerner
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * As a special exception, you may use this file as part of a free
10  * software library without restriction. Specifically, if other files
11  * instantiate templates or use macros or inline functions from this
12  * file, or you compile this file and link it with other files to
13  * produce an executable, this file does not by itself cause the
14  * resulting executable to be covered by the GNU General Public
15  * License. This exception does not however invalidate any other
16  * reasons why the executable file might be covered by the GNU Library
17  * General Public License.
18  *
19  * This library is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  * Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public
25  * License along with this library; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27  */
28 #ifndef CXXTOOLS_DATE_H
29 #define CXXTOOLS_DATE_H
30 
31 #include <cxxtools/api.h>
32 #include <string>
33 #include <stdexcept>
34 
35 namespace cxxtools
36 {
37 
38 class SerializationInfo;
39 
40 class CXXTOOLS_API InvalidDate : public std::invalid_argument
41 {
42  public:
43  InvalidDate();
44 
45  ~InvalidDate() throw()
46  {}
47 };
48 
49 CXXTOOLS_API void greg2jul(unsigned& jd, int y, int m, int d);
50 
51 CXXTOOLS_API void jul2greg(unsigned jd, int& y, int& m, int& d);
52 
53 /*
54  Notes:
55  - Henry F. Fliegel and Thomas C. Van Flandern, "A Machine Algorithm for
56  Processing Calendar Dates". CACM, Vol. 11, No. 10, October 1968, pp 657.
57 */
61 class Date
62 {
63  public:
64  enum Month
65  {
66  Jan = 1, Feb, Mar, Apr, May, Jun,
68  };
69 
70  enum WeekDay
71  {
72  Sun = 0, Mon, Tue, Wed, Thu, Fri, Sat
73  };
74 
78  static const unsigned DaysPerYear = 365;
79 
83  static const unsigned DaysPerLeapYear = 366;
84 
88  static const unsigned DaysOfJan = 31;
89 
93  static const unsigned DaysOfFeb = 28;
94 
98  static const unsigned DaysOfLeapFeb = 29;
99 
103  static const unsigned DaysOfMar = 31;
104 
108  static const unsigned DaysOfApr = 30;
109 
113  static const unsigned DaysOfMay = 31;
114 
118  static const unsigned DaysOfJun = 30;
119 
123  static const unsigned DaysOfJul = 31;
124 
128  static const unsigned DaysOfAug = 31;
129 
133  static const unsigned DaysOfSep = 30;
134 
138  static const unsigned DaysOfOct = 31;
139 
143  static const unsigned DaysOfNov = 30;
144 
148  static const unsigned DaysOfDec = 31;
149 
150  public:
156  : _julian(0)
157  {}
158 
161  Date(const Date& date)
162  : _julian(date._julian)
163  {}
164 
170  Date(int y, unsigned m, unsigned d)
171  {
172  greg2jul(_julian, y, m, d);
173  }
174 
177  explicit Date(unsigned julianDays)
178  : _julian(julianDays)
179  {}
180 
183  void setJulian(unsigned d)
184  { _julian=d; }
185 
188  unsigned julian() const
189  { return _julian; }
190 
196  void set(int year, unsigned month, unsigned day)
197  {
198  greg2jul(_julian, year, month, day);
199  }
200 
203  void get(int& year, unsigned& month, unsigned& day) const;
204 
207  unsigned day() const;
208 
211  unsigned month() const;
212 
215  int year() const;
216 
219  unsigned dayOfWeek() const;
220 
223  unsigned daysInMonth() const;
224 
227  unsigned dayOfYear() const;
228 
231  bool leapYear() const;
232 
233  // TODO: move to cxxtools:.System
234  //static Date localDate();
235 
236  // TODO: move to cxxtools:.System
237  //static Date universalDate();
238 
242  { _julian = date._julian; return *this; }
243 
246  Date& operator+=(int days)
247  { _julian += days; return *this; }
248 
251  Date& operator-=(int days)
252  { _julian -= days; return *this; }
253 
257  { _julian++; return *this; }
258 
262  { _julian--; return *this; }
263 
266  bool operator==(const Date& date) const
267  { return _julian==date._julian; }
268 
271  bool operator!=(const Date& date) const
272  { return _julian!=date._julian; }
273 
276  bool operator<(const Date& date) const
277  { return _julian<date._julian; }
278 
281  bool operator<=(const Date& date) const
282  { return _julian<=date._julian; }
283 
286  bool operator>(const Date& date) const
287  { return _julian>date._julian; }
288 
291  bool operator>=(const Date& date) const
292  { return _julian>=date._julian; }
293 
294  friend inline Date operator+(const Date& d, int days);
295 
296  friend inline Date operator+(int days, const Date& d);
297 
298  friend inline int operator-(const Date& a, const Date& b);
299 
306  std::string toIsoString() const;
307 
318  static Date fromIsoString(const std::string& s);
319 
320  public:
323  static bool isValid(int y, int m, int d);
324 
327  static bool leapYear(int year);
328 
329  private:
331  unsigned _julian;
332 };
333 
334 CXXTOOLS_API void operator >>=(const SerializationInfo& si, Date& date);
335 
336 CXXTOOLS_API void operator <<=(SerializationInfo& si, const Date& date);
337 
338 CXXTOOLS_API void convert(std::string& str, const Date& date);
339 
340 CXXTOOLS_API void convert(Date& date, const std::string& s);
341 
342 
343 inline void Date::get(int& y, unsigned& m, unsigned& d) const
344 {
345  int mon, day;
346  jul2greg(_julian, y, mon, day);
347  m = mon;
348  d = day;
349 }
350 
351 
352 inline bool Date::leapYear(int y)
353 {
354  return ((y%4==0) && (y%100!=0)) || (y%400==0);
355 }
356 
357 
358 inline unsigned Date::day() const
359 {
360  int d,m,y;
361  jul2greg(_julian, y ,m, d);
362  return d;
363 }
364 
365 
366 inline unsigned Date::month() const
367 {
368  int d,m,y;
369  jul2greg(_julian, y, m, d);
370  return m;
371 }
372 
373 
374 inline int Date::year() const
375 {
376  int d,m,y;
377  jul2greg(_julian, y, m, d);
378  return y;
379 }
380 
381 
382 inline unsigned Date::dayOfWeek() const
383 {
384  return (_julian+1) % 7;
385 }
386 
387 
388 inline unsigned Date::daysInMonth() const
389 {
390  static const unsigned char monthDays[13]=
391  {
392  0,31,28,31,30,31,30,31,31,30,31,30,31
393  };
394 
395  int y, m, d;
396  jul2greg(_julian, y, m, d);
397 
398  if( m==2 && leapYear(y) )
399  return 29;
400 
401  return monthDays[m];
402 }
403 
404 
405 inline unsigned Date::dayOfYear() const
406 {
407  int y,m,d;
408  unsigned jd;
409  jul2greg(_julian,y,m,d);
410 
411  greg2jul(jd,y,1,1);
412  return _julian-jd+1;
413 }
414 
415 
416 inline bool Date::leapYear() const
417 {
418  int d,m,y;
419  jul2greg(_julian,y,m,d);
420  return leapYear(y);
421 }
422 
423 
424 inline bool Date::isValid(int y, int m, int d)
425 {
426  if(m<1 || m>12 || d<1 || d>31)
427  {
428  return false;
429  }
430 
431  return true;
432 }
433 
434 
435 inline std::string Date::toIsoString() const
436 {
437  std::string str;
438  convert(str, *this);
439  return str;
440 }
441 
442 
443 inline Date Date::fromIsoString(const std::string& s)
444 {
445  Date date;
446  convert(date, s);
447  return date;
448 }
449 
450 
451 inline Date operator+(const Date& d, int days)
452 { return Date(d._julian + days); }
453 
454 
455 inline Date operator+(int days, const Date& d)
456 { return Date(days + d._julian); }
457 
458 
459 inline int operator-(const Date& a, const Date& b)
460 { return a._julian - b._julian; }
461 
462 }
463 
464 #endif