Date.h
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 
29 #ifndef PT_DATE_H
30 #define PT_DATE_H
31 
32 #include <Pt/Api.h>
33 #include <Pt/String.h>
34 #include <string>
35 #include <stdexcept>
36 
37 namespace Pt {
38 
39 class SerializationInfo;
40 
48 class PT_API InvalidDate : public std::runtime_error
49 {
50  public:
52  InvalidDate();
53 
55  ~InvalidDate() throw()
56  {}
57 };
58 
60 PT_API std::string dateToString(const Date& date);
61 
63 PT_API Date dateFromString(const std::string& s);
64 
66 PT_API void greg2jul(unsigned& jd, int y, int m, int d);
67 
69 PT_API void jul2greg(unsigned jd, int& y, int& m, int& d);
70 
102 class Date
103 {
104  public:
105  enum Month
106  {
107  Jan = 1, Feb, Mar, Apr, May, Jun,
108  Jul, Aug, Sep, Oct, Nov, Dec
109  };
110 
111  enum WeekDay
112  {
113  Sun = 0, Mon, Tue, Wed, Thu, Fri, Sat
114  };
115 
119  static const unsigned DaysPerYear = 365;
120 
124  static const unsigned DaysPerLeapYear = 366;
125 
129  static const unsigned DaysOfJan = 31;
130 
134  static const unsigned DaysOfFeb = 28;
135 
139  static const unsigned DaysOfLeapFeb = 29;
140 
144  static const unsigned DaysOfMar = 31;
145 
149  static const unsigned DaysOfApr = 30;
150 
154  static const unsigned DaysOfMay = 31;
155 
159  static const unsigned DaysOfJun = 30;
160 
164  static const unsigned DaysOfJul = 31;
165 
169  static const unsigned DaysOfAug = 31;
170 
174  static const unsigned DaysOfSep = 30;
175 
179  static const unsigned DaysOfOct = 31;
180 
184  static const unsigned DaysOfNov = 30;
185 
189  static const unsigned DaysOfDec = 31;
190 
191  public:
197  : _julian(0)
198  {}
199 
202  Date(const Date& date)
203  : _julian(date._julian)
204  {}
205 
211  Date(int y, unsigned m, unsigned d)
212  : _julian(0)
213  {
214  greg2jul(_julian, y, m, d);
215  }
216 
219  explicit Date(unsigned julianDays)
220  : _julian(julianDays)
221  {}
222 
225  Date& operator=(const Date& date)
226  { _julian = date._julian; return *this; }
227 
230  void setJulian(unsigned d)
231  { _julian=d; }
232 
235  unsigned julian() const
236  { return _julian; }
237 
243  void set(int y, unsigned m, unsigned d)
244  {
245  greg2jul(_julian, y, m, d);
246  }
247 
250  void get(int& year, unsigned& month, unsigned& day) const;
251 
254  unsigned day() const;
255 
258  unsigned month() const;
259 
262  int year() const;
263 
266  unsigned dayOfWeek() const;
267 
270  unsigned daysInMonth() const;
271 
274  unsigned dayOfYear() const;
275 
278  bool isLeapYear() const;
279 
282  void addDays(int n)
283  { _julian += n; }
284 
287  void addMonths(int n)
288  {
289  int y = 0;
290  unsigned m = 0, d = 0;
291  get(y, m, d);
292 
293  m += n % 12;
294  y += n / 12;
295 
296  if ( m > 12 )
297  {
298  m -= 12;
299  y += 1;
300  }
301 
302  set(y, m, d);
303  }
304 
307  void addYears(int n)
308  {
309  int y = 0;
310  unsigned m = 0, d = 0;
311  get(y, m, d);
312  y += n;
313  set(y, m, d);
314  }
315 
322  std::string toIsoString() const
323  { return dateToString(*this); }
324 
335  static Date fromIsoString(const std::string& s)
336  { return dateFromString(s); }
337 
340  Date& operator+=(int days)
341  { _julian += days; return *this; }
342 
345  Date& operator-=(int days)
346  { _julian -= days; return *this; }
347 
351  { _julian++; return *this; }
352 
356  { _julian--; return *this; }
357 
360  static bool isValid(int y, int m, int d);
361 
364  static bool isLeapYear(int year);
365 
366  private:
368  unsigned _julian;
369 };
370 
375 PT_API void operator >>=(const SerializationInfo& si, Date& date);
376 
381 PT_API void operator <<=(SerializationInfo& si, const Date& date);
382 
383 
388 inline bool operator==(const Date& a, const Date& b)
389 { return a.julian() == b.julian(); }
390 
395 inline bool operator!=(const Date& a, const Date& b)
396 { return a.julian() != b.julian(); }
397 
402 inline bool operator<(const Date& a, const Date& b)
403 { return a.julian() < b.julian(); }
404 
409 inline bool operator<=(const Date& a, const Date& b)
410 { return a.julian() <= b.julian(); }
411 
416 inline bool operator>(const Date& a, const Date& b)
417 { return a.julian() > b.julian(); }
418 
423 inline bool operator>=(const Date& a, const Date& b)
424 { return a.julian() >= b.julian(); }
425 
430 inline Date operator+(const Date& d, int days)
431 { return Date(d.julian() + days); }
432 
437 inline Date operator+(int days, const Date& d)
438 { return Date(days + d.julian()); }
439 
444 inline int operator-(const Date& a, const Date& b)
445 { return a.julian() - b.julian(); }
446 
447 
448 inline void Date::get(int& y, unsigned& m, unsigned& d) const
449 {
450  int mon, day_;
451  jul2greg(_julian, y, mon, day_);
452  m = mon;
453  d = day_;
454 }
455 
456 
457 inline bool Date::isLeapYear(int y)
458 {
459  return ((y%4==0) && (y%100!=0)) || (y%400==0);
460 }
461 
462 
463 inline unsigned Date::day() const
464 {
465  int d,m,y;
466  jul2greg(_julian, y ,m, d);
467  return d;
468 }
469 
470 
471 inline unsigned Date::month() const
472 {
473  int d,m,y;
474  jul2greg(_julian, y, m, d);
475  return m;
476 }
477 
478 
479 inline int Date::year() const
480 {
481  int d,m,y;
482  jul2greg(_julian, y, m, d);
483  return y;
484 }
485 
486 
487 inline unsigned Date::dayOfWeek() const
488 {
489  return (_julian+1) % 7;
490 }
491 
492 
493 inline unsigned Date::daysInMonth() const
494 {
495  static const unsigned char monthDays[13]=
496  {
497  0,31,28,31,30,31,30,31,31,30,31,30,31
498  };
499 
500  int y, m, d;
501  jul2greg(_julian, y, m, d);
502 
503  if( m==2 && isLeapYear(y) )
504  return 29;
505 
506  return monthDays[m];
507 }
508 
509 
510 inline unsigned Date::dayOfYear() const
511 {
512  int y,m,d;
513  unsigned jd;
514  jul2greg(_julian,y,m,d);
515 
516  greg2jul(jd,y,1,1);
517  return _julian-jd+1;
518 }
519 
520 
521 inline bool Date::isLeapYear() const
522 {
523  int d,m,y;
524  jul2greg(_julian,y,m,d);
525  return isLeapYear(y);
526 }
527 
528 
529 inline bool Date::isValid(int, int m, int d)
530 {
531  if(m<1 || m>12 || d<1 || d>31)
532  {
533  return false;
534  }
535 
536  return true;
537 }
538 
539 } // namespace Pt
540 
541 #endif // PT_DATE_H
bool isLeapYear() const
Returns true if the date is in a leap year.
Definition: Date.h:521
static const unsigned DaysOfLeapFeb
The number of days of a February in a leap year.
Definition: Date.h:139
static const unsigned DaysPerLeapYear
The number of days of a leap year.
Definition: Date.h:124
void addMonths(int n)
Adds n months to the date.
Definition: Date.h:287
static const unsigned DaysOfOct
The number of days of a October.
Definition: Date.h:179
Date & operator--()
Decrements the date by one day.
Definition: Date.h:355
unsigned daysInMonth() const
Returns the days of the month of the date.
Definition: Date.h:493
bool operator>=(const Date &a, const Date &b)
Greater-than-equal comparison operator.
Definition: Date.h:423
static const unsigned DaysOfAug
The number of days of a August.
Definition: Date.h:169
bool operator==(const Date &a, const Date &b)
Returns true if the dates are equal.
Definition: Date.h:388
Date expressed in year, month, and day.
Definition: Date.h:102
void addYears(int n)
Adds n years to the date.
Definition: Date.h:307
Date & operator=(const Date &date)
Assignment operator.
Definition: Date.h:225
void get(int &year, unsigned &month, unsigned &day) const
Gets the year, month and day.
Definition: Date.h:448
unsigned month() const
Returns the month-part of the date.
Definition: Date.h:471
static bool isValid(int y, int m, int d)
Returns true if values describe a valid date.
Definition: Date.h:529
unsigned julian() const
Returns the Date as a julian day.
Definition: Date.h:235
static const unsigned DaysOfJun
The number of days of a June.
Definition: Date.h:159
void set(int y, unsigned m, unsigned d)
Sets the date to a year, month and day.
Definition: Date.h:243
~InvalidDate()
Destructor.
Definition: Date.h:55
bool operator<(const Date &a, const Date &b)
Less-than comparison operator.
Definition: Date.h:402
static const unsigned DaysOfNov
The number of days of a November.
Definition: Date.h:184
static const unsigned DaysOfMar
The number of days of a March.
Definition: Date.h:144
Date()
Default constructor.
Definition: Date.h:196
static const unsigned DaysOfFeb
The number of days of a February.
Definition: Date.h:134
static const unsigned DaysOfJul
The number of days of a July.
Definition: Date.h:164
static const unsigned DaysOfSep
The number of days of a September.
Definition: Date.h:174
Date(unsigned julianDays)
Constructs a Date from a julian day.
Definition: Date.h:219
unsigned day() const
Returns the day-part of the date.
Definition: Date.h:463
void setJulian(unsigned d)
Sets the Date to a julian day.
Definition: Date.h:230
Date operator+(const Date &d, int days)
Add days to a date.
Definition: Date.h:430
Indicates an invalid date value.
Definition: Date.h:48
static const unsigned DaysOfJan
The number of days of a January.
Definition: Date.h:129
Date(int y, unsigned m, unsigned d)
Constructs a Date from given values.
Definition: Date.h:211
bool operator!=(const Date &a, const Date &b)
Returns true if the dates are not equal.
Definition: Date.h:395
unsigned dayOfYear() const
Returns the day of the year.
Definition: Date.h:510
static const unsigned DaysPerYear
The number of days of an ordinary year.
Definition: Date.h:119
int operator-(const Date &a, const Date &b)
Subtract two dates.
Definition: Date.h:444
unsigned dayOfWeek() const
Return day of the week, starting with sunday.
Definition: Date.h:487
Date & operator++()
Increments the date by one day.
Definition: Date.h:350
Date & operator-=(int days)
Substract days from the date.
Definition: Date.h:345
bool operator>(const Date &a, const Date &b)
Greater-than comparison operator.
Definition: Date.h:416
int year() const
Returns the year-part of the date.
Definition: Date.h:479
Date & operator+=(int days)
Add days to the date.
Definition: Date.h:340
static const unsigned DaysOfMay
The number of days of a May.
Definition: Date.h:154
static const unsigned DaysOfApr
The number of days of a April.
Definition: Date.h:149
std::string toIsoString() const
Returns the date in ISO-format.
Definition: Date.h:322
void addDays(int n)
Adds n days to the date.
Definition: Date.h:282
bool operator<=(const Date &a, const Date &b)
Less-than-equal comparison operator.
Definition: Date.h:409
static Date fromIsoString(const std::string &s)
Interprets a string as a date-string in ISO-format.
Definition: Date.h:335
static const unsigned DaysOfDec
The number of days of a December.
Definition: Date.h:189
Date(const Date &date)
Copy constructor.
Definition: Date.h:202
Date operator+(int days, const Date &d)
Add days to a date.
Definition: Date.h:437