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 #include <cstdlib>
37 
38 namespace Pt {
39 
40 class SerializationInfo;
41 
49 class PT_API InvalidDate : public std::runtime_error
50 {
51  public:
54 
56  ~InvalidDate() throw()
57  {}
58 };
59 
61 PT_API std::string dateToString(const Date& date);
62 
64 PT_API Date dateFromString(const std::string& s);
65 
67 PT_API void greg2jul(unsigned& jd, int y, int m, int d);
68 
70 PT_API void jul2greg(unsigned jd, int& y, int& m, int& d);
71 
103 class Date
104 {
105  public:
106  enum Month
107  {
108  Jan = 1, Feb, Mar, Apr, May, Jun,
109  Jul, Aug, Sep, Oct, Nov, Dec
110  };
111 
112  enum WeekDay
113  {
114  Sun = 0, Mon, Tue, Wed, Thu, Fri, Sat
115  };
116 
120  static const unsigned DaysPerYear = 365;
121 
125  static const unsigned DaysPerLeapYear = 366;
126 
130  static const unsigned DaysOfJan = 31;
131 
135  static const unsigned DaysOfFeb = 28;
136 
140  static const unsigned DaysOfLeapFeb = 29;
141 
145  static const unsigned DaysOfMar = 31;
146 
150  static const unsigned DaysOfApr = 30;
151 
155  static const unsigned DaysOfMay = 31;
156 
160  static const unsigned DaysOfJun = 30;
161 
165  static const unsigned DaysOfJul = 31;
166 
170  static const unsigned DaysOfAug = 31;
171 
175  static const unsigned DaysOfSep = 30;
176 
180  static const unsigned DaysOfOct = 31;
181 
185  static const unsigned DaysOfNov = 30;
186 
190  static const unsigned DaysOfDec = 31;
191 
192  public:
198  : _julian(0)
199  {}
200 
203  Date(const Date& date)
204  : _julian(date._julian)
205  {}
206 
212  Date(int y, unsigned m, unsigned d)
213  : _julian(0)
214  {
215  greg2jul(_julian, y, m, d);
216  }
217 
220  explicit Date(unsigned julianDays)
221  : _julian(julianDays)
222  {}
223 
226  Date& operator=(const Date& date)
227  { _julian = date._julian; return *this; }
228 
231  void setJulian(unsigned d)
232  { _julian=d; }
233 
236  unsigned julian() const
237  { return _julian; }
238 
244  void set(int y, unsigned m, unsigned d)
245  {
246  greg2jul(_julian, y, m, d);
247  }
248 
251  void get(int& year, unsigned& month, unsigned& day) const;
252 
255  unsigned day() const;
256 
259  unsigned month() const;
260 
263  int year() const;
264 
267  unsigned dayOfWeek() const;
268 
271  unsigned daysInMonth() const;
272 
275  unsigned dayOfYear() const;
276 
279  bool isLeapYear() const;
280 
283  void addDays(int n)
284  { _julian += n; }
285 
288  void addMonths(int n)
289  {
290  int y = 0;
291  unsigned m = 0, d = 0;
292  get(y, m, d);
293 
294  y += n / 12;
295 
296  unsigned deltaM = static_cast<unsigned>( std::abs(n) % 12 );
297 
298  if(n < 0)
299  {
300  if(m <= deltaM)
301  {
302  m += 12;
303  y -= 1;
304  }
305 
306  m -= deltaM;
307  }
308  else
309  {
310  m += deltaM;
311 
312  if(m > 12)
313  {
314  m -= 12;
315  y += 1;
316  }
317  }
318 
319  Date dt(y, m, 1);
320  unsigned maxDays = dt.daysInMonth();
321  if(d > maxDays)
322  {
323  d = maxDays;
324  }
325 
326  set(y, m, d);
327  }
328 
331  void addYears(int n)
332  {
333  int y = 0;
334  unsigned m = 0, d = 0;
335  get(y, m, d);
336  y += n;
337  set(y, m, d);
338  }
339 
346  std::string toIsoString() const
347  { return dateToString(*this); }
348 
359  static Date fromIsoString(const std::string& s)
360  { return dateFromString(s); }
361 
364  Date& operator+=(int days)
365  { _julian += days; return *this; }
366 
369  Date& operator-=(int days)
370  { _julian -= days; return *this; }
371 
375  { _julian++; return *this; }
376 
380  { _julian--; return *this; }
381 
384  static bool isValid(int y, int m, int d);
385 
388  static bool isLeapYear(int year);
389 
390  private:
392  unsigned _julian;
393 };
394 
399 PT_API void operator >>=(const SerializationInfo& si, Date& date);
400 
405 PT_API void operator <<=(SerializationInfo& si, const Date& date);
406 
407 
412 inline bool operator==(const Date& a, const Date& b)
413 { return a.julian() == b.julian(); }
414 
419 inline bool operator!=(const Date& a, const Date& b)
420 { return a.julian() != b.julian(); }
421 
426 inline bool operator<(const Date& a, const Date& b)
427 { return a.julian() < b.julian(); }
428 
433 inline bool operator<=(const Date& a, const Date& b)
434 { return a.julian() <= b.julian(); }
435 
440 inline bool operator>(const Date& a, const Date& b)
441 { return a.julian() > b.julian(); }
442 
447 inline bool operator>=(const Date& a, const Date& b)
448 { return a.julian() >= b.julian(); }
449 
454 inline Date operator+(const Date& d, int days)
455 { return Date(d.julian() + days); }
456 
461 inline Date operator+(int days, const Date& d)
462 { return Date(days + d.julian()); }
463 
468 inline int operator-(const Date& a, const Date& b)
469 { return a.julian() - b.julian(); }
470 
471 
472 inline void Date::get(int& y, unsigned& m, unsigned& d) const
473 {
474  int mon, day_;
475  jul2greg(_julian, y, mon, day_);
476  m = mon;
477  d = day_;
478 }
479 
480 
481 inline bool Date::isLeapYear(int y)
482 {
483  return ((y%4==0) && (y%100!=0)) || (y%400==0);
484 }
485 
486 
487 inline unsigned Date::day() const
488 {
489  int d,m,y;
490  jul2greg(_julian, y ,m, d);
491  return d;
492 }
493 
494 
495 inline unsigned Date::month() const
496 {
497  int d,m,y;
498  jul2greg(_julian, y, m, d);
499  return m;
500 }
501 
502 
503 inline int Date::year() const
504 {
505  int d,m,y;
506  jul2greg(_julian, y, m, d);
507  return y;
508 }
509 
510 
511 inline unsigned Date::dayOfWeek() const
512 {
513  return (_julian+1) % 7;
514 }
515 
516 
517 inline unsigned Date::daysInMonth() const
518 {
519  static const unsigned char monthDays[13]=
520  {
521  0,31,28,31,30,31,30,31,31,30,31,30,31
522  };
523 
524  int y, m, d;
525  jul2greg(_julian, y, m, d);
526 
527  if( m==2 && isLeapYear(y) )
528  return 29;
529 
530  return monthDays[m];
531 }
532 
533 
534 inline unsigned Date::dayOfYear() const
535 {
536  int y,m,d;
537  unsigned jd;
538  jul2greg(_julian,y,m,d);
539 
540  greg2jul(jd,y,1,1);
541  return _julian-jd+1;
542 }
543 
544 
545 inline bool Date::isLeapYear() const
546 {
547  int d,m,y;
548  jul2greg(_julian,y,m,d);
549  return isLeapYear(y);
550 }
551 
552 
553 inline bool Date::isValid(int, int m, int d)
554 {
555  if(m<1 || m>12 || d<1 || d>31)
556  {
557  return false;
558  }
559 
560  return true;
561 }
562 
563 } // namespace Pt
564 
565 #endif // PT_DATE_H
bool operator<(const Date &a, const Date &b)
Less-than comparison operator.
Definition: Date.h:426
Core module.
Definition: Allocator.h:33
Date expressed in year, month, and day.
Definition: Date.h:104
unsigned day() const
Returns the day-part of the date.
Definition: Date.h:487
Date operator+(const Date &d, int days)
Add days to a date.
Definition: Date.h:454
unsigned month() const
Returns the month-part of the date.
Definition: Date.h:495
static const unsigned DaysOfFeb
The number of days of a February.
Definition: Date.h:135
static const unsigned DaysOfJul
The number of days of a July.
Definition: Date.h:165
static const unsigned DaysOfSep
The number of days of a September.
Definition: Date.h:175
static const unsigned DaysPerYear
The number of days of an ordinary year.
Definition: Date.h:120
Date(unsigned julianDays)
Constructs a Date from a julian day.
Definition: Date.h:220
void setJulian(unsigned d)
Sets the Date to a julian day.
Definition: Date.h:231
int operator-(const Date &a, const Date &b)
Subtract two dates.
Definition: Date.h:468
Date & operator++()
Increments the date by one day.
Definition: Date.h:374
static const unsigned DaysOfJan
The number of days of a January.
Definition: Date.h:130
Date(int y, unsigned m, unsigned d)
Constructs a Date from given values.
Definition: Date.h:212
bool operator!=(const Date &a, const Date &b)
Returns true if the dates are not equal.
Definition: Date.h:419
bool operator>(const Date &a, const Date &b)
Greater-than comparison operator.
Definition: Date.h:440
int year() const
Returns the year-part of the date.
Definition: Date.h:503
Date & operator+=(int days)
Add days to the date.
Definition: Date.h:364
Date & operator-=(int days)
Substract days from the date.
Definition: Date.h:369
unsigned daysInMonth() const
Returns the days of the month of the date.
Definition: Date.h:517
void get(int &year, unsigned &month, unsigned &day) const
Gets the year, month and day.
Definition: Date.h:472
static const unsigned DaysOfMay
The number of days of a May.
Definition: Date.h:155
static const unsigned DaysOfApr
The number of days of a April.
Definition: Date.h:150
void addDays(int n)
Adds n days to the date.
Definition: Date.h:283
static Date fromIsoString(const std::string &s)
Interprets a string as a date-string in ISO-format.
Definition: Date.h:359
static const unsigned DaysOfDec
The number of days of a December.
Definition: Date.h:190
~InvalidDate()
Destructor.
Definition: Date.h:56
bool operator<=(const Date &a, const Date &b)
Less-than-equal comparison operator.
Definition: Date.h:433
unsigned dayOfWeek() const
Return day of the week, starting with sunday.
Definition: Date.h:511
Date operator+(int days, const Date &d)
Add days to a date.
Definition: Date.h:461
static const unsigned DaysOfLeapFeb
The number of days of a February in a leap year.
Definition: Date.h:140
std::string toIsoString() const
Returns the date in ISO-format.
Definition: Date.h:346
void addMonths(int n)
Adds n months to the date.
Definition: Date.h:288
static const unsigned DaysOfOct
The number of days of a October.
Definition: Date.h:180
static const unsigned DaysPerLeapYear
The number of days of a leap year.
Definition: Date.h:125
Date(const Date &date)
Copy constructor.
Definition: Date.h:203
Date & operator--()
Decrements the date by one day.
Definition: Date.h:379
unsigned dayOfYear() const
Returns the day of the year.
Definition: Date.h:534
unsigned julian() const
Returns the Date as a julian day.
Definition: Date.h:236
static const unsigned DaysOfAug
The number of days of a August.
Definition: Date.h:170
Indicates an invalid date value.
Definition: Date.h:50
void addYears(int n)
Adds n years to the date.
Definition: Date.h:331
bool operator>=(const Date &a, const Date &b)
Greater-than-equal comparison operator.
Definition: Date.h:447
bool operator==(const Date &a, const Date &b)
Returns true if the dates are equal.
Definition: Date.h:412
static bool isValid(int y, int m, int d)
Returns true if values describe a valid date.
Definition: Date.h:553
Date & operator=(const Date &date)
Assignment operator.
Definition: Date.h:226
static const unsigned DaysOfJun
The number of days of a June.
Definition: Date.h:160
bool isLeapYear() const
Returns true if the date is in a leap year.
Definition: Date.h:545
void set(int y, unsigned m, unsigned d)
Sets the date to a year, month and day.
Definition: Date.h:244
Represents arbitrary types during serialization.
Definition: SerializationInfo.h:59
static const unsigned DaysOfMar
The number of days of a March.
Definition: Date.h:145
Date()
Default constructor.
Definition: Date.h:197
InvalidDate()
Constructor.
static const unsigned DaysOfNov
The number of days of a November.
Definition: Date.h:185