1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008-2009 Sun Microsystems
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
* Defines the API for dealing with temporal data inside the server.
26
* The Temporal class is the base class for all data of any temporal
27
* type. A number of derived classes define specialized classes
28
* representng various date, date-time, time, or timestamp types.
30
* All Temporal derived classes are ValueObjects. That is to say that
31
* Temporal class instances are not part of the Item hierarchy and serve
32
* <em>only</em> to represent a time or date-related piece of data.
36
* Low-level calendrical calculations are done via routines in the
39
* @see drizzled/calendar.cc
42
#ifndef DRIZZLED_TEMPORAL_H
43
#define DRIZZLED_TEMPORAL_H
45
#define DRIZZLE_MAX_SECONDS 59
46
#define DRIZZLE_MAX_MINUTES 59
47
#define DRIZZLE_MAX_HOURS 23
48
#define DRIZZLE_MAX_DAYS 31
49
#define DRIZZLE_MAX_MONTHS 12
50
#define DRIZZLE_MAX_YEARS_SQL 9999
51
#define DRIZZLE_MAX_YEARS_EPOCH 2038
52
#define DRIZZLE_MIN_SECONDS 0
53
#define DRIZZLE_MIN_MINUTES 0
54
#define DRIZZLE_MIN_HOURS 0
55
#define DRIZZLE_MIN_DAYS 1
56
#define DRIZZLE_MIN_MONTHS 1
57
#define DRIZZLE_MIN_YEARS_SQL 1
58
#define DRIZZLE_MIN_YEARS_EPOCH 1970
60
#define DRIZZLE_SECONDS_IN_MINUTE 60
61
#define DRIZZLE_SECONDS_IN_HOUR (60*60)
62
#define DRIZZLE_SECONDS_IN_DAY (60*60*24)
63
#define DRIZZLE_NANOSECONDS_IN_MICROSECOND 1000
65
#define DRIZZLE_MAX_LENGTH_DATETIME_AS_STRING 40
67
#define DRIZZLE_YY_PART_YEAR 70
69
#include "drizzled/calendar.h"
73
/* Outside forward declarations */
79
/* Forward declaration needed */
80
class TemporalInterval;
81
class TemporalIntervalYear;
82
class TemporalIntervalDayOrLess;
83
class TemporalIntervalDayOrWeek;
84
class TemporalIntervalYearMonth;
87
* Base class for all temporal data classes.
92
enum calendar _calendar;
99
time_t _epoch_seconds;
102
/** Set on some operator overloads. Indicates that an overflow occurred. */
104
/** Returns number of seconds in time components (hour + minute + second) */
105
uint64_t _cumulative_seconds_in_time() const;
106
/** Resets all temporal components to zero */
109
_years= _months= _days= _hours= _minutes=
110
_seconds= _epoch_seconds= _useconds= _nseconds= 0;
115
virtual ~Temporal() {}
117
/** Returns the calendar component. */
118
inline enum calendar calendar() const {return _calendar;}
119
/** Sets the nseconds component. */
120
inline void set_nseconds(const uint32_t nsecond) {_nseconds= nsecond;}
121
/** Returns the nanoseconds component. */
122
inline uint32_t nseconds() const {return _nseconds;}
123
/** Sets the useconds component. */
124
inline void set_useconds(const uint32_t usecond) {_useconds= usecond;}
125
/** Returns the microsseconds component. */
126
inline uint32_t useconds() const {return _useconds;}
128
* Sets the epoch_seconds component automatically,
129
* based on the temporal's components.
131
void set_epoch_seconds();
132
/** Sets the epch_seconds component manually. */
133
inline void set_epoch_seconds(const uint32_t epoch_second)
134
{_epoch_seconds= epoch_second;}
135
/** Returns the UNIX epoch seconds component. */
136
inline time_t epoch_seconds() const {return _epoch_seconds;}
137
/** Sets the seconds component. */
138
inline void set_seconds(const uint32_t second) {_seconds= second;}
139
/** Returns the seconds component. */
140
inline uint32_t seconds() const {return _seconds;}
141
/** Sets the days component. */
142
inline void set_minutes(const uint32_t minute) {_minutes= minute;}
143
/** Returns the minutes component. */
144
inline uint32_t minutes() const {return _minutes;}
145
/** Sets the hours component. */
146
inline void set_hours(const uint32_t hour) {_hours= hour;}
147
/** Returns the hours component. */
148
inline uint32_t hours() const {return _hours;}
149
/** Sets the days component. */
150
inline void set_days(const uint32_t day) {_days= day;}
151
/** Returns the days component. */
152
inline uint32_t days() const {return _days;}
153
/** Sets the months component. */
154
inline void set_months(const uint32_t month) {_months= month;}
155
/** Returns the months component. */
156
inline uint32_t months() const {return _months;}
157
/** Sets the years component. */
158
inline void set_years(const uint32_t year) {_years= year;}
159
/** Returns the years component. */
160
inline uint32_t years() const {return _years;}
161
/** Returns whether the overflow flag was set
162
* (which can occur during an overloaded operator's execution) */
163
inline bool overflow() const {return _overflow;}
165
/** Returns whether the temporal value is valid as a date. */
166
virtual bool is_valid_date() const= 0;
167
/** Returns whether the temporal value is valid as a datetime. */
168
virtual bool is_valid_datetime() const= 0;
169
/** Returns whether the temporal value is valid as a time. */
170
virtual bool is_valid_time() const= 0;
171
/** Returns whether the temporal value is valid as a UNIX timestamp. */
172
virtual bool is_valid_timestamp() const= 0;
175
* Returns whether the temporal
176
* value is valid. Each subclass defines what is
177
* valid for the range of temporal data it contains.
179
virtual bool is_valid() const= 0;
182
* All Temporal derived classes must implement
183
* conversion routines for converting to and from
184
* a string. Subclasses implement other conversion
185
* routines, but should always follow these notes:
187
* 1) Ensure that ALL from_xxx methods call is_valid()
188
* 2) Ensure that ALL to_xxx methods are void returns and
189
* do not call is_valid()
191
* This minimizes the repeated bounds-checking to
192
* just the conversion from_xxx routines.
194
friend class TemporalFormat;
197
/* Forward declaration needed */
203
* Class representing temporal components in a valid
204
* SQL date range, with no time component
206
class Date: public Temporal
209
Date() :Temporal() {}
211
* Comparison operator overloads to compare a Date against
212
* another Date value.
214
* @param Date to compare against.
216
virtual bool operator==(const Date &rhs);
217
virtual bool operator!=(const Date &rhs);
218
virtual bool operator>(const Date &rhs);
219
virtual bool operator>=(const Date &rhs);
220
virtual bool operator<(const Date &rhs);
221
virtual bool operator<=(const Date &rhs);
224
* Comparison operator overloads to compare a Date against
227
* @param DateTime to compare against.
229
virtual bool operator==(const DateTime &rhs);
230
virtual bool operator!=(const DateTime &rhs);
231
virtual bool operator>(const DateTime &rhs);
232
virtual bool operator>=(const DateTime &rhs);
233
virtual bool operator<(const DateTime &rhs);
234
virtual bool operator<=(const DateTime &rhs);
237
* Comparison operator overloads to compare this against
240
* @param Timestamp to compare against.
242
virtual bool operator==(const Timestamp &rhs);
243
virtual bool operator!=(const Timestamp &rhs);
244
virtual bool operator>(const Timestamp &rhs);
245
virtual bool operator>=(const Timestamp &rhs);
246
virtual bool operator<(const Timestamp &rhs);
247
virtual bool operator<=(const Timestamp &rhs);
250
* Operator overload for adding/subtracting another Date
251
* (or subclass) to/from this temporal. When subtracting
252
* or adding two Dates, we return a new Date instance.
254
* @param Date instance to add/subtract to/from
256
const Date operator-(const Date &rhs);
257
const Date operator+(const Date &rhs);
258
Date& operator+=(const Date &rhs);
259
Date& operator-=(const Date &rhs);
262
* Operator to add/subtract a Time from a Time.
263
* We can return a Time new temporal instance.
265
* @param Temporal instance to add/subtract to/from
267
const Date operator-(const Time &rhs);
268
const Date operator+(const Time &rhs);
269
Date& operator-=(const Time &rhs);
270
Date& operator+=(const Time &rhs);
274
* Operator overload for adding/subtracting a DateTime
275
* (or subclass) to/from this temporal. When subtracting
276
* or adding two Dates, we return a new Date instance.
278
* @param DateTime instance to add/subtract to/from
280
const Date operator-(const DateTime &rhs);
281
const Date operator+(const DateTime &rhs);
282
Date& operator+=(const DateTime &rhs);
283
Date& operator-=(const DateTime &rhs);
287
* Operator overload for adding/subtracting a TemporalInterval
288
* instance to this temporal.
290
* @param TemporalInterval instance to add/subtract to/from
292
Date& operator+=(const TemporalIntervalYear &rhs);
293
Date& operator+=(const TemporalIntervalDayOrLess &rhs);
294
Date& operator+=(const TemporalIntervalDayOrWeek &rhs);
295
Date& operator+=(const TemporalIntervalYearMonth &rhs);
296
Date& operator-=(const TemporalIntervalYear &rhs);
297
Date& operator-=(const TemporalIntervalDayOrLess &rhs);
298
Date& operator-=(const TemporalIntervalDayOrWeek &rhs);
299
Date& operator-=(const TemporalIntervalYearMonth &rhs);
303
* Operator overload for when a DateTime instance is
304
* assigned to a Date. We do a copy of the DateTime's
305
* date-related components.
307
* @param The DateTime to copy from
309
Date& operator=(const DateTime &rhs);
311
virtual bool is_valid_date() const {return is_valid();}
312
virtual bool is_valid_datetime() const {return is_valid();}
313
virtual bool is_valid_time() const {return false;}
314
virtual bool is_valid_timestamp() const
316
return is_valid() && in_unix_epoch();
319
/** Returns whether the temporal value is valid date. */
320
virtual bool is_valid() const;
321
/* Returns whether the Date (or subclass) instance is in the Unix Epoch. */
322
virtual bool in_unix_epoch() const;
325
* Fills a supplied char string with a
326
* string representation of the Date
329
* @param C-String to fill.
330
* @param Length of to C-String
331
* @returns length of string written (not including trailing '\0').
332
* If output was truncated, returns length that would have
335
virtual int to_string(char *to, size_t to_len) const;
338
* Maximum length of C-String needed to represent type
341
static const int MAX_STRING_LENGTH= 11;
344
* Attempts to populate the Date instance based
345
* on the contents of a supplied string.
347
* Returns whether the conversion was
350
* @param String to convert from
351
* @param Length of supplied string
353
virtual bool from_string(const char *from, size_t from_len);
356
* Fills a supplied 8-byte integer pointer with an
357
* integer representation of the Date
360
* @param Integer to fill.
362
virtual void to_int64_t(int64_t *to) const;
365
* Fills a supplied 4-byte integer pointer with an
366
* integer representation of the Date
369
* @param Integer to fill.
371
virtual void to_int32_t(int32_t *to) const;
374
* Attempts to populate the Date instance based
375
* on the contents of a supplied 4-byte integer.
377
* Returns whether the conversion was
380
* @param Integer to convert from
382
virtual bool from_int32_t(const int32_t from);
385
* Fills a supplied int64_t with the Julian Day Number
386
* representation of this Date.
388
* @note Julian Day Number != julian day!
390
* Julian Day Number is the monotonically increasing number
391
* of days from the start of the Julian calendar (~4713 B.C.)
393
* julian day is the ordinal day number of a day in a year.
395
* @param int64_t to fill
397
void to_julian_day_number(int64_t *to) const;
400
* Attempts to populate the Date instance based
401
* on the contents of a supplied Julian Day Number
403
* Returns whether the conversion was
406
* @param Integer to convert from
408
bool from_julian_day_number(const int64_t from);
411
* Fills a supplied tm pointer with an
412
* representation of the Date
417
virtual void to_tm(struct tm *to) const;
420
* Attempts to populate the Date instance based
421
* on the contents of a supplied pointer to struct tm
424
* Returns whether the conversion was
427
* @param Pointe rto the struct tm to convert from
429
virtual bool from_tm(const struct tm *from);
432
* Attempts to convert the Date value into
435
* @param Pointer to a time_t to convert to
437
virtual void to_time_t(time_t *to) const;
440
* Attempts to populate the Date instance based
441
* on the contents of a supplied time_t
443
* Returns whether the conversion was
446
* @param time_t to convert from
448
virtual bool from_time_t(const time_t from);
451
* Fills a supplied my_decimal with a representation of
454
* @param Pointer to the my_decimal to fill
456
virtual void to_decimal(my_decimal *to) const;
458
friend class TemporalInterval;
459
friend class Timestamp;
462
/* Forward declare needed for friendship */
466
* Class representing temporal components having only
467
* a time component, with no date structure
469
class Time: public Temporal
472
Time() :Temporal() {}
473
/* Maximum number of seconds in 23:59:59 (24 * 60 * 60) */
474
const static uint32_t MAX_CUMULATIVE_SECONDS= 86400L;
477
* Comparison operator overloads to compare a Time against
478
* another Time value.
480
* @param Time to compare against.
482
bool operator==(const Time &rhs);
483
bool operator!=(const Time &rhs);
484
bool operator>(const Time &rhs);
485
bool operator>=(const Time &rhs);
486
bool operator<(const Time &rhs);
487
bool operator<=(const Time &rhs);
489
* Operator to add/subtract a Time from a Time.
490
* We can return a Time new temporal instance.
492
* @param Temporal instance to add/subtract to/from
494
const Time operator-(const Time &rhs);
495
const Time operator+(const Time &rhs);
496
Time& operator-=(const Time &rhs);
497
Time& operator+=(const Time &rhs);
499
bool is_valid_date() const {return false;}
500
bool is_valid_datetime() const {return false;}
501
bool is_valid_time() const {return is_valid();}
502
bool is_valid_timestamp() const {return false;}
503
/** Returns whether the temporal value is valid date. */
504
bool is_valid() const;
507
* Fills a supplied char string with a
508
* string representation of the Time
511
* @param C-String to fill
512
* @param Length of to C-String
513
* @returns length of string written (not including trailing '\0').
514
* If output was truncated, returns length that would have
517
int to_string(char *to, size_t to_len) const;
520
* Maximum length of C-String needed to represent type
523
static const int MAX_STRING_LENGTH= 9;
527
* Attempts to populate the Time instance based
528
* on the contents of a supplied string.
530
* Returns whether the conversion was
533
* @param String to convert from
534
* @param Length of supplied string
536
bool from_string(const char *from, size_t from_len);
539
* Fills a supplied 4-byte integer pointer with an
540
* integer representation of the Time
543
* @param Integer to fill.
545
void to_int32_t(int32_t *to) const;
548
* Attempts to populate the Time instance based
549
* on the contents of a supplied 4-byte integer.
551
* Returns whether the conversion was
554
* @param Integer to convert from
556
bool from_int32_t(const int32_t from);
559
* Attempts to populate the Time instance based
560
* on the contents of a supplied time_t
562
* Returns whether the conversion was
567
* We can only convert *from* a time_t, not back
568
* to a time_t since it would be a lossy conversion.
570
* @param time_t to convert from
572
bool from_time_t(const time_t from);
575
* Fills a supplied my_decimal with a representation of
578
* @param Pointer to the my_decimal to fill
580
void to_decimal(my_decimal *to) const;
583
friend class DateTime;
587
* Class representing temporal components in a valid
588
* SQL datetime range, including a time component
590
class DateTime: public Date
593
DateTime() :Date() {}
595
friend class TemporalInterval;
597
/** Returns whether the DateTime (or subclass) instance
598
* is in the Unix Epoch.
600
bool in_unix_epoch() const;
601
/** Returns whether the temporal value is valid datetime. */
602
virtual bool is_valid() const;
605
* It's not possible to convert to and from a DateTime and
606
* a 4-byte integer, so let us know if we try and do it!
608
void to_int32_t(int32_t *) const {assert(0);}
609
bool from_int32_t(int32_t) {assert(0); return false;}
612
* Fills a supplied char string with a
613
* string representation of the DateTime
616
* @param C-String to fill
617
* @param Length of to C-String
618
* @returns length of string written (not including trailing '\0').
619
* If output was truncated, returns length that would have
622
virtual int to_string(char *to, size_t to_len) const;
625
* Maximum length of C-String needed to represent type
628
static const int MAX_STRING_LENGTH= 27;
631
* Attempts to populate the DateTime instance based
632
* on the contents of a supplied string.
634
* Returns whether the conversion was
637
* @param String to convert from
638
* @param Length of supplied string
640
bool from_string(const char *from, size_t from_len);
643
* Fills a supplied 8-byte integer pointer with an
644
* integer representation of the DateTime
647
* @param Integer to fill.
649
void to_int64_t(int64_t *to) const;
652
* Attempts to populate the DateTime instance based
653
* on the contents of a supplied time_t
655
* Returns whether the conversion was
658
* @param time_t to convert from
660
bool from_time_t(const time_t from);
663
* Attempts to populate the DateTime instance based
664
* on the contents of a supplied 8-byte integer.
666
* Returns whether the conversion was
669
* @param Integer to convert from
670
* @param convert if conversion to canonical representation
671
* should be attempted
673
bool from_int64_t(const int64_t from, bool convert);
675
bool from_int64_t(const int64_t from) {
676
return from_int64_t(from, true);
680
* Fills a supplied tm pointer with an
681
* representation of the DateTime
686
void to_tm(struct tm *to) const;
689
* Fills a supplied my_decimal with a representation of
690
* the DateTime value.
692
* @param Pointer to the my_decimal to fill
694
void to_decimal(my_decimal *to) const;
696
friend class Timestamp;
700
* Class representing temporal components in the UNIX epoch
702
class Timestamp: public DateTime
705
Timestamp() :DateTime() {}
708
* Comparison operator overloads to compare this against
711
* @param Timestamp to compare against.
713
bool operator==(const Date &rhs);
714
bool operator!=(const Date &rhs);
715
bool operator>(const Date &rhs);
716
bool operator>=(const Date &rhs);
717
bool operator<(const Date &rhs);
718
bool operator<=(const Date &rhs);
721
* Comparison operator overloads to compare this against
724
* @param DateTime to compare against.
726
bool operator==(const DateTime &rhs);
727
bool operator!=(const DateTime &rhs);
728
bool operator>(const DateTime &rhs);
729
bool operator>=(const DateTime &rhs);
730
bool operator<(const DateTime &rhs);
731
bool operator<=(const DateTime &rhs);
734
* Comparison operator overloads to compare this against
735
* another Timestamp value.
737
* @param Timestamp to compare against.
739
bool operator==(const Timestamp &rhs);
740
bool operator!=(const Timestamp &rhs);
741
bool operator>(const Timestamp &rhs);
742
bool operator>=(const Timestamp &rhs);
743
bool operator<(const Timestamp &rhs);
744
bool operator<=(const Timestamp &rhs);
746
bool is_valid_timestamp() const {return is_valid();}
747
/** Returns whether the temporal value is valid timestamp. */
748
virtual bool is_valid() const;
751
* Attempts to convert the Timestamp value into
754
* @param Pointer to a time_t to convert to
756
void to_time_t(time_t *to) const;
760
* Operator overload to an output stream for a Timestamp.
762
std::ostream& operator<<(std::ostream& os, const Timestamp& subject);
765
* Class representing temporal components in the UNIX epoch
766
* with an additional microsecond component.
768
class MicroTimestamp: public Timestamp
771
MicroTimestamp() :Timestamp() {}
772
/** Returns whether the temporal value is valid micro-timestamp. */
773
bool is_valid() const;
776
* Fills a supplied char string with a
777
* string representation of the MicroTimestamp
780
* @param C-String to fill
781
* @param Length of to C-String
782
* @returns length of string written (not including trailing '\0').
783
* If output was truncated, returns length that would have
786
int to_string(char *to, size_t to_len) const;
789
* Maximum length of C-String needed to represent type
792
static const int MAX_STRING_LENGTH= 27;
795
* Fills a supplied timeval pointer with an
796
* representation of the MicroTimestamp
799
* Returns whether the conversion was
802
* @param timeval to fill.
804
void to_timeval(struct timeval *to) const;
808
* Class representing temporal components in the UNIX epoch
809
* with an additional nanosecond component.
811
class NanoTimestamp: public Timestamp
814
NanoTimestamp() :Timestamp() {}
815
/** Returns whether the temporal value is valid nano-timestamp. */
816
bool is_valid() const;
819
* Fills a supplied timespec pointer with an
820
* representation of the NanoTimestamp
823
* Returns whether the conversion was
826
* @param timespec to fill.
828
void to_timespec(struct timespec *to) const;
831
} /* end namespace drizzled */
833
#endif /* DRIZZLED_TEMPORAL_H */