~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/temporal.cc

  • Committer: Monty Taylor
  • Date: 2009-03-02 23:14:32 UTC
  • mto: This revision was merged to the branch mainline in revision 910.
  • Revision ID: mordred@inaugust.com-20090302231432-i35xehp7uzo6hjjw
Updated build system to use new version numbering. Just remember to run ./config/autorun.sh before running make distcheck for release and all should be peachy.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems, Inc.
 
4
 *  Copyright (C) 2008 Sun Microsystems
5
5
 *
6
6
 *  Authors:
7
7
 *
34
34
 * their single parameter.
35
35
 */
36
36
 
37
 
#include <config.h>
38
 
 
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>
45
 
#include "time.h"
46
 
 
47
 
#include <drizzled/util/gmtime.h>
48
 
 
49
 
#include <time.h>
50
 
 
51
 
#include <cstdio>
52
 
#include <ostream>
53
 
#include <iomanip>
 
37
#include "drizzled/global.h"
 
38
 
 
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"
 
45
#endif
 
46
#include "drizzled/temporal_format.h"
 
47
 
54
48
#include <vector>
55
49
#include <string.h>
56
50
 
 
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>
 
55
#endif
 
56
 
 
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
 
57
61
namespace drizzled 
58
62
{
59
63
 
60
 
extern std::vector<TemporalFormat *> known_datetime_formats;
61
 
extern std::vector<TemporalFormat *> known_date_formats;
62
 
extern std::vector<TemporalFormat *> known_time_formats;
63
 
 
64
 
Temporal::Temporal() :
65
 
  _calendar(GREGORIAN),
66
 
  _years(0),
67
 
  _months(0),
68
 
  _days(0),
69
 
  _hours(0),
70
 
  _minutes(0),
71
 
  _seconds(0),
72
 
  _epoch_seconds(0),
73
 
  _useconds(0),
74
 
  _nseconds(0),
75
 
  _overflow(false)
 
64
Temporal::Temporal()
 
65
:
 
66
  _calendar(GREGORIAN)
 
67
, _years(0)
 
68
, _months(0)
 
69
, _days(0)
 
70
, _hours(0)
 
71
, _minutes(0)
 
72
, _seconds(0)
 
73
, _epoch_seconds(0)
 
74
, _useconds(0)
 
75
, _nseconds(0)
 
76
, _overflow(false)
76
77
{}
77
78
 
78
79
uint64_t Temporal::_cumulative_seconds_in_time() const
82
83
      + _seconds);
83
84
}
84
85
 
85
 
#if defined(TARGET_OS_SOLARIS)
86
 
/* @TODO: Replace this with Boost.DateTime */
87
 
static time_t timegm(struct tm *my_time)
88
 
{
89
 
        time_t local_secs, gm_secs;
90
 
        struct tm gm__rec, *gm_time;
91
 
 
92
 
        // Interpret 't' as the local time and convert it to seconds since the Epoch
93
 
        local_secs = mktime(my_time);
94
 
        if (local_secs == -1)
95
 
  {
96
 
                my_time->tm_hour--;
97
 
                local_secs = mktime (my_time);
98
 
                if (local_secs == -1)
99
 
                        return -1; 
100
 
                local_secs += 3600;
101
 
        }
102
 
        
103
 
        // Get the gmtime based on the local seconds since the Epoch
104
 
        gm_time = util::gmtime(local_secs, &gm__rec);
105
 
        gm_time->tm_isdst = 0;
106
 
        
107
 
        // Interpret gmtime as the local time and convert it to seconds since the Epoch
108
 
        gm_secs = mktime (gm_time);
109
 
        if (gm_secs == -1)
110
 
  {
111
 
                gm_time->tm_hour--;
112
 
                gm_secs = mktime (gm_time);
113
 
                if (gm_secs == -1)
114
 
                        return -1; 
115
 
                gm_secs += 3600;
116
 
        }
117
 
        
118
 
        // Return the local time adjusted by the difference from GM time.
119
 
        return (local_secs - (gm_secs - local_secs));
120
 
}
121
 
#endif
122
 
 
123
86
void Temporal::set_epoch_seconds()
124
87
{
125
88
  /* 
154
117
  TemporalFormat *current_format;
155
118
  std::vector<TemporalFormat *>::iterator current= known_date_formats.begin();
156
119
 
157
 
  _useconds= 0; // We may not match on it, so we need to make sure we zero it out.
158
120
  while (current != known_date_formats.end())
159
121
  {
160
122
    current_format= *current;
244
206
 * This operator is called in the following situation:
245
207
 *
246
208
 * @code
247
 
 * Time lhs;
 
209
 * drizzled::Time lhs;
248
210
 * lhs.from_string("20:00:00");
249
 
 * Time rhs;
 
211
 * drizzled::Time rhs;
250
212
 * rhs.from_string("19:00:00");
251
213
 *
252
 
 * Time result= lhs - rhs;
 
214
 * drizzled::Time result= lhs - rhs;
253
215
 * @endcode
254
216
 *
255
217
 * @note
833
795
 
834
796
  return *this;
835
797
}
836
 
 
 
798
#ifdef NOTYETIMPLEMENTED
 
799
Date& Date::operator+=(const TemporalIntervalYear &rhs)
 
800
{
 
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)
 
805
  {
 
806
    /* 
 
807
     * Set everything to zero. We got an overflow.
 
808
     * @TODO Exceptions would be great here...
 
809
     */
 
810
    _reset();
 
811
    _overflow= true;
 
812
    return *this;
 
813
  }
 
814
  _years= (uint32_t) new_years;
 
815
  if (_months == 2 && _days == 29 && days_in_gregorian_year_month(_years, _months) != 366)
 
816
    _days= 28;
 
817
  return *this;
 
818
 
819
 
 
820
Date& Date::operator-=(const TemporalIntervalYear &rhs)
 
821
{
 
822
  /* Simple one...subtract the years and adjust for any leaps */
 
823
  int64_t new_years= _years;
 
824
  new_years-= rhs._years;
 
825
  if (new_years < 0)
 
826
  {
 
827
    /* 
 
828
     * Set everything to zero. We got an overflow.
 
829
     * @TODO Exceptions would be great here...
 
830
     */
 
831
    _reset();
 
832
    _overflow= true;
 
833
    return *this;
 
834
  }
 
835
  _years= (uint32_t) new_years;
 
836
  if (_months == 2 && _days == 29 && days_in_gregorian_year_month(_years, _months) != 366)
 
837
    _days= 28;
 
838
  return *this;
 
839
 
840
 
 
841
Date& Date::operator+=(const TemporalIntervalDayOrWeek &rhs)
 
842
{
 
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);
 
846
  return *this;
 
847
 
848
 
 
849
Date& Date::operator-=(const TemporalIntervalDayOrWeek &rhs)
 
850
{
 
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);
 
854
  return *this;
 
855
 
856
 
 
857
Date& Date::operator+=(const TemporalIntervalYearMonth &rhs)
 
858
{
 
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)
 
863
  {
 
864
    /* 
 
865
     * Set everything to zero. We got an overflow.
 
866
     * @TODO Exceptions would be great here...
 
867
     */
 
868
    _reset();
 
869
    _overflow= true;
 
870
    return *this;
 
871
  }
 
872
  _years= (uint32_t) new_years;
 
873
  _months= (uint32_t) (period % 12) + 1;
 
874
  
 
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;
 
879
  return *this;
 
880
 
881
 
 
882
Date& Date::operator-=(const TemporalIntervalYearMonth &rhs)
 
883
{
 
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);
 
887
  if (new_years < 0)
 
888
  {
 
889
    /* 
 
890
     * Set everything to zero. We got an overflow.
 
891
     * @TODO Exceptions would be great here...
 
892
     */
 
893
    _reset();
 
894
    _overflow= true;
 
895
    return *this;
 
896
  }
 
897
  _years= (uint32_t) (period / 12);
 
898
  _months= (uint32_t) (period % 12) + 1;
 
899
  
 
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;
 
904
  return *this;
 
905
 
906
 
 
907
Date& Date::operator+=(const TemporalIntervalDayOrLess &rhs)
 
908
{
 
909
  /* 
 
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
 
913
   * component.
 
914
   */
 
915
  int64_t new_seconds;
 
916
  int64_t new_microseconds;
 
917
  int64_t extra_sec;
 
918
  int64_t new_days;
 
919
  new_microseconds= _useconds + rhs._useconds;
 
920
  extra_sec= new_microseconds / INT64_C(1000000);
 
921
  new_microseconds= new_microseconds % INT64_C(1000000);
 
922
 
 
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;
 
926
 
 
927
  if (new_microseconds < 0)
 
928
  {
 
929
    new_microseconds+= INT64_C(1000000);
 
930
    new_seconds--;
 
931
  }
 
932
  
 
933
  new_days= new_seconds / (3600 * 24L);
 
934
  new_seconds-= new_days * 3600 * 24L;
 
935
  if (new_seconds < 0)
 
936
  {
 
937
    new_days--;
 
938
    new_seconds+= 3600 * 24L;
 
939
  }
 
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);
 
946
  return *this;
 
947
}
 
948
 
 
949
Date& Date::operator-=(const TemporalIntervalDayOrLess &rhs)
 
950
{
 
951
  /* 
 
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
 
955
   * component.
 
956
   */
 
957
  int64_t new_seconds;
 
958
  int64_t new_microseconds;
 
959
  int64_t extra_sec;
 
960
  int64_t new_days;
 
961
  new_microseconds= _useconds - rhs._useconds;
 
962
  extra_sec= new_microseconds / INT64_C(1000000);
 
963
  new_microseconds= new_microseconds % INT64_C(1000000);
 
964
 
 
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;
 
968
 
 
969
  if (new_microseconds < 0)
 
970
  {
 
971
    new_microseconds+= INT64_C(1000000);
 
972
    new_seconds--;
 
973
  }
 
974
  
 
975
  new_days= new_seconds / (3600 * 24L);
 
976
  new_seconds-= new_days * 3600 * 24L;
 
977
  if (new_seconds < 0)
 
978
  {
 
979
    new_days--;
 
980
    new_seconds+= 3600 * 24L;
 
981
  }
 
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);
 
988
  return *this;
 
989
}
 
990
#endif /* NOTYETIMPLEMENTED */
837
991
/*
838
 
 * Comparison operators between a Date and a Timestamp
 
992
 * Comparison operators between two Timestamps
839
993
 */
840
994
bool Date::operator==(const Timestamp& rhs)
841
995
{
842
 
  return (_years == rhs._years && _months == rhs._months && _days == rhs._days);
 
996
  return (_epoch_seconds == rhs._epoch_seconds);
843
997
}
844
998
bool Date::operator!=(const Timestamp& rhs)
845
999
{
847
1001
}
848
1002
bool Date::operator<(const Timestamp& rhs)
849
1003
{
850
 
  if (_years < rhs._years)
851
 
    return true;
852
 
  if (_years > rhs._years)
853
 
    return false;
854
 
  /* In same year */
855
 
  if (_months < rhs._months)
856
 
    return true;
857
 
  if (_months > rhs._months)
858
 
    return false;
859
 
  /* Same month */
860
 
  return _days < rhs._days;
 
1004
  return (_epoch_seconds < rhs._epoch_seconds);
861
1005
}
862
1006
bool Date::operator<=(const Timestamp& rhs)
863
1007
{
864
 
  return (*this < rhs || *this == rhs);
 
1008
  return (_epoch_seconds <= rhs._epoch_seconds);
865
1009
}
866
1010
bool Date::operator>(const Timestamp& rhs)
867
1011
{
868
 
  return ! (*this <= rhs);
 
1012
  return ! (*this < rhs);
869
1013
}
870
1014
bool Date::operator>=(const Timestamp& rhs)
871
1015
{
872
 
  return ! (*this < rhs);
873
 
}
874
 
/*
875
 
 * Comparison operators between a Timestamp and a Date
876
 
 */
877
 
bool Timestamp::operator==(const Date& rhs)
878
 
{
879
 
  return (_years == rhs._years && _months == rhs._months && _days == rhs._days);
880
 
}
881
 
bool Timestamp::operator!=(const Date& rhs)
882
 
{
883
 
  return ! (*this == rhs);
884
 
}
885
 
bool Timestamp::operator<(const Date& rhs)
886
 
{
887
 
  if (_years < rhs._years)
888
 
    return true;
889
 
  if (_years > rhs._years)
890
 
    return false;
891
 
  /* In same year */
892
 
  if (_months < rhs._months)
893
 
    return true;
894
 
  if (_months > rhs._months)
895
 
    return false;
896
 
  /* Same month */
897
 
  return _days < rhs._days;
898
 
}
899
 
bool Timestamp::operator<=(const Date& rhs)
900
 
{
901
 
  return (*this < rhs || *this == rhs);
902
 
}
903
 
bool Timestamp::operator>(const Date& rhs)
904
 
{
905
 
  return ! (*this <= rhs);
906
 
}
907
 
bool Timestamp::operator>=(const Date& rhs)
908
 
{
909
 
  return ! (*this < rhs);
910
 
}
911
 
/*
912
 
 * Comparison operators between a Timestamp and a DateTime
913
 
 */
914
 
bool Timestamp::operator==(const DateTime& rhs)
915
 
{
916
 
  return (_years == rhs._years && _months == rhs._months && _days == rhs._days
917
 
          && _hours == rhs._hours && _minutes == rhs._minutes && _seconds == rhs._seconds);
918
 
}
919
 
bool Timestamp::operator!=(const DateTime& rhs)
920
 
{
921
 
  return ! (*this == rhs);
922
 
}
923
 
bool Timestamp::operator<(const DateTime& rhs)
924
 
{
925
 
  if (_years < rhs._years)
926
 
    return true;
927
 
  if (_years > rhs._years)
928
 
    return false;
929
 
  /* In same year */
930
 
  if (_months < rhs._months)
931
 
    return true;
932
 
  if (_months > rhs._months)
933
 
    return false;
934
 
  /* Same month */
935
 
  if (_days < rhs._days)
936
 
    return true;
937
 
  if (_days > rhs._days)
938
 
     return false;
939
 
  /* Same day */
940
 
  if (_hours < rhs._hours)
941
 
    return true;
942
 
  if (_hours > rhs._hours)
943
 
    return false;
944
 
  /* Same hour */
945
 
  if (_minutes < rhs._minutes)
946
 
    return true;
947
 
  if (_minutes > rhs._minutes)
948
 
    return false;
949
 
  /* Same minute */
950
 
  return _seconds < rhs._seconds;
951
 
}
952
 
bool Timestamp::operator<=(const DateTime& rhs)
953
 
{
954
 
  return (*this < rhs || *this == rhs);
955
 
}
956
 
bool Timestamp::operator>(const DateTime& rhs)
957
 
{
958
 
  return ! (*this <= rhs);
959
 
}
960
 
bool Timestamp::operator>=(const DateTime& rhs)
961
 
{
962
 
  return ! (*this < rhs);
963
 
}
964
 
/*
965
 
 * Comparison operators between two Timestamps
966
 
 */
967
 
bool Timestamp::operator==(const Timestamp& rhs)
968
 
{
969
 
  return (_epoch_seconds == rhs._epoch_seconds);
970
 
}
971
 
bool Timestamp::operator!=(const Timestamp& rhs)
972
 
{
973
 
  return ! (*this == rhs);
974
 
}
975
 
bool Timestamp::operator<(const Timestamp& rhs)
976
 
{
977
 
  return (_epoch_seconds < rhs._epoch_seconds);
978
 
}
979
 
bool Timestamp::operator<=(const Timestamp& rhs)
980
 
{
981
 
  return (_epoch_seconds <= rhs._epoch_seconds);
982
 
}
983
 
bool Timestamp::operator>(const Timestamp& rhs)
984
 
{
985
 
  return ! (*this <= rhs);
986
 
}
987
 
bool Timestamp::operator>=(const Timestamp& rhs)
988
 
{
989
 
  return ! (*this < rhs);
990
 
}
991
 
 
992
 
/**
993
 
 * Push the contents of the timestamp into the output stream
994
 
 * as a formatted Timestamp value.
995
 
 *
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... :(
998
 
 */
999
 
std::ostream& operator<<(std::ostream& os, const Timestamp& subject)
1000
 
{
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);
1007
1017
}
1008
1018
 
1009
1019
bool Time::from_string(const char *from, size_t from_len)
1027
1037
    current++;
1028
1038
  }
1029
1039
 
1030
 
  if (not matched)
 
1040
  if (! matched)
1031
1041
    return false;
1032
 
 
1033
 
  return is_fuzzy_valid();
1034
 
}
1035
 
 
1036
 
int Time::to_string(char *to, size_t to_len) const
1037
 
{
1038
 
  return snprintf(to, to_len,
1039
 
                  "%02" PRIu32 ":%02" PRIu32 ":%02" PRIu32,
1040
 
                  _hours, _minutes, _seconds);
1041
 
}
1042
 
 
1043
 
int Date::to_string(char *to, size_t to_len) const
1044
 
{
1045
 
  return snprintf(to, to_len,
1046
 
                  "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32,
1047
 
                  _years, _months, _days);
1048
 
}
1049
 
 
1050
 
int DateTime::to_string(char *to, size_t to_len) const
 
1042
  else
 
1043
    return is_valid();
 
1044
}
 
1045
 
 
1046
void Time::to_string(char *to, size_t *to_len) const
 
1047
{
 
1048
  *to_len= sprintf(to
 
1049
                 , "%02" PRIu32 ":%02" PRIu32 ":%02" PRIu32
 
1050
                 , _hours
 
1051
                 , _minutes
 
1052
                 , _seconds);
 
1053
}
 
1054
 
 
1055
void Date::to_string(char *to, size_t *to_len) const
 
1056
{
 
1057
  *to_len= sprintf(to
 
1058
                 , "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32
 
1059
                 , _years
 
1060
                 , _months
 
1061
                 , _days);
 
1062
}
 
1063
 
 
1064
void DateTime::to_string(char *to, size_t *to_len) const
1051
1065
{
1052
1066
  /* If the temporal has a microsecond component, use a slightly different output */
1053
1067
  if (_useconds == 0)
1054
1068
  {
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);
 
1069
    *to_len= sprintf(to
 
1070
                  , "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32 " %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32
 
1071
                  , _years
 
1072
                  , _months
 
1073
                  , _days
 
1074
                  , _hours
 
1075
                  , _minutes
 
1076
                  , _seconds);
1060
1077
  }
1061
1078
  else
1062
1079
  {
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);
 
1080
    *to_len= sprintf(to
 
1081
                  , "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32 " %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 ".%06" PRIu32
 
1082
                  , _years
 
1083
                  , _months
 
1084
                  , _days
 
1085
                  , _hours
 
1086
                  , _minutes
 
1087
                  , _seconds
 
1088
                  , _useconds);
1068
1089
  }
1069
1090
}
1070
1091
 
1071
 
int MicroTimestamp::to_string(char *to, size_t to_len) const
 
1092
void MicroTimestamp::to_string(char *to, size_t *to_len) const
1072
1093
{
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);
 
1094
  *to_len= sprintf(to
 
1095
                 , "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32 " %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 ".%06" PRIu32
 
1096
                 , _years
 
1097
                 , _months
 
1098
                 , _days
 
1099
                 , _hours
 
1100
                 , _minutes
 
1101
                 , _seconds
 
1102
                 , _useconds);
1078
1103
}
1079
1104
 
1080
 
void Time::to_decimal(type::Decimal *to) const
 
1105
void Time::to_decimal(my_decimal *to) const
1081
1106
{
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)
1085
1110
  {
1086
1111
    to->buf[(to->intg-1) / 9 + 1]= _useconds * 1000;
1088
1113
  }
1089
1114
}
1090
1115
 
1091
 
void Date::to_decimal(type::Decimal *to) const
 
1116
void Date::to_decimal(my_decimal *to) const
1092
1117
{
1093
1118
  int64_t date_portion= (((_years * 100L) + _months) * 100L) + _days;
1094
 
  (void) int2_class_decimal(E_DEC_FATAL_ERROR, date_portion, false, to);
 
1119
  (void) int2my_decimal(E_DEC_FATAL_ERROR, date_portion, false, to);
1095
1120
}
1096
1121
 
1097
 
void DateTime::to_decimal(type::Decimal *to) const
 
1122
void DateTime::to_decimal(my_decimal *to) const
1098
1123
{
1099
1124
  int64_t date_portion= (((_years * 100L) + _months) * 100L) + _days;
1100
1125
  int64_t time_portion= (((((date_portion * 100L) + _hours) * 100L) + _minutes) * 100L) + _seconds;
1101
 
  (void) int2_class_decimal(E_DEC_FATAL_ERROR, time_portion, false, to);
 
1126
  (void) int2my_decimal(E_DEC_FATAL_ERROR, time_portion, false, to);
1102
1127
  if (_useconds > 0)
1103
1128
  {
1104
1129
    to->buf[(to->intg-1) / 9 + 1]= _useconds * 1000;
1127
1152
     + _seconds;
1128
1153
}
1129
1154
 
1130
 
// We fill the structure based on just int
1131
 
void Time::to_uint64_t(uint64_t &to) const
1132
 
{
1133
 
  to= _hours * 24
1134
 
     + _minutes * 60
1135
 
     + _seconds;
1136
 
}
1137
 
 
1138
1155
void DateTime::to_int64_t(int64_t *to) const
1139
1156
{
1140
1157
  *to= ((
1195
1212
bool Time::from_int32_t(const int32_t from)
1196
1213
{
1197
1214
  uint32_t copy_from= (uint32_t) from;
1198
 
  _hours= copy_from / INT32_C(10000);
1199
 
  _minutes= (copy_from % INT32_C(10000)) / INT32_C(100);
1200
 
  _seconds= copy_from % INT32_C(100); /* Masks off all but last 2 digits */
 
1215
  _hours= copy_from % INT32_C(10000);
 
1216
  _minutes= copy_from % INT32_C(100);
 
1217
  _seconds= copy_from & 3; /* Masks off all but last 2 digits */
1201
1218
  return is_valid();
1202
1219
}
1203
1220
 
1206
1223
 * This is pretty much a hack for usability, but keeps us compatible
1207
1224
 * with MySQL.
1208
1225
 */
1209
 
bool DateTime::from_int64_t(const int64_t from, bool convert)
 
1226
bool DateTime::from_int64_t(const int64_t from)
1210
1227
{
1211
1228
  int64_t copy_from= from;
1212
1229
  int64_t part1;
1215
1232
  if (copy_from == 0LL)
1216
1233
    return false;
1217
1234
 
1218
 
  if (convert && copy_from < 10000101000000LL)
 
1235
  if (copy_from < 10000101000000LL)
1219
1236
  {
1220
1237
    if (copy_from < 101)
1221
1238
      return false;
1236
1253
    else if (copy_from <  DRIZZLE_YY_PART_YEAR * 10000000000LL + 101000000LL)
1237
1254
      return false;
1238
1255
    else if (copy_from <= 991231235959LL)
1239
 
      copy_from= copy_from + 19000000000000LL;    /* YYMMDDHHMMSS, 1970-1999 */
 
1256
      copy_from= copy_from + 19000000000000LL;          /* YYMMDDHHMMSS, 1970-1999 */
1240
1257
  }
1241
1258
 
1242
1259
  part1= (int64_t) (copy_from / 1000000LL);
1291
1308
  struct tm broken_time;
1292
1309
  struct tm *result;
1293
1310
 
1294
 
  result= util::gmtime(from, &broken_time);
 
1311
  result= gmtime_r(&from, &broken_time);
1295
1312
  if (result != NULL)
1296
1313
  {
1297
1314
    _years= 0;
1315
1332
  struct tm broken_time;
1316
1333
  struct tm *result;
1317
1334
 
1318
 
  result= util::gmtime(from, &broken_time);
 
1335
  result= gmtime_r(&from, &broken_time);
1319
1336
  if (result != NULL)
1320
1337
  {
1321
1338
    _years= 1900 + broken_time.tm_year;
1334
1351
    return false;
1335
1352
}
1336
1353
 
1337
 
bool DateTime::from_timeval(struct timeval &timeval_arg)
1338
 
{
1339
 
  struct tm broken_time;
1340
 
  struct tm *result;
1341
 
 
1342
 
  result= util::gmtime(timeval_arg.tv_sec, &broken_time);
1343
 
  if (result != NULL)
1344
 
  {
1345
 
    _years= 1900 + broken_time.tm_year;
1346
 
    _months= 1 + broken_time.tm_mon; /* Month is NOT ordinal for struct tm! */
1347
 
    _days= broken_time.tm_mday; /* Day IS ordinal for struct tm */
1348
 
    _hours= broken_time.tm_hour;
1349
 
    _minutes= broken_time.tm_min;
1350
 
    _seconds= broken_time.tm_sec;
1351
 
    _epoch_seconds= timeval_arg.tv_sec;
1352
 
    /* Set hires precision to zero */
1353
 
    _useconds= timeval_arg.tv_usec;
1354
 
    _nseconds= 0;
1355
 
    return is_valid();
1356
 
  }
1357
 
  else 
1358
 
  {
1359
 
    return false;
1360
 
  }
1361
 
}
1362
 
 
1363
1354
bool DateTime::from_time_t(const time_t from)
1364
1355
{
1365
1356
  struct tm broken_time;
1366
1357
  struct tm *result;
1367
1358
 
1368
 
  result= util::gmtime(from, &broken_time);
 
1359
  result= gmtime_r(&from, &broken_time);
1369
1360
  if (result != NULL)
1370
1361
  {
1371
1362
    _years= 1900 + broken_time.tm_year;
1381
1372
    return is_valid();
1382
1373
  }
1383
1374
  else 
1384
 
  {
1385
1375
    return false;
1386
 
  }
1387
1376
}
1388
1377
 
1389
 
void Date::to_time_t(time_t &to) const
 
1378
void Date::to_time_t(time_t *to) const
1390
1379
{
1391
1380
  if (in_unix_epoch())
1392
 
  {
1393
 
    to= _epoch_seconds;
1394
 
  }
1395
 
  else
1396
 
  {
1397
 
    to= 0;
1398
 
  }
1399
 
}
1400
 
 
1401
 
void Timestamp::to_time_t(time_t &to) const
1402
 
{
1403
 
  to= _epoch_seconds;
1404
 
}
1405
 
 
1406
 
void MicroTimestamp::to_timeval(struct timeval &to) const
1407
 
{
1408
 
  to.tv_sec= _epoch_seconds;
1409
 
  to.tv_usec= _useconds;
 
1381
    *to= _epoch_seconds;
 
1382
  *to= 0;
 
1383
}
 
1384
 
 
1385
void Timestamp::to_time_t(time_t *to) const
 
1386
{
 
1387
  *to= _epoch_seconds;
 
1388
}
 
1389
 
 
1390
void MicroTimestamp::to_timeval(struct timeval *to) const
 
1391
{
 
1392
  to->tv_sec= _epoch_seconds;
 
1393
  to->tv_usec= _useconds;
1410
1394
}
1411
1395
 
1412
1396
void NanoTimestamp::to_timespec(struct timespec *to) const
1418
1402
bool Date::is_valid() const
1419
1403
{
1420
1404
  return (_years >= DRIZZLE_MIN_YEARS_SQL && _years <= DRIZZLE_MAX_YEARS_SQL)
1421
 
      && (_months >= 1 && _months <= DRIZZLE_MAX_MONTHS)
 
1405
      && (_months >= 1 && _months <= 12)
1422
1406
      && (_days >= 1 && _days <= days_in_gregorian_year_month(_years, _months));
1423
1407
}
1424
1408
 
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... */
1433
 
}
1434
 
 
1435
 
bool Time::is_fuzzy_valid() const
1436
 
{
1437
 
  if (is_valid())
1438
 
    return true;
1439
 
 
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... */
 
1414
      && (_hours <= 23)
 
1415
      && (_minutes <= 59)
 
1416
      && (_seconds <= 59); /* No Leap second... TIME is for elapsed time... */
1446
1417
}
1447
1418
 
1448
1419
bool DateTime::is_valid() const
1449
1420
{
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... */
 
1424
      && (_hours <= 23)
 
1425
      && (_minutes <= 59)
 
1426
      && (_seconds <= 61); /* Leap second... */
1456
1427
}
1457
1428
 
1458
1429
bool Timestamp::is_valid() const
1459
1430
{
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);
1463
1432
}
1464
1433
 
1465
1434
bool MicroTimestamp::is_valid() const
1466
1435
{
1467
 
  return Timestamp::is_valid()
 
1436
  return in_unix_epoch_range(_years, _months, _days, _hours, _minutes, _seconds)
1468
1437
      && (_useconds <= UINT32_C(999999));
1469
1438
}
1470
1439
 
1471
1440
bool NanoTimestamp::is_valid() const
1472
1441
{
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));
1476
1445
}
1477
1446
 
1478
 
} /* namespace drizzled */
 
1447
} /* end namespace drizzled */