34
34
* their single parameter.
39
#include <drizzled/charset_info.h>
40
#include <drizzled/type/decimal.h>
41
#include <drizzled/calendar.h>
42
#include <drizzled/temporal.h>
43
#include <drizzled/temporal_format.h>
44
#include <drizzled/time_functions.h>
47
#include <drizzled/util/gmtime.h>
37
#include "drizzled/global.h"
39
#include "mystrings/m_ctype.h"
40
#include "drizzled/my_decimal.h"
41
#include "drizzled/calendar.h"
42
#include "drizzled/temporal.h"
43
#ifdef NOTYETIMPLEMENTED
44
#include "drizzled/temporal_interval.h"
46
#include "drizzled/temporal_format.h"
55
49
#include <string.h>
51
/* time.h may already have been included in global.h, but we
52
need to pick up the extra defs as well, after the global time.h */
53
#ifndef HAVE_DECL_TIMEGM
54
# include <gnulib/time.h>
57
extern std::vector<drizzled::TemporalFormat *> known_datetime_formats;
58
extern std::vector<drizzled::TemporalFormat *> known_date_formats;
59
extern std::vector<drizzled::TemporalFormat *> known_time_formats;
60
extern std::vector<TemporalFormat *> known_datetime_formats;
61
extern std::vector<TemporalFormat *> known_date_formats;
62
extern std::vector<TemporalFormat *> known_time_formats;
64
Temporal::Temporal() :
78
79
uint64_t Temporal::_cumulative_seconds_in_time() const
798
#ifdef NOTYETIMPLEMENTED
799
Date& Date::operator+=(const TemporalIntervalYear &rhs)
801
/* Simple one...add the years and adjust for any leaps */
802
int64_t new_years= _years;
803
new_years+= rhs._years;
804
if (new_years > DRIZZLE_MAX_YEARS_SQL)
807
* Set everything to zero. We got an overflow.
808
* @TODO Exceptions would be great here...
814
_years= (uint32_t) new_years;
815
if (_months == 2 && _days == 29 && days_in_gregorian_year_month(_years, _months) != 366)
820
Date& Date::operator-=(const TemporalIntervalYear &rhs)
822
/* Simple one...subtract the years and adjust for any leaps */
823
int64_t new_years= _years;
824
new_years-= rhs._years;
828
* Set everything to zero. We got an overflow.
829
* @TODO Exceptions would be great here...
835
_years= (uint32_t) new_years;
836
if (_months == 2 && _days == 29 && days_in_gregorian_year_month(_years, _months) != 366)
841
Date& Date::operator+=(const TemporalIntervalDayOrWeek &rhs)
843
/* Simple one...add the days */
844
int64_t julian_day= julian_day_number_from_gregorian_date(_years, _months, _days) + rhs._days;
845
gregorian_date_from_julian_day_number(julian_day, &_years, &_months, &_days);
849
Date& Date::operator-=(const TemporalIntervalDayOrWeek &rhs)
851
/* Simple one...subtract the days */
852
int64_t julian_day= julian_day_number_from_gregorian_date(_years, _months, _days) - rhs._days;
853
gregorian_date_from_julian_day_number(julian_day, &_years, &_months, &_days);
857
Date& Date::operator+=(const TemporalIntervalYearMonth &rhs)
859
/* Simple one...add the months in the period adjust */
860
int64_t period= (_years * 12) + (rhs._years * 12) + (_months - 1) + rhs._months;
861
int64_t new_years= (period / 12);
862
if (new_years > DRIZZLE_MAX_YEARS_SQL)
865
* Set everything to zero. We got an overflow.
866
* @TODO Exceptions would be great here...
872
_years= (uint32_t) new_years;
873
_months= (uint32_t) (period % 12) + 1;
875
/* Adjust day if the new month doesn't have enough days */
876
uint32_t days_in_new_month= days_in_gregorian_year_month(_years, _months);
877
if (_days > days_in_new_month)
878
_days= days_in_new_month;
882
Date& Date::operator-=(const TemporalIntervalYearMonth &rhs)
884
/* Simple one...subtract the months in the period and adjust */
885
int64_t period= (_years * 12) - (rhs._years * 12) + (_months - 1) - rhs._months;
886
int64_t new_years= (period / 12);
890
* Set everything to zero. We got an overflow.
891
* @TODO Exceptions would be great here...
897
_years= (uint32_t) (period / 12);
898
_months= (uint32_t) (period % 12) + 1;
900
/* Adjust day if the new month doesn't have enough days */
901
uint32_t days_in_new_month= days_in_gregorian_year_month(_years, _months);
902
if (_days > days_in_new_month)
903
_days= days_in_new_month;
907
Date& Date::operator+=(const TemporalIntervalDayOrLess &rhs)
910
* Convert the temporal and the interval into a number of
911
* microseconds, then add them together and convert the
912
* resulting microseconds back into a broken-down temporal
916
int64_t new_microseconds;
919
new_microseconds= _useconds + rhs._useconds;
920
extra_sec= new_microseconds / INT64_C(1000000);
921
new_microseconds= new_microseconds % INT64_C(1000000);
923
new_seconds= ((_days - 1) * 3600 * 24) + (_hours * 3600) + (_minutes * 60) + _seconds;
924
new_seconds+= (rhs._days * 3600 * 24) + (rhs._hours * 3600) + (rhs._minutes * 60) + rhs._seconds;
925
new_seconds+= extra_sec;
927
if (new_microseconds < 0)
929
new_microseconds+= INT64_C(1000000);
933
new_days= new_seconds / (3600 * 24L);
934
new_seconds-= new_days * 3600 * 24L;
938
new_seconds+= 3600 * 24L;
940
_useconds= (uint32_t) new_microseconds;
941
_seconds= (uint32_t) (new_seconds % 60);
942
_minutes= (uint32_t) ((new_seconds / 60) % 60);
943
_hours= (uint32_t) (new_seconds / 3600);
944
int64_t julian_day= julian_day_number_from_gregorian_date(_years, _months, 1) + new_days;
945
gregorian_date_from_julian_day_number(julian_day, &_years, &_months, &_days);
949
Date& Date::operator-=(const TemporalIntervalDayOrLess &rhs)
952
* Convert the temporal and the interval into a number of
953
* microseconds, then subtract them from each other and convert
954
* the resulting microseconds back into a broken-down temporal
958
int64_t new_microseconds;
961
new_microseconds= _useconds - rhs._useconds;
962
extra_sec= new_microseconds / INT64_C(1000000);
963
new_microseconds= new_microseconds % INT64_C(1000000);
965
new_seconds= ((_days - 1) * 3600 * 24) + (_hours * 3600) + (_minutes * 60) + _seconds;
966
new_seconds-= (rhs._days * 3600 * 24) + (rhs._hours * 3600) + (rhs._minutes * 60) + rhs._seconds;
967
new_seconds+= extra_sec;
969
if (new_microseconds < 0)
971
new_microseconds+= INT64_C(1000000);
975
new_days= new_seconds / (3600 * 24L);
976
new_seconds-= new_days * 3600 * 24L;
980
new_seconds+= 3600 * 24L;
982
_useconds= (uint32_t) new_microseconds;
983
_seconds= (uint32_t) (new_seconds % 60);
984
_minutes= (uint32_t) ((new_seconds / 60) % 60);
985
_hours= (uint32_t) (new_seconds / 3600);
986
int64_t julian_day= julian_day_number_from_gregorian_date(_years, _months, 1) + new_days;
987
gregorian_date_from_julian_day_number(julian_day, &_years, &_months, &_days);
990
#endif /* NOTYETIMPLEMENTED */
838
* Comparison operators between a Date and a Timestamp
992
* Comparison operators between two Timestamps
840
994
bool Date::operator==(const Timestamp& rhs)
842
return (_years == rhs._years && _months == rhs._months && _days == rhs._days);
996
return (_epoch_seconds == rhs._epoch_seconds);
844
998
bool Date::operator!=(const Timestamp& rhs)
848
1002
bool Date::operator<(const Timestamp& rhs)
850
if (_years < rhs._years)
852
if (_years > rhs._years)
855
if (_months < rhs._months)
857
if (_months > rhs._months)
860
return _days < rhs._days;
1004
return (_epoch_seconds < rhs._epoch_seconds);
862
1006
bool Date::operator<=(const Timestamp& rhs)
864
return (*this < rhs || *this == rhs);
1008
return (_epoch_seconds <= rhs._epoch_seconds);
866
1010
bool Date::operator>(const Timestamp& rhs)
868
return ! (*this <= rhs);
1012
return ! (*this < rhs);
870
1014
bool Date::operator>=(const Timestamp& rhs)
872
return ! (*this < rhs);
875
* Comparison operators between a Timestamp and a Date
877
bool Timestamp::operator==(const Date& rhs)
879
return (_years == rhs._years && _months == rhs._months && _days == rhs._days);
881
bool Timestamp::operator!=(const Date& rhs)
883
return ! (*this == rhs);
885
bool Timestamp::operator<(const Date& rhs)
887
if (_years < rhs._years)
889
if (_years > rhs._years)
892
if (_months < rhs._months)
894
if (_months > rhs._months)
897
return _days < rhs._days;
899
bool Timestamp::operator<=(const Date& rhs)
901
return (*this < rhs || *this == rhs);
903
bool Timestamp::operator>(const Date& rhs)
905
return ! (*this <= rhs);
907
bool Timestamp::operator>=(const Date& rhs)
909
return ! (*this < rhs);
912
* Comparison operators between a Timestamp and a DateTime
914
bool Timestamp::operator==(const DateTime& rhs)
916
return (_years == rhs._years && _months == rhs._months && _days == rhs._days
917
&& _hours == rhs._hours && _minutes == rhs._minutes && _seconds == rhs._seconds);
919
bool Timestamp::operator!=(const DateTime& rhs)
921
return ! (*this == rhs);
923
bool Timestamp::operator<(const DateTime& rhs)
925
if (_years < rhs._years)
927
if (_years > rhs._years)
930
if (_months < rhs._months)
932
if (_months > rhs._months)
935
if (_days < rhs._days)
937
if (_days > rhs._days)
940
if (_hours < rhs._hours)
942
if (_hours > rhs._hours)
945
if (_minutes < rhs._minutes)
947
if (_minutes > rhs._minutes)
950
return _seconds < rhs._seconds;
952
bool Timestamp::operator<=(const DateTime& rhs)
954
return (*this < rhs || *this == rhs);
956
bool Timestamp::operator>(const DateTime& rhs)
958
return ! (*this <= rhs);
960
bool Timestamp::operator>=(const DateTime& rhs)
962
return ! (*this < rhs);
965
* Comparison operators between two Timestamps
967
bool Timestamp::operator==(const Timestamp& rhs)
969
return (_epoch_seconds == rhs._epoch_seconds);
971
bool Timestamp::operator!=(const Timestamp& rhs)
973
return ! (*this == rhs);
975
bool Timestamp::operator<(const Timestamp& rhs)
977
return (_epoch_seconds < rhs._epoch_seconds);
979
bool Timestamp::operator<=(const Timestamp& rhs)
981
return (_epoch_seconds <= rhs._epoch_seconds);
983
bool Timestamp::operator>(const Timestamp& rhs)
985
return ! (*this <= rhs);
987
bool Timestamp::operator>=(const Timestamp& rhs)
989
return ! (*this < rhs);
993
* Push the contents of the timestamp into the output stream
994
* as a formatted Timestamp value.
996
* @TODO This unfortunately fails in a weird way...even with std::noskipws,
997
* the output stream only reads up to the space in the string... :(
999
std::ostream& operator<<(std::ostream& os, const Timestamp& subject)
1001
return os << subject.years() << '-'
1002
<< std::setw(2) << std::setfill('0') << subject.months() << '-'
1003
<< std::setw(2) << std::setfill('0') << subject.days() << ' '
1004
<< std::setw(2) << std::setfill('0') << subject.hours() << ':'
1005
<< std::setw(2) << std::setfill('0') << subject.minutes() << ':'
1006
<< std::setw(2) << std::setfill('0') << subject.seconds();
1016
return ! (*this <= rhs);
1009
1019
bool Time::from_string(const char *from, size_t from_len)
1033
return is_fuzzy_valid();
1036
int Time::to_string(char *to, size_t to_len) const
1038
return snprintf(to, to_len,
1039
"%02" PRIu32 ":%02" PRIu32 ":%02" PRIu32,
1040
_hours, _minutes, _seconds);
1043
int Date::to_string(char *to, size_t to_len) const
1045
return snprintf(to, to_len,
1046
"%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32,
1047
_years, _months, _days);
1050
int DateTime::to_string(char *to, size_t to_len) const
1046
void Time::to_string(char *to, size_t *to_len) const
1049
, "%02" PRIu32 ":%02" PRIu32 ":%02" PRIu32
1055
void Date::to_string(char *to, size_t *to_len) const
1058
, "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32
1064
void DateTime::to_string(char *to, size_t *to_len) const
1052
1066
/* If the temporal has a microsecond component, use a slightly different output */
1053
1067
if (_useconds == 0)
1055
return snprintf(to, to_len,
1056
"%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32
1057
" %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32,
1058
_years, _months, _days,
1059
_hours, _minutes, _seconds);
1070
, "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32 " %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32
1063
return snprintf(to, to_len,
1064
"%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32
1065
" %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 ".%06" PRIu32,
1066
_years, _months, _days,
1067
_hours, _minutes, _seconds, _useconds);
1081
, "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32 " %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 ".%06" PRIu32
1071
int MicroTimestamp::to_string(char *to, size_t to_len) const
1092
void MicroTimestamp::to_string(char *to, size_t *to_len) const
1073
return snprintf(to, to_len,
1074
"%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32
1075
" %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 ".%06" PRIu32,
1076
_years, _months, _days,
1077
_hours, _minutes, _seconds, _useconds);
1095
, "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32 " %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 ".%06" PRIu32
1080
void Time::to_decimal(type::Decimal *to) const
1105
void Time::to_decimal(my_decimal *to) const
1082
1107
int64_t time_portion= (((_hours * 100L) + _minutes) * 100L) + _seconds;
1083
(void) int2_class_decimal(E_DEC_FATAL_ERROR, time_portion, false, to);
1108
(void) int2my_decimal(E_DEC_FATAL_ERROR, time_portion, false, to);
1084
1109
if (_useconds > 0)
1086
1111
to->buf[(to->intg-1) / 9 + 1]= _useconds * 1000;
1427
1411
return (_years == 0)
1428
1412
&& (_months == 0)
1429
1413
&& (_days == 0)
1430
&& (_hours <= DRIZZLE_MAX_HOURS)
1431
&& (_minutes <= DRIZZLE_MAX_MINUTES)
1432
&& (_seconds <= DRIZZLE_MAX_SECONDS); /* No Leap second... TIME is for elapsed time... */
1435
bool Time::is_fuzzy_valid() const
1440
return (_years >= DRIZZLE_MIN_YEARS_SQL && _years <= DRIZZLE_MAX_YEARS_SQL)
1441
&& (_months >= 1 && _months <= DRIZZLE_MAX_MONTHS)
1442
&& (_days >= 1 && _days <= days_in_gregorian_year_month(_years, _months))
1443
&& (_hours <= DRIZZLE_MAX_HOURS)
1444
&& (_minutes <= DRIZZLE_MAX_MINUTES)
1445
&& (_seconds <= DRIZZLE_MAX_SECONDS); /* No Leap second... TIME is for elapsed time... */
1416
&& (_seconds <= 59); /* No Leap second... TIME is for elapsed time... */
1448
1419
bool DateTime::is_valid() const
1450
1421
return (_years >= DRIZZLE_MIN_YEARS_SQL && _years <= DRIZZLE_MAX_YEARS_SQL)
1451
&& (_months >= 1 && _months <= DRIZZLE_MAX_MONTHS)
1422
&& (_months >= 1 && _months <= 12)
1452
1423
&& (_days >= 1 && _days <= days_in_gregorian_year_month(_years, _months))
1453
&& (_hours <= DRIZZLE_MAX_HOURS)
1454
&& (_minutes <= DRIZZLE_MAX_MINUTES)
1455
&& (_seconds <= DRIZZLE_MAX_SECONDS_WITH_LEAP); /* Leap second... */
1426
&& (_seconds <= 61); /* Leap second... */
1458
1429
bool Timestamp::is_valid() const
1460
return DateTime::is_valid()
1461
&& in_unix_epoch_range(_years, _months, _days, _hours, _minutes, _seconds)
1462
&& (_seconds <= DRIZZLE_MAX_SECONDS);
1431
return in_unix_epoch_range(_years, _months, _days, _hours, _minutes, _seconds);
1465
1434
bool MicroTimestamp::is_valid() const
1467
return Timestamp::is_valid()
1436
return in_unix_epoch_range(_years, _months, _days, _hours, _minutes, _seconds)
1468
1437
&& (_useconds <= UINT32_C(999999));
1471
1440
bool NanoTimestamp::is_valid() const
1473
return Timestamp::is_valid()
1442
return in_unix_epoch_range(_years, _months, _days, _hours, _minutes, _seconds)
1474
1443
&& (_useconds <= UINT32_C(999999))
1475
1444
&& (_nseconds <= UINT32_C(999999999));
1478
} /* namespace drizzled */
1447
} /* end namespace drizzled */