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, Inc.
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"
74
/* Outside forward declarations */
82
/* Forward declaration needed */
83
class TemporalInterval;
84
class TemporalIntervalYear;
85
class TemporalIntervalDayOrLess;
86
class TemporalIntervalDayOrWeek;
87
class TemporalIntervalYearMonth;
90
* Base class for all temporal data classes.
95
enum calendar _calendar;
102
time_t _epoch_seconds;
105
/** Set on some operator overloads. Indicates that an overflow occurred. */
107
/** Returns number of seconds in time components (hour + minute + second) */
108
uint64_t _cumulative_seconds_in_time() const;
109
/** Resets all temporal components to zero */
112
_years= _months= _days= _hours= _minutes=
113
_seconds= _epoch_seconds= _useconds= _nseconds= 0;
118
virtual ~Temporal() {}
120
/** Returns the calendar component. */
121
inline enum calendar calendar() const {return _calendar;}
122
/** Sets the nseconds component. */
123
inline void set_nseconds(const uint32_t nsecond) {_nseconds= nsecond;}
124
/** Returns the nanoseconds component. */
125
inline uint32_t nseconds() const {return _nseconds;}
126
/** Sets the useconds component. */
127
inline void set_useconds(const uint32_t usecond) {_useconds= usecond;}
128
/** Returns the microsseconds component. */
129
inline uint32_t useconds() const {return _useconds;}
131
* Sets the epoch_seconds component automatically,
132
* based on the temporal's components.
134
void set_epoch_seconds();
135
/** Sets the epch_seconds component manually. */
136
inline void set_epoch_seconds(const uint32_t epoch_second)
137
{_epoch_seconds= epoch_second;}
138
/** Returns the UNIX epoch seconds component. */
139
inline time_t epoch_seconds() const {return _epoch_seconds;}
140
/** Sets the seconds component. */
141
inline void set_seconds(const uint32_t second) {_seconds= second;}
142
/** Returns the seconds component. */
143
inline uint32_t seconds() const {return _seconds;}
144
/** Sets the days component. */
145
inline void set_minutes(const uint32_t minute) {_minutes= minute;}
146
/** Returns the minutes component. */
147
inline uint32_t minutes() const {return _minutes;}
148
/** Sets the hours component. */
149
inline void set_hours(const uint32_t hour) {_hours= hour;}
150
/** Returns the hours component. */
151
inline uint32_t hours() const {return _hours;}
152
/** Sets the days component. */
153
inline void set_days(const uint32_t day) {_days= day;}
154
/** Returns the days component. */
155
inline uint32_t days() const {return _days;}
156
/** Sets the months component. */
157
inline void set_months(const uint32_t month) {_months= month;}
158
/** Returns the months component. */
159
inline uint32_t months() const {return _months;}
160
/** Sets the years component. */
161
inline void set_years(const uint32_t year) {_years= year;}
162
/** Returns the years component. */
163
inline uint32_t years() const {return _years;}
164
/** Returns whether the overflow flag was set
165
* (which can occur during an overloaded operator's execution) */
166
inline bool overflow() const {return _overflow;}
168
/** Returns whether the temporal value is valid as a date. */
169
virtual bool is_valid_date() const= 0;
170
/** Returns whether the temporal value is valid as a datetime. */
171
virtual bool is_valid_datetime() const= 0;
172
/** Returns whether the temporal value is valid as a time. */
173
virtual bool is_valid_time() const= 0;
174
/** Returns whether the temporal value is valid as a UNIX timestamp. */
175
virtual bool is_valid_timestamp() const= 0;
178
* Returns whether the temporal
179
* value is valid. Each subclass defines what is
180
* valid for the range of temporal data it contains.
182
virtual bool is_valid() const= 0;
185
* All Temporal derived classes must implement
186
* conversion routines for converting to and from
187
* a string. Subclasses implement other conversion
188
* routines, but should always follow these notes:
190
* 1) Ensure that ALL from_xxx methods call is_valid()
191
* 2) Ensure that ALL to_xxx methods are void returns and
192
* do not call is_valid()
194
* This minimizes the repeated bounds-checking to
195
* just the conversion from_xxx routines.
197
friend class TemporalFormat;
200
/* Forward declaration needed */
206
* Class representing temporal components in a valid
207
* SQL date range, with no time component
209
class Date: public Temporal
212
Date() :Temporal() {}
214
* Comparison operator overloads to compare a Date against
215
* another Date value.
217
* @param Date to compare against.
219
virtual bool operator==(const Date &rhs);
220
virtual bool operator!=(const Date &rhs);
221
virtual bool operator>(const Date &rhs);
222
virtual bool operator>=(const Date &rhs);
223
virtual bool operator<(const Date &rhs);
224
virtual bool operator<=(const Date &rhs);
227
* Comparison operator overloads to compare a Date against
230
* @param DateTime to compare against.
232
virtual bool operator==(const DateTime &rhs);
233
virtual bool operator!=(const DateTime &rhs);
234
virtual bool operator>(const DateTime &rhs);
235
virtual bool operator>=(const DateTime &rhs);
236
virtual bool operator<(const DateTime &rhs);
237
virtual bool operator<=(const DateTime &rhs);
240
* Comparison operator overloads to compare this against
243
* @param Timestamp to compare against.
245
virtual bool operator==(const Timestamp &rhs);
246
virtual bool operator!=(const Timestamp &rhs);
247
virtual bool operator>(const Timestamp &rhs);
248
virtual bool operator>=(const Timestamp &rhs);
249
virtual bool operator<(const Timestamp &rhs);
250
virtual bool operator<=(const Timestamp &rhs);
253
* Operator overload for adding/subtracting another Date
254
* (or subclass) to/from this temporal. When subtracting
255
* or adding two Dates, we return a new Date instance.
257
* @param Date instance to add/subtract to/from
259
const Date operator-(const Date &rhs);
260
const Date operator+(const Date &rhs);
261
Date& operator+=(const Date &rhs);
262
Date& operator-=(const Date &rhs);
265
* Operator to add/subtract a Time from a Time.
266
* We can return a Time new temporal instance.
268
* @param Temporal instance to add/subtract to/from
270
const Date operator-(const Time &rhs);
271
const Date operator+(const Time &rhs);
272
Date& operator-=(const Time &rhs);
273
Date& operator+=(const Time &rhs);
277
* Operator overload for adding/subtracting a DateTime
278
* (or subclass) to/from this temporal. When subtracting
279
* or adding two Dates, we return a new Date instance.
281
* @param DateTime instance to add/subtract to/from
283
const Date operator-(const DateTime &rhs);
284
const Date operator+(const DateTime &rhs);
285
Date& operator+=(const DateTime &rhs);
286
Date& operator-=(const DateTime &rhs);
290
* Operator overload for when a DateTime instance is
291
* assigned to a Date. We do a copy of the DateTime's
292
* date-related components.
294
* @param The DateTime to copy from
296
Date& operator=(const DateTime &rhs);
298
virtual bool is_valid_date() const {return is_valid();}
299
virtual bool is_valid_datetime() const {return is_valid();}
300
virtual bool is_valid_time() const {return false;}
301
virtual bool is_valid_timestamp() const
303
return is_valid() && in_unix_epoch();
306
/** Returns whether the temporal value is valid date. */
307
virtual bool is_valid() const;
308
/* Returns whether the Date (or subclass) instance is in the Unix Epoch. */
309
virtual bool in_unix_epoch() const;
312
* Fills a supplied char string with a
313
* string representation of the Date
316
* @param C-String to fill.
317
* @param Length of to C-String
318
* @returns length of string written (including trailing '\0').
319
* If output was truncated, returns length that would have
322
virtual int to_string(char *to, size_t to_len) const;
325
* Maximum length of C-String needed to represent type
328
static const int MAX_STRING_LENGTH= 11;
331
* Attempts to populate the Date instance based
332
* on the contents of a supplied string.
334
* Returns whether the conversion was
337
* @param String to convert from
338
* @param Length of supplied string (not including trailing '\0').
340
virtual bool from_string(const char *from, size_t from_len);
343
* Fills a supplied 8-byte integer pointer with an
344
* integer representation of the Date
347
* @param Integer to fill.
349
virtual void to_int64_t(int64_t *to) const;
352
* Fills a supplied 4-byte integer pointer with an
353
* integer representation of the Date
356
* @param Integer to fill.
358
virtual void to_int32_t(int32_t *to) const;
361
* Attempts to populate the Date instance based
362
* on the contents of a supplied 4-byte integer.
364
* Returns whether the conversion was
367
* @param Integer to convert from
369
virtual bool from_int32_t(const int32_t from);
372
* Fills a supplied int64_t with the Julian Day Number
373
* representation of this Date.
375
* @note Julian Day Number != julian day!
377
* Julian Day Number is the monotonically increasing number
378
* of days from the start of the Julian calendar (~4713 B.C.)
380
* julian day is the ordinal day number of a day in a year.
382
* @param int64_t to fill
384
void to_julian_day_number(int64_t *to) const;
387
* Attempts to populate the Date instance based
388
* on the contents of a supplied Julian Day Number
390
* Returns whether the conversion was
393
* @param Integer to convert from
395
bool from_julian_day_number(const int64_t from);
398
* Fills a supplied tm pointer with an
399
* representation of the Date
404
virtual void to_tm(struct tm *to) const;
407
* Attempts to populate the Date instance based
408
* on the contents of a supplied pointer to struct tm
411
* Returns whether the conversion was
414
* @param Pointe rto the struct tm to convert from
416
virtual bool from_tm(const struct tm *from);
419
* Attempts to convert the Date value into
422
* @param Pointer to a time_t to convert to
424
virtual void to_time_t(time_t &to) const;
427
* Attempts to populate the Date instance based
428
* on the contents of a supplied time_t
430
* Returns whether the conversion was
433
* @param time_t to convert from
435
virtual bool from_time_t(const time_t from);
438
* Fills a supplied type::Decimal with a representation of
441
* @param Pointer to the type::Decimal to fill
443
virtual void to_decimal(type::Decimal *to) const;
445
friend class TemporalInterval;
446
friend class Timestamp;
449
/* Forward declare needed for friendship */
453
* Class representing temporal components having only
454
* a time component, with no date structure
456
class Time: public Temporal
459
Time() :Temporal() {}
460
/* Maximum number of seconds in 23:59:59 (24 * 60 * 60) */
461
static const uint32_t MAX_CUMULATIVE_SECONDS= 86400L;
464
* Comparison operator overloads to compare a Time against
465
* another Time value.
467
* @param Time to compare against.
469
bool operator==(const Time &rhs);
470
bool operator!=(const Time &rhs);
471
bool operator>(const Time &rhs);
472
bool operator>=(const Time &rhs);
473
bool operator<(const Time &rhs);
474
bool operator<=(const Time &rhs);
476
* Operator to add/subtract a Time from a Time.
477
* We can return a Time new temporal instance.
479
* @param Temporal instance to add/subtract to/from
481
const Time operator-(const Time &rhs);
482
const Time operator+(const Time &rhs);
483
Time& operator-=(const Time &rhs);
484
Time& operator+=(const Time &rhs);
486
bool is_valid_date() const {return false;}
487
bool is_valid_datetime() const {return false;}
488
bool is_valid_time() const {return is_valid();}
489
bool is_valid_timestamp() const {return false;}
491
/** Returns whether the temporal value is valid date. */
492
bool is_valid() const;
493
bool is_fuzzy_valid() const;
496
* Fills a supplied char string with a
497
* string representation of the Time
500
* @param C-String to fill
501
* @param Length of to C-String
502
* @returns length of string written (not including trailing '\0').
503
* If output was truncated, returns length that would have
506
int to_string(char *to, size_t to_len) const;
509
* Maximum length of C-String needed to represent type
512
static const int MAX_STRING_LENGTH= 9;
516
* Attempts to populate the Time instance based
517
* on the contents of a supplied string.
519
* Returns whether the conversion was
522
* @param String to convert from
523
* @param Length of supplied string
525
bool from_string(const char *from, size_t from_len);
528
* Fills a supplied 4-byte integer pointer with an
529
* integer representation of the Time
532
* @param Integer to fill.
534
void to_int32_t(int32_t *to) const;
537
* Fills a supplied 8-byte integer pointer with an
538
* integer representation of the Time
539
* value. It is assume seconds past unix epoch
541
* @param Integer to fill.
543
void to_uint64_t(uint64_t &to) const;
546
* Attempts to populate the Time instance based
547
* on the contents of a supplied 4-byte integer.
549
* Returns whether the conversion was
552
* @param Integer to convert from
554
bool from_int32_t(const int32_t from);
557
* Attempts to populate the Time instance based
558
* on the contents of a supplied time_t
560
* Returns whether the conversion was
565
* We can only convert *from* a time_t, not back
566
* to a time_t since it would be a lossy conversion.
568
* @param time_t to convert from
570
bool from_time_t(const time_t from);
573
* Fills a supplied type::Decimal with a representation of
576
* @param Pointer to the type::Decimal to fill
578
void to_decimal(type::Decimal *to) const;
581
friend class DateTime;
585
* Class representing temporal components in a valid
586
* SQL datetime range, including a time component
588
class DateTime: public Date
591
DateTime() :Date() {}
593
friend class TemporalInterval;
595
/** Returns whether the DateTime (or subclass) instance
596
* is in the Unix Epoch.
598
bool in_unix_epoch() const;
599
/** Returns whether the temporal value is valid datetime. */
600
virtual bool is_valid() const;
603
* It's not possible to convert to and from a DateTime and
604
* a 4-byte integer, so let us know if we try and do it!
606
void to_int32_t(int32_t *) const {assert(0);}
607
bool from_int32_t(int32_t) {assert(0); return false;}
610
* Fills a supplied char string with a
611
* string representation of the DateTime
614
* @param C-String to fill
615
* @param Length of to C-String
616
* @returns length of string written (not including trailing '\0').
617
* If output was truncated, returns length that would have
620
virtual int to_string(char *to, size_t to_len) const;
623
* Maximum length of C-String needed to represent type
626
static const int MAX_STRING_LENGTH= 27;
629
* Attempts to populate the DateTime instance based
630
* on the contents of a supplied string.
632
* Returns whether the conversion was
635
* @param String to convert from
636
* @param Length of supplied string
638
bool from_string(const char *from, size_t from_len);
641
* Fills a supplied 8-byte integer pointer with an
642
* integer representation of the DateTime
645
* @param Integer to fill.
647
void to_int64_t(int64_t *to) const;
650
* Attempts to populate the DateTime instance based
651
* on the contents of a supplied time_t
653
* Returns whether the conversion was
656
* @param time_t to convert from
658
bool from_time_t(const time_t from);
659
bool from_timeval(struct timeval &_timeval);
662
* Attempts to populate the DateTime instance based
663
* on the contents of a supplied 8-byte integer.
665
* Returns whether the conversion was
668
* @param Integer to convert from
669
* @param convert if conversion to canonical representation
670
* should be attempted
672
bool from_int64_t(const int64_t from, bool convert);
674
bool from_int64_t(const int64_t from) {
675
return from_int64_t(from, true);
679
* Fills a supplied tm pointer with an
680
* representation of the DateTime
685
void to_tm(struct tm *to) const;
688
* Fills a supplied type::Decimal with a representation of
689
* the DateTime value.
691
* @param Pointer to the type::Decimal to fill
693
void to_decimal(type::Decimal *to) const;
695
friend class Timestamp;
699
* Class representing temporal components in the UNIX epoch
701
class Timestamp: public DateTime
704
Timestamp() :DateTime() {}
707
* Comparison operator overloads to compare this against
710
* @param Timestamp to compare against.
712
bool operator==(const Date &rhs);
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);
720
* Comparison operator overloads to compare this against
723
* @param DateTime to compare against.
725
bool operator==(const DateTime &rhs);
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);
733
* Comparison operator overloads to compare this against
734
* another Timestamp value.
736
* @param Timestamp to compare against.
738
bool operator==(const Timestamp &rhs);
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);
745
bool is_valid_timestamp() const {return is_valid();}
746
/** Returns whether the temporal value is valid timestamp. */
747
virtual bool is_valid() const;
750
* Attempts to convert the Timestamp value into
753
* @param Pointer to a time_t to convert to
755
void to_time_t(time_t &to) const;
759
* Operator overload to an output stream for a Timestamp.
761
std::ostream& operator<<(std::ostream& os, const Timestamp& subject);
764
* Class representing temporal components in the UNIX epoch
765
* with an additional microsecond component.
767
class MicroTimestamp: public Timestamp
770
MicroTimestamp() :Timestamp() {}
771
/** Returns whether the temporal value is valid micro-timestamp. */
772
bool is_valid() const;
775
* Fills a supplied char string with a
776
* string representation of the MicroTimestamp
779
* @param C-String to fill
780
* @param Length of to C-String
781
* @returns length of string written (not including trailing '\0').
782
* If output was truncated, returns length that would have
785
int to_string(char *to, size_t to_len) const;
788
* Maximum length of C-String needed to represent type
791
static const int MAX_STRING_LENGTH= 27;
794
* Fills a supplied timeval pointer with an
795
* representation of the MicroTimestamp
798
* Returns whether the conversion was
801
* @param timeval to fill.
803
void to_timeval(struct timeval &to) const;
807
* Class representing temporal components in the UNIX epoch
808
* with an additional nanosecond component.
810
class NanoTimestamp: public Timestamp
813
NanoTimestamp() :Timestamp() {}
814
/** Returns whether the temporal value is valid nano-timestamp. */
815
bool is_valid() const;
818
* Fills a supplied timespec pointer with an
819
* representation of the NanoTimestamp
822
* Returns whether the conversion was
825
* @param timespec to fill.
827
void to_timespec(struct timespec *to) const;
830
} /* end namespace drizzled */
832
#endif /* DRIZZLED_TEMPORAL_H */