1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems
8
* Jay Pipes <jay.pipes@sun.com>
10
* This program is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License as published by
12
* the Free Software Foundation; either version 2 of the License, or
13
* (at your option) any later version.
15
* This program is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU General Public License for more details.
20
* You should have received a copy of the GNU General Public License
21
* along with this program; if not, write to the Free Software
22
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28
* Implementation of the server's temporal class API
32
* Move to completed ValueObject API, which would remove the from_xxx() methods
33
* and replace them with constructors which take other ValueObject instances as
34
* their single parameter.
40
#include "drizzled/global.h"
41
#include "mystrings/m_ctype.h"
42
#include "drizzled/my_decimal.h"
43
#include "drizzled/temporal.h"
44
#include "drizzled/temporal_format.h"
46
extern std::vector<drizzled::TemporalFormat *> known_datetime_formats;
47
extern std::vector<drizzled::TemporalFormat *> known_date_formats;
48
extern std::vector<drizzled::TemporalFormat *> known_time_formats;
67
uint64_t Temporal::_cumulative_seconds_in_time() const
69
return (uint64_t) ((_hours * INT64_C(3600))
70
+ (_minutes * INT64_C(60))
74
void Temporal::set_epoch_seconds()
77
* If the temporal is in the range of a timestamp, set
78
* the epoch_seconds member variable
80
if (in_unix_epoch_range(_years, _months, _days, _hours, _minutes, _seconds))
83
struct tm broken_time;
85
broken_time.tm_sec= _seconds;
86
broken_time.tm_min= _minutes;
87
broken_time.tm_hour= _hours;
88
broken_time.tm_mday= _days; /* Drizzle format uses ordinal, standard tm does too! */
89
broken_time.tm_mon= _months - 1; /* Drizzle format uses ordinal, standard tm does NOT! */
90
broken_time.tm_year= _years - 1900; /* tm_year expects range of 70 - 38 */
92
result_time= timegm(&broken_time);
94
_epoch_seconds= result_time;
98
bool Date::from_string(const char *from, size_t from_len)
101
* Loop through the known date formats and see if
105
TemporalFormat *current_format;
106
std::vector<TemporalFormat *>::iterator current= known_date_formats.begin();
108
while (current != known_date_formats.end())
110
current_format= *current;
111
if (current_format->matches(from, from_len, this))
126
bool DateTime::from_string(const char *from, size_t from_len)
129
* Loop through the known datetime formats and see if
133
TemporalFormat *current_format;
134
std::vector<TemporalFormat *>::iterator current= known_datetime_formats.begin();
136
while (current != known_datetime_formats.end())
138
current_format= *current;
139
if (current_format->matches(from, from_len, this))
155
* Comparison operators for Time against another Time
156
* are easy. We simply compare the cumulative time
159
bool Time::operator==(const Time& rhs)
163
&& _minutes == rhs._minutes
164
&& _seconds == rhs._seconds
165
&& _useconds == rhs._useconds
166
&& _nseconds == rhs._nseconds
169
bool Time::operator!=(const Time& rhs)
171
return ! (*this == rhs);
173
bool Time::operator<(const Time& rhs)
175
return (_cumulative_seconds_in_time() < rhs._cumulative_seconds_in_time());
177
bool Time::operator<=(const Time& rhs)
179
return (_cumulative_seconds_in_time() <= rhs._cumulative_seconds_in_time());
181
bool Time::operator>(const Time& rhs)
183
return (_cumulative_seconds_in_time() > rhs._cumulative_seconds_in_time());
185
bool Time::operator>=(const Time& rhs)
187
return (_cumulative_seconds_in_time() >= rhs._cumulative_seconds_in_time());
191
* Subtracting one Time value from another can yield
192
* a new Time instance.
194
* This operator is called in the following situation:
197
* drizzled::Time lhs;
198
* lhs.from_string("20:00:00");
199
* drizzled::Time rhs;
200
* rhs.from_string("19:00:00");
202
* drizzled::Time result= lhs - rhs;
207
* Subtracting a larger time value from a smaller one
208
* should throw an exception at some point. The result
209
* of such an operator should be a TemporalInterval, not
210
* a Time instance, since a negative time is not possible.
212
const Time Time::operator-(const Time& rhs)
216
int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
217
result._hours= second_diff % DRIZZLE_SECONDS_IN_HOUR;
218
second_diff-= (result._hours * DRIZZLE_SECONDS_IN_HOUR);
219
result._minutes= second_diff % DRIZZLE_SECONDS_IN_MINUTE;
220
second_diff-= (result._minutes * DRIZZLE_SECONDS_IN_MINUTE);
221
result._seconds= second_diff;
225
const Time Time::operator+(const Time& rhs)
228
int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
229
result._hours= second_diff % DRIZZLE_SECONDS_IN_HOUR;
230
second_diff-= (result._hours * DRIZZLE_SECONDS_IN_HOUR);
231
result._minutes= second_diff % DRIZZLE_SECONDS_IN_MINUTE;
232
second_diff-= (result._minutes * DRIZZLE_SECONDS_IN_MINUTE);
233
result._seconds= second_diff;
235
* @TODO Once exceptions are supported, we should raise an error here if
236
* the result Time is not valid?
242
* Variation of + and - operator which returns a reference to the left-hand
243
* side Time object and adds the right-hand side to itself.
245
Time& Time::operator+=(const Time& rhs)
247
int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
248
_hours= second_diff % DRIZZLE_SECONDS_IN_HOUR;
249
second_diff-= (_hours * DRIZZLE_SECONDS_IN_HOUR);
250
_minutes= second_diff % DRIZZLE_SECONDS_IN_MINUTE;
251
second_diff-= (_minutes * DRIZZLE_SECONDS_IN_MINUTE);
252
_seconds= second_diff;
254
* @TODO Once exceptions are supported, we should raise an error here if
255
* the result Time is not valid?
259
Time& Time::operator-=(const Time& rhs)
261
int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
262
_hours= second_diff % DRIZZLE_SECONDS_IN_HOUR;
263
second_diff-= (_hours * DRIZZLE_SECONDS_IN_HOUR);
264
_minutes= second_diff % DRIZZLE_SECONDS_IN_MINUTE;
265
second_diff-= (_minutes * DRIZZLE_SECONDS_IN_MINUTE);
266
_seconds= second_diff;
268
* @TODO Once exceptions are supported, we should raise an error here if
269
* the result Time is not valid?
275
* Comparison operators for Date against another Date
276
* are easy. We simply compare the cumulative
279
bool Date::operator==(const Date& rhs)
283
&& _months == rhs._months
284
&& _days == rhs._days
287
bool Date::operator!=(const Date& rhs)
289
return ! (*this == rhs);
291
bool Date::operator<(const Date& rhs)
293
int days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
294
int days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
295
return (days_left < days_right);
297
bool Date::operator<=(const Date& rhs)
299
int days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
300
int days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
301
return (days_left <= days_right);
303
bool Date::operator>(const Date& rhs)
305
return ! (*this <= rhs);
307
bool Date::operator>=(const Date& rhs)
309
return ! (*this < rhs);
313
* Comparison operators for DateTime against another DateTime
314
* are easy. We simply compare the cumulative time
317
bool DateTime::operator==(const DateTime& rhs)
321
&& _months == rhs._months
322
&& _days == rhs._days
323
&& _hours == rhs._hours
324
&& _minutes == rhs._minutes
325
&& _seconds == rhs._seconds
326
&& _useconds == rhs._useconds
327
&& _nseconds == rhs._nseconds
330
bool DateTime::operator!=(const DateTime& rhs)
332
return ! (*this == rhs);
334
bool DateTime::operator<(const DateTime& rhs)
336
int days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
337
int days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
338
if (days_left < days_right)
340
else if (days_left > days_right)
342
/* Here if both dates are the same, so compare times */
343
return (_cumulative_seconds_in_time() < rhs._cumulative_seconds_in_time());
345
bool DateTime::operator<=(const DateTime& rhs)
347
int days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
348
int days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
349
if (days_left < days_right)
351
else if (days_left > days_right)
353
/* Here if both dates are the same, so compare times */
354
return (_cumulative_seconds_in_time() <= rhs._cumulative_seconds_in_time());
356
bool DateTime::operator>(const DateTime& rhs)
358
return ! (*this <= rhs);
360
bool DateTime::operator>=(const DateTime& rhs)
362
return ! (*this < rhs);
366
* We can add or subtract a Time value to/from a DateTime value
367
* as well...it always produces a DateTime.
369
const DateTime DateTime::operator-(const Time& rhs)
374
* First, we set the resulting DATE pieces equal to our
375
* left-hand side DateTime's DATE components. Then, deal with
376
* the time components.
378
result._years= _years;
379
result._months= _months;
382
int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
385
* The resulting diff might be negative. If it is, that means that
386
* we have subtracting a larger time piece from the datetime, like so:
388
* x = DateTime("2007-06-09 09:30:00") - Time("16:30:00");
390
* In these cases, we need to subtract a day from the resulting
396
result._hours= second_diff % DRIZZLE_SECONDS_IN_HOUR;
397
second_diff-= (result._hours * DRIZZLE_SECONDS_IN_HOUR);
398
result._minutes= second_diff % DRIZZLE_SECONDS_IN_MINUTE;
399
second_diff-= (result._minutes * DRIZZLE_SECONDS_IN_MINUTE);
400
result._seconds= second_diff;
402
/* Handle the microsecond precision */
403
int64_t microsecond_diff= _useconds - rhs._useconds;
404
if (microsecond_diff < 0)
406
microsecond_diff= (-1 * microsecond_diff);
409
result._useconds= microsecond_diff;
413
const DateTime DateTime::operator+(const Time& rhs)
418
* First, we set the resulting DATE pieces equal to our
419
* left-hand side DateTime's DATE components. Then, deal with
420
* the time components.
422
result._years= _years;
423
result._months= _months;
426
int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
429
* The resulting seconds might be more than a day. If do,
430
* adjust our resulting days up 1.
432
if (second_diff >= DRIZZLE_SECONDS_IN_DAY)
435
second_diff-= (result._days * DRIZZLE_SECONDS_IN_DAY);
438
result._hours= second_diff % DRIZZLE_SECONDS_IN_HOUR;
439
second_diff-= (result._hours * DRIZZLE_SECONDS_IN_HOUR);
440
result._minutes= second_diff % DRIZZLE_SECONDS_IN_MINUTE;
441
second_diff-= (result._minutes * DRIZZLE_SECONDS_IN_MINUTE);
442
result._seconds= second_diff;
444
/* Handle the microsecond precision */
445
int64_t microsecond_diff= _useconds - rhs._useconds;
446
if (microsecond_diff < 0)
448
microsecond_diff= (-1 * microsecond_diff);
451
result._useconds= microsecond_diff;
457
* Variation of + and - operator which returns a reference to the left-hand
458
* side DateTime object and adds the right-hand side Time to itself.
460
DateTime& DateTime::operator+=(const Time& rhs)
462
int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
464
* The resulting seconds might be more than a day. If do,
465
* adjust our resulting days up 1.
467
if (second_diff >= DRIZZLE_SECONDS_IN_DAY)
470
second_diff-= (_days * DRIZZLE_SECONDS_IN_DAY);
473
_hours= second_diff % DRIZZLE_SECONDS_IN_HOUR;
474
second_diff-= (_hours * DRIZZLE_SECONDS_IN_HOUR);
475
_minutes= second_diff % DRIZZLE_SECONDS_IN_MINUTE;
476
second_diff-= (_minutes * DRIZZLE_SECONDS_IN_MINUTE);
477
_seconds= second_diff;
479
/* Handle the microsecond precision */
480
int64_t microsecond_diff= _useconds - rhs._useconds;
481
if (microsecond_diff < 0)
483
microsecond_diff= (-1 * microsecond_diff);
486
_useconds= microsecond_diff;
488
* @TODO Once exceptions are supported, we should raise an error here if
489
* the result Time is not valid?
493
DateTime& DateTime::operator-=(const Time& rhs)
495
int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
498
* The resulting diff might be negative. If it is, that means that
499
* we have subtracting a larger time piece from the datetime, like so:
501
* x = DateTime("2007-06-09 09:30:00");
502
* x-= Time("16:30:00");
504
* In these cases, we need to subtract a day from the resulting
510
_hours= second_diff % DRIZZLE_SECONDS_IN_HOUR;
511
second_diff-= (_hours * DRIZZLE_SECONDS_IN_HOUR);
512
_minutes= second_diff % DRIZZLE_SECONDS_IN_MINUTE;
513
second_diff-= (_minutes * DRIZZLE_SECONDS_IN_MINUTE);
514
_seconds= second_diff;
516
/* Handle the microsecond precision */
517
int64_t microsecond_diff= _useconds - rhs._useconds;
518
if (microsecond_diff < 0)
520
microsecond_diff= (-1 * microsecond_diff);
523
_useconds= microsecond_diff;
525
* @TODO Once exceptions are supported, we should raise an error here if
526
* the result Time is not valid?
532
* We can add/subtract two Dates to/from each other. The result
533
* is always another Date instance.
535
const Date Date::operator-(const Date &rhs)
537
/* Figure out the difference in days between the two dates */
538
int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
539
int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
540
int64_t day_diff= day_left - day_right;
543
/* Now re-compose the Date's structure from the resulting Julian Day Number */
544
gregorian_date_from_julian_day_number(day_diff, &result._years, &result._months, &result._days);
547
const Date Date::operator+(const Date &rhs)
550
* Figure out the new Julian Day Number by adding the JDNs of both
553
int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
554
int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
555
int64_t day_diff= day_left + day_right;
557
/** @TODO Need an exception check here for bounds of JDN... */
560
/* Now re-compose the Date's structure from the resulting Julian Day Number */
561
gregorian_date_from_julian_day_number(day_diff, &result._years, &result._months, &result._days);
564
/* Similar to the above, but we add/subtract the right side to this object itself */
565
Date& Date::operator-=(const Date &rhs)
567
int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
568
int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
569
int64_t day_diff= day_left - day_right;
571
/* Now re-compose the Date's structure from the resulting Julian Day Number */
572
gregorian_date_from_julian_day_number(day_diff, &_years, &_months, &_days);
575
Date& Date::operator+=(const Date &rhs)
578
* Figure out the new Julian Day Number by adding the JDNs of both
581
int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
582
int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
583
int64_t day_diff= day_left + day_right;
585
/** @TODO Need an exception check here for bounds of JDN... */
587
/* Now re-compose the Date's structure from the resulting Julian Day Number */
588
gregorian_date_from_julian_day_number(day_diff, &_years, &_months, &_days);
593
* We can add/subtract two DateTimes to/from each other. The result
594
* is always another DateTime instance.
596
const DateTime DateTime::operator-(const DateTime &rhs)
598
/* Figure out the difference in days between the two dates. */
599
int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
600
int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
601
int64_t day_diff= day_left - day_right;
604
/* Now re-compose the Date's structure from the resulting Julian Day Number */
605
gregorian_date_from_julian_day_number(day_diff, &result._years, &result._months, &result._days);
607
/* And now handle the time components */
608
int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
611
* The resulting diff might be negative. If it is, that means that
612
* we have subtracting a larger time piece from the datetime, like so:
614
* x = DateTime("2007-06-09 09:30:00");
615
* x-= Time("16:30:00");
617
* In these cases, we need to subtract a day from the resulting
623
result._hours= second_diff % DRIZZLE_SECONDS_IN_HOUR;
624
second_diff-= (result._hours * DRIZZLE_SECONDS_IN_HOUR);
625
result._minutes= second_diff % DRIZZLE_SECONDS_IN_MINUTE;
626
second_diff-= (result._minutes * DRIZZLE_SECONDS_IN_MINUTE);
627
result._seconds= second_diff;
629
/* Handle the microsecond precision */
630
int64_t microsecond_diff= _useconds - rhs._useconds;
631
if (microsecond_diff < 0)
633
microsecond_diff= (-1 * microsecond_diff);
636
result._useconds= microsecond_diff;
640
const DateTime DateTime::operator+(const DateTime &rhs)
643
* Figure out the new Julian Day Number by adding the JDNs of both
646
int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
647
int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
648
int64_t day_diff= day_left + day_right;
650
/** @TODO Need an exception check here for bounds of JDN... */
653
/* Now re-compose the Date's structure from the resulting Julian Day Number */
654
gregorian_date_from_julian_day_number(day_diff, &result._years, &result._months, &result._days);
656
/* And now handle the time components */
657
int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
660
* The resulting seconds might be more than a day. If do,
661
* adjust our resulting days up 1.
663
if (second_diff >= DRIZZLE_SECONDS_IN_DAY)
666
second_diff-= (result._days * DRIZZLE_SECONDS_IN_DAY);
669
result._hours= second_diff % DRIZZLE_SECONDS_IN_HOUR;
670
second_diff-= (result._hours * DRIZZLE_SECONDS_IN_HOUR);
671
result._minutes= second_diff % DRIZZLE_SECONDS_IN_MINUTE;
672
second_diff-= (result._minutes * DRIZZLE_SECONDS_IN_MINUTE);
673
result._seconds= second_diff;
675
/* Handle the microsecond precision */
676
int64_t microsecond_diff= _useconds - rhs._useconds;
677
if (microsecond_diff < 0)
679
microsecond_diff= (-1 * microsecond_diff);
682
result._useconds= microsecond_diff;
686
/* Similar to the above, but we add/subtract the right side to this object itself */
687
DateTime& DateTime::operator-=(const DateTime &rhs)
689
/* Figure out the difference in days between the two dates. */
690
int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
691
int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
692
int64_t day_diff= day_left - day_right;
694
/* Now re-compose the Date's structure from the ng Julian Day Number */
695
gregorian_date_from_julian_day_number(day_diff, &_years, &_months, &_days);
697
/* And now handle the time components */
698
int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
701
* The resulting diff might be negative. If it is, that means that
702
* we have subtracting a larger time piece from the datetime, like so:
704
* x = DateTime("2007-06-09 09:30:00");
705
* x-= Time("16:30:00");
707
* In these cases, we need to subtract a day from the ng
713
_hours= second_diff % DRIZZLE_SECONDS_IN_HOUR;
714
second_diff-= (_hours * DRIZZLE_SECONDS_IN_HOUR);
715
_minutes= second_diff % DRIZZLE_SECONDS_IN_MINUTE;
716
second_diff-= (_minutes * DRIZZLE_SECONDS_IN_MINUTE);
717
_seconds= second_diff;
719
/* Handle the microsecond precision */
720
int64_t microsecond_diff= _useconds - rhs._useconds;
721
if (microsecond_diff < 0)
723
microsecond_diff= (-1 * microsecond_diff);
726
_useconds= microsecond_diff;
730
DateTime& DateTime::operator+=(const DateTime &rhs)
733
* Figure out the new Julian Day Number by adding the JDNs of both
736
int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
737
int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
738
int64_t day_diff= day_left + day_right;
740
/** @TODO Need an exception check here for bounds of JDN... */
742
/* Now re-compose the Date's structure from the ng Julian Day Number */
743
gregorian_date_from_julian_day_number(day_diff, &_years, &_months, &_days);
745
/* And now handle the time components */
746
int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
749
* The resulting seconds might be more than a day. If do,
750
* adjust our ng days up 1.
752
if (second_diff >= DRIZZLE_SECONDS_IN_DAY)
755
second_diff-= (_days * DRIZZLE_SECONDS_IN_DAY);
758
_hours= second_diff % DRIZZLE_SECONDS_IN_HOUR;
759
second_diff-= (_hours * DRIZZLE_SECONDS_IN_HOUR);
760
_minutes= second_diff % DRIZZLE_SECONDS_IN_MINUTE;
761
second_diff-= (_minutes * DRIZZLE_SECONDS_IN_MINUTE);
762
_seconds= second_diff;
764
/* Handle the microsecond precision */
765
int64_t microsecond_diff= _useconds - rhs._useconds;
766
if (microsecond_diff < 0)
768
microsecond_diff= (-1 * microsecond_diff);
771
_useconds= microsecond_diff;
777
* Comparison operators between two Timestamps
779
bool Timestamp::operator==(const Timestamp& rhs)
781
return (_epoch_seconds == rhs._epoch_seconds);
783
bool Timestamp::operator!=(const Timestamp& rhs)
785
return ! (*this == rhs);
787
bool Timestamp::operator<(const Timestamp& rhs)
789
return (_epoch_seconds < rhs._epoch_seconds);
791
bool Timestamp::operator<=(const Timestamp& rhs)
793
return (_epoch_seconds <= rhs._epoch_seconds);
795
bool Timestamp::operator>(const Timestamp& rhs)
797
return ! (*this < rhs);
799
bool Timestamp::operator>=(const Timestamp& rhs)
801
return ! (*this <= rhs);
805
bool Time::from_string(const char *from, size_t from_len)
808
* Loop through the known time formats and see if
812
TemporalFormat *current_format;
813
std::vector<TemporalFormat *>::iterator current= known_time_formats.begin();
815
while (current != known_time_formats.end())
817
current_format= *current;
818
if (current_format->matches(from, from_len, this))
832
void Time::to_string(char *to, size_t *to_len) const
835
, "%02" PRIu32 ":%02" PRIu32 ":%02" PRIu32
841
void Date::to_string(char *to, size_t *to_len) const
844
, "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32
850
void DateTime::to_string(char *to, size_t *to_len) const
853
, "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32 " %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32
862
void MicroTimestamp::to_string(char *to, size_t *to_len) const
865
, "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32 " %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 ".%06" PRIu32
875
void Time::to_decimal(my_decimal *to) const
877
int64_t time_portion= (((_hours * 100L) + _minutes) * 100L) + _seconds;
878
(void) int2my_decimal(E_DEC_FATAL_ERROR, time_portion, false, to);
881
to->buf[(to->intg-1) / 9 + 1]= _useconds * 1000;
886
void Date::to_decimal(my_decimal *to) const
888
int64_t date_portion= (((_years * 100L) + _months) * 100L) + _days;
889
(void) int2my_decimal(E_DEC_FATAL_ERROR, date_portion, false, to);
892
void DateTime::to_decimal(my_decimal *to) const
894
int64_t date_portion= (((_years * 100L) + _months) * 100L) + _days;
895
int64_t time_portion= (((((date_portion * 100L) + _hours) * 100L) + _minutes) * 100L) + _seconds;
896
(void) int2my_decimal(E_DEC_FATAL_ERROR, time_portion, false, to);
899
to->buf[(to->intg-1) / 9 + 1]= _useconds * 1000;
904
void Date::to_int64_t(int64_t *to) const
906
*to= (_years * INT32_C(10000))
907
+ (_months * INT32_C(100))
911
void Date::to_int32_t(int32_t *to) const
913
*to= (_years * INT32_C(10000))
914
+ (_months * INT32_C(100))
918
void Time::to_int32_t(int32_t *to) const
920
*to= (_hours * INT32_C(10000))
921
+ (_minutes * INT32_C(100))
925
void DateTime::to_int64_t(int64_t *to) const
928
(_years * INT64_C(10000))
929
+ (_months * INT64_C(100))
931
) * INT64_C(1000000))
933
(_hours * INT64_C(10000))
934
+ (_minutes * INT64_C(100) )
939
void Date::to_tm(struct tm *to) const
944
to->tm_mday= _days; /* Drizzle format uses ordinal, standard tm does too! */
945
to->tm_mon= _months - 1; /* Drizzle format uses ordinal, standard tm does NOT! */
946
to->tm_year= _years - 1900;
949
void DateTime::to_tm(struct tm *to) const
951
to->tm_sec= _seconds;
952
to->tm_min= _minutes;
954
to->tm_mday= _days; /* Drizzle format uses ordinal, standard tm does too! */
955
to->tm_mon= _months - 1; /* Drizzle format uses ordinal, standard tm does NOT! */
956
to->tm_year= _years - 1900;
960
* We assume that the supplied integer is an
961
* absolute day number (for instance, from the FROM_DAYS()
964
bool Date::from_julian_day_number(const int64_t from)
967
* First convert the absolute day number into a Julian
968
* Day Number and then run a standard conversion on the
971
gregorian_date_from_julian_day_number(from, &_years, &_months, &_days);
976
* Ignore overflow and pass-through to DateTime::from_int64_t()
978
bool Date::from_int32_t(const int32_t from)
980
return ((DateTime *) this)->from_int64_t((int64_t) from);
984
* Attempt to interpret the supplied 4-byte integer as
985
* a TIME value in the format HHmmSS
987
bool Time::from_int32_t(const int32_t from)
989
int32_t copy_from= from;
990
_hours= copy_from % INT32_C(10000);
991
_minutes= copy_from % INT32_C(100);
992
_seconds= copy_from & 3; /* Masks off all but last 2 digits */
997
* We try to intepret the incoming number as a datetime "string".
998
* This is pretty much a hack for usability, but keeps us compatible
1001
bool DateTime::from_int64_t(const int64_t from)
1003
int64_t copy_from= from;
1007
if (! (copy_from == 0LL || copy_from >= 10000101000000LL))
1009
if (copy_from < 101)
1011
if (copy_from <= (DRIZZLE_YY_PART_YEAR-1)*10000L+1231L)
1012
copy_from= (copy_from+20000000L)*1000000L; /* YYMMDD, year: 2000-2069 */
1013
if (copy_from < (DRIZZLE_YY_PART_YEAR)*10000L+101L)
1015
if (copy_from <= 991231L)
1016
copy_from= (copy_from+19000000L)*1000000L; /* YYMMDD, year: 1970-1999 */
1017
if (copy_from < 10000101L)
1019
if (copy_from <= 99991231L)
1020
copy_from= copy_from*1000000L;
1021
if (copy_from < 101000000L)
1023
if (copy_from <= (DRIZZLE_YY_PART_YEAR-1) * 10000000000LL + 1231235959LL)
1024
copy_from= copy_from + 20000000000000LL; /* YYMMDDHHMMSS, 2000-2069 */
1025
if (copy_from < DRIZZLE_YY_PART_YEAR * 10000000000LL + 101000000LL)
1027
if (copy_from <= 991231235959LL)
1028
copy_from= copy_from + 19000000000000LL; /* YYMMDDHHMMSS, 1970-1999 */
1031
part1= (int64_t) (copy_from / 1000000LL);
1032
part2= (int64_t) (copy_from - (int64_t) part1 * 1000000LL);
1033
_years= (uint32_t) (part1/10000L);
1036
_months= (uint32_t) part1 / 100;
1037
_days= (uint32_t) part1 % 100;
1038
_hours= (uint32_t) (part2/10000L);
1041
_minutes= (uint32_t) part2 / 100;
1042
_seconds= (uint32_t) part2 % 100;
1044
set_epoch_seconds();
1048
bool Date::in_unix_epoch() const
1050
return in_unix_epoch_range(_years, _months, _days, 0, 0, 0);
1053
bool DateTime::in_unix_epoch() const
1055
return in_unix_epoch_range(_years, _months, _days, _hours, _minutes, _seconds);
1058
bool Date::from_tm(const struct tm *from)
1060
_years= 1900 + from->tm_year;
1061
_months= 1 + from->tm_mon; /* Month is NOT ordinal for struct tm! */
1062
_days= from->tm_mday; /* Day IS ordinal for struct tm */
1063
_hours= from->tm_hour;
1064
_minutes= from->tm_min;
1065
_seconds= from->tm_sec;
1066
/* Set hires precision to zero */
1070
set_epoch_seconds();
1074
bool Date::from_time_t(const time_t from)
1076
struct tm broken_time;
1079
result= gmtime_r(&from, &broken_time);
1082
_years= 1900 + broken_time.tm_year;
1083
_months= 1 + broken_time.tm_mon; /* Month is NOT ordinal for struct tm! */
1084
_days= broken_time.tm_mday; /* Day IS ordinal for struct tm */
1089
/* Set hires precision to zero */
1098
bool DateTime::from_time_t(const time_t from)
1100
struct tm broken_time;
1103
result= gmtime_r(&from, &broken_time);
1106
_years= 1900 + broken_time.tm_year;
1107
_months= 1 + broken_time.tm_mon; /* Month is NOT ordinal for struct tm! */
1108
_days= broken_time.tm_mday; /* Day IS ordinal for struct tm */
1109
_hours= broken_time.tm_hour;
1110
_minutes= broken_time.tm_min;
1111
_seconds= broken_time.tm_sec;
1112
_epoch_seconds= from;
1113
/* Set hires precision to zero */
1122
void Date::to_time_t(time_t *to) const
1124
if (in_unix_epoch())
1125
*to= _epoch_seconds;
1129
void Timestamp::to_time_t(time_t *to) const
1131
*to= _epoch_seconds;
1134
void MicroTimestamp::to_timeval(struct timeval *to) const
1136
to->tv_sec= _epoch_seconds;
1137
to->tv_usec= _useconds;
1140
void NanoTimestamp::to_timespec(struct timespec *to) const
1142
to->tv_sec= _epoch_seconds;
1143
to->tv_nsec= _nseconds;
1146
bool Date::is_valid() const
1148
return (_years >= DRIZZLE_MIN_YEARS_SQL && _years <= DRIZZLE_MAX_YEARS_SQL)
1149
&& (_months >= 1 && _months <= 12)
1150
&& (_days >= 1 && _days <= days_in_gregorian_year_month(_years, _months));
1153
bool Time::is_valid() const
1155
return (_years == 0)
1160
&& (_seconds <= 59); /* No Leap second... TIME is for elapsed time... */
1163
bool DateTime::is_valid() const
1165
return (_years >= DRIZZLE_MIN_YEARS_SQL && _years <= DRIZZLE_MAX_YEARS_SQL)
1166
&& (_months >= 1 && _months <= 12)
1167
&& (_days >= 1 && _days <= days_in_gregorian_year_month(_years, _months))
1170
&& (_seconds <= 61); /* Leap second... */
1173
bool Timestamp::is_valid() const
1175
return in_unix_epoch_range(_years, _months, _days, _hours, _minutes, _seconds);
1178
bool MicroTimestamp::is_valid() const
1180
return in_unix_epoch_range(_years, _months, _days, _hours, _minutes, _seconds)
1181
&& (_useconds <= UINT32_C(999999));
1184
bool NanoTimestamp::is_valid() const
1186
return in_unix_epoch_range(_years, _months, _days, _hours, _minutes, _seconds)
1187
&& (_useconds <= UINT32_C(999999))
1188
&& (_nseconds <= UINT32_C(999999999));
1191
} /* end namespace drizzled */