~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/temporal.cc

New merge for TableShare

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
 * their single parameter.
35
35
 */
36
36
 
37
 
#include "config.h"
 
37
#include "drizzled/global.h"
38
38
 
39
 
#include "drizzled/charset_info.h"
40
 
#include "drizzled/decimal.h"
 
39
#include "mystrings/m_ctype.h"
 
40
#include "drizzled/my_decimal.h"
41
41
#include "drizzled/calendar.h"
42
42
#include "drizzled/temporal.h"
 
43
#ifdef NOTYETIMPLEMENTED
 
44
#include "drizzled/temporal_interval.h"
 
45
#endif
43
46
#include "drizzled/temporal_format.h"
44
 
#include "drizzled/time_functions.h"
45
47
#include "time.h"
46
48
 
47
 
#include <time.h>
48
 
 
49
 
#include <cstdio>
50
49
#include <ostream>
51
50
#include <iomanip>
52
51
#include <vector>
53
52
#include <string.h>
54
53
 
 
54
extern std::vector<drizzled::TemporalFormat *> known_datetime_formats;
 
55
extern std::vector<drizzled::TemporalFormat *> known_date_formats;
 
56
extern std::vector<drizzled::TemporalFormat *> known_time_formats;
 
57
 
55
58
namespace drizzled 
56
59
{
57
60
 
58
 
extern std::vector<TemporalFormat *> known_datetime_formats;
59
 
extern std::vector<TemporalFormat *> known_date_formats;
60
 
extern std::vector<TemporalFormat *> known_time_formats;
61
 
 
62
61
Temporal::Temporal()
63
62
:
64
63
  _calendar(GREGORIAN)
81
80
      + _seconds);
82
81
}
83
82
 
84
 
#if defined(TARGET_OS_SOLARIS)
85
 
/* @TODO: Replace this with Boost.DateTime */
86
 
static time_t timegm(struct tm *my_time)
87
 
{
88
 
        time_t local_secs, gm_secs;
89
 
        struct tm gm__rec, *gm_time;
90
 
 
91
 
        // Interpret 't' as the local time and convert it to seconds since the Epoch
92
 
        local_secs = mktime(my_time);
93
 
        if (local_secs == -1)
94
 
  {
95
 
                my_time->tm_hour--;
96
 
                local_secs = mktime (my_time);
97
 
                if (local_secs == -1)
98
 
                        return -1; 
99
 
                local_secs += 3600;
100
 
        }
101
 
        
102
 
        // Get the gmtime based on the local seconds since the Epoch
103
 
        gm_time = gmtime_r(&local_secs, &gm__rec);
104
 
        gm_time->tm_isdst = 0;
105
 
        
106
 
        // Interpret gmtime as the local time and convert it to seconds since the Epoch
107
 
        gm_secs = mktime (gm_time);
108
 
        if (gm_secs == -1)
109
 
  {
110
 
                gm_time->tm_hour--;
111
 
                gm_secs = mktime (gm_time);
112
 
                if (gm_secs == -1)
113
 
                        return -1; 
114
 
                gm_secs += 3600;
115
 
        }
116
 
        
117
 
        // Return the local time adjusted by the difference from GM time.
118
 
        return (local_secs - (gm_secs - local_secs));
119
 
}
120
 
#endif
121
 
 
122
83
void Temporal::set_epoch_seconds()
123
84
{
124
85
  /* 
242
203
 * This operator is called in the following situation:
243
204
 *
244
205
 * @code
245
 
 * Time lhs;
 
206
 * drizzled::Time lhs;
246
207
 * lhs.from_string("20:00:00");
247
 
 * Time rhs;
 
208
 * drizzled::Time rhs;
248
209
 * rhs.from_string("19:00:00");
249
210
 *
250
 
 * Time result= lhs - rhs;
 
211
 * drizzled::Time result= lhs - rhs;
251
212
 * @endcode
252
213
 *
253
214
 * @note
831
792
 
832
793
  return *this;
833
794
}
834
 
 
 
795
#ifdef NOTYETIMPLEMENTED
 
796
Date& Date::operator+=(const TemporalIntervalYear &rhs)
 
797
{
 
798
  /* Simple one...add the years and adjust for any leaps */
 
799
  int64_t new_years= _years;
 
800
  new_years+= rhs._years;
 
801
  if (new_years > DRIZZLE_MAX_YEARS_SQL)
 
802
  {
 
803
    /* 
 
804
     * Set everything to zero. We got an overflow.
 
805
     * @TODO Exceptions would be great here...
 
806
     */
 
807
    _reset();
 
808
    _overflow= true;
 
809
    return *this;
 
810
  }
 
811
  _years= (uint32_t) new_years;
 
812
  if (_months == 2 && _days == 29 && days_in_gregorian_year_month(_years, _months) != 366)
 
813
    _days= 28;
 
814
  return *this;
 
815
 
816
 
 
817
Date& Date::operator-=(const TemporalIntervalYear &rhs)
 
818
{
 
819
  /* Simple one...subtract the years and adjust for any leaps */
 
820
  int64_t new_years= _years;
 
821
  new_years-= rhs._years;
 
822
  if (new_years < 0)
 
823
  {
 
824
    /* 
 
825
     * Set everything to zero. We got an overflow.
 
826
     * @TODO Exceptions would be great here...
 
827
     */
 
828
    _reset();
 
829
    _overflow= true;
 
830
    return *this;
 
831
  }
 
832
  _years= (uint32_t) new_years;
 
833
  if (_months == 2 && _days == 29 && days_in_gregorian_year_month(_years, _months) != 366)
 
834
    _days= 28;
 
835
  return *this;
 
836
 
837
 
 
838
Date& Date::operator+=(const TemporalIntervalDayOrWeek &rhs)
 
839
{
 
840
  /* Simple one...add the days */
 
841
  int64_t julian_day= julian_day_number_from_gregorian_date(_years, _months, _days) + rhs._days;
 
842
  gregorian_date_from_julian_day_number(julian_day, &_years, &_months, &_days);
 
843
  return *this;
 
844
 
845
 
 
846
Date& Date::operator-=(const TemporalIntervalDayOrWeek &rhs)
 
847
{
 
848
  /* Simple one...subtract the days */
 
849
  int64_t julian_day= julian_day_number_from_gregorian_date(_years, _months, _days) - rhs._days;
 
850
  gregorian_date_from_julian_day_number(julian_day, &_years, &_months, &_days);
 
851
  return *this;
 
852
 
853
 
 
854
Date& Date::operator+=(const TemporalIntervalYearMonth &rhs)
 
855
{
 
856
  /* Simple one...add the months in the period adjust */
 
857
  int64_t period= (_years * 12) + (rhs._years * 12) + (_months - 1) + rhs._months;
 
858
  int64_t new_years= (period / 12);
 
859
  if (new_years > DRIZZLE_MAX_YEARS_SQL)
 
860
  {
 
861
    /* 
 
862
     * Set everything to zero. We got an overflow.
 
863
     * @TODO Exceptions would be great here...
 
864
     */
 
865
    _reset();
 
866
    _overflow= true;
 
867
    return *this;
 
868
  }
 
869
  _years= (uint32_t) new_years;
 
870
  _months= (uint32_t) (period % 12) + 1;
 
871
  
 
872
  /* Adjust day if the new month doesn't have enough days */
 
873
  uint32_t days_in_new_month= days_in_gregorian_year_month(_years, _months);
 
874
  if (_days > days_in_new_month)
 
875
    _days= days_in_new_month;
 
876
  return *this;
 
877
 
878
 
 
879
Date& Date::operator-=(const TemporalIntervalYearMonth &rhs)
 
880
{
 
881
  /* Simple one...subtract the months in the period and adjust */
 
882
  int64_t period= (_years * 12) - (rhs._years * 12) + (_months - 1) - rhs._months;
 
883
  int64_t new_years= (period / 12);
 
884
  if (new_years < 0)
 
885
  {
 
886
    /* 
 
887
     * Set everything to zero. We got an overflow.
 
888
     * @TODO Exceptions would be great here...
 
889
     */
 
890
    _reset();
 
891
    _overflow= true;
 
892
    return *this;
 
893
  }
 
894
  _years= (uint32_t) (period / 12);
 
895
  _months= (uint32_t) (period % 12) + 1;
 
896
  
 
897
  /* Adjust day if the new month doesn't have enough days */
 
898
  uint32_t days_in_new_month= days_in_gregorian_year_month(_years, _months);
 
899
  if (_days > days_in_new_month)
 
900
    _days= days_in_new_month;
 
901
  return *this;
 
902
 
903
 
 
904
Date& Date::operator+=(const TemporalIntervalDayOrLess &rhs)
 
905
{
 
906
  /* 
 
907
   * Convert the temporal and the interval into a number of 
 
908
   * microseconds, then add them together and convert the
 
909
   * resulting microseconds back into a broken-down temporal
 
910
   * component.
 
911
   */
 
912
  int64_t new_seconds;
 
913
  int64_t new_microseconds;
 
914
  int64_t extra_sec;
 
915
  int64_t new_days;
 
916
  new_microseconds= _useconds + rhs._useconds;
 
917
  extra_sec= new_microseconds / INT64_C(1000000);
 
918
  new_microseconds= new_microseconds % INT64_C(1000000);
 
919
 
 
920
  new_seconds= ((_days - 1) * 3600 * 24) + (_hours * 3600) + (_minutes * 60) + _seconds;
 
921
  new_seconds+= (rhs._days * 3600 * 24) + (rhs._hours * 3600) + (rhs._minutes * 60) + rhs._seconds;
 
922
  new_seconds+= extra_sec;
 
923
 
 
924
  if (new_microseconds < 0)
 
925
  {
 
926
    new_microseconds+= INT64_C(1000000);
 
927
    new_seconds--;
 
928
  }
 
929
  
 
930
  new_days= new_seconds / (3600 * 24L);
 
931
  new_seconds-= new_days * 3600 * 24L;
 
932
  if (new_seconds < 0)
 
933
  {
 
934
    new_days--;
 
935
    new_seconds+= 3600 * 24L;
 
936
  }
 
937
  _useconds= (uint32_t) new_microseconds;
 
938
  _seconds= (uint32_t) (new_seconds % 60);
 
939
  _minutes= (uint32_t) ((new_seconds / 60) % 60);
 
940
  _hours= (uint32_t) (new_seconds / 3600);
 
941
  int64_t julian_day= julian_day_number_from_gregorian_date(_years, _months, 1) + new_days;
 
942
  gregorian_date_from_julian_day_number(julian_day, &_years, &_months, &_days);
 
943
  return *this;
 
944
}
 
945
 
 
946
Date& Date::operator-=(const TemporalIntervalDayOrLess &rhs)
 
947
{
 
948
  /* 
 
949
   * Convert the temporal and the interval into a number of 
 
950
   * microseconds, then subtract them from each other and convert 
 
951
   * the resulting microseconds back into a broken-down temporal
 
952
   * component.
 
953
   */
 
954
  int64_t new_seconds;
 
955
  int64_t new_microseconds;
 
956
  int64_t extra_sec;
 
957
  int64_t new_days;
 
958
  new_microseconds= _useconds - rhs._useconds;
 
959
  extra_sec= new_microseconds / INT64_C(1000000);
 
960
  new_microseconds= new_microseconds % INT64_C(1000000);
 
961
 
 
962
  new_seconds= ((_days - 1) * 3600 * 24) + (_hours * 3600) + (_minutes * 60) + _seconds;
 
963
  new_seconds-= (rhs._days * 3600 * 24) + (rhs._hours * 3600) + (rhs._minutes * 60) + rhs._seconds;
 
964
  new_seconds+= extra_sec;
 
965
 
 
966
  if (new_microseconds < 0)
 
967
  {
 
968
    new_microseconds+= INT64_C(1000000);
 
969
    new_seconds--;
 
970
  }
 
971
  
 
972
  new_days= new_seconds / (3600 * 24L);
 
973
  new_seconds-= new_days * 3600 * 24L;
 
974
  if (new_seconds < 0)
 
975
  {
 
976
    new_days--;
 
977
    new_seconds+= 3600 * 24L;
 
978
  }
 
979
  _useconds= (uint32_t) new_microseconds;
 
980
  _seconds= (uint32_t) (new_seconds % 60);
 
981
  _minutes= (uint32_t) ((new_seconds / 60) % 60);
 
982
  _hours= (uint32_t) (new_seconds / 3600);
 
983
  int64_t julian_day= julian_day_number_from_gregorian_date(_years, _months, 1) + new_days;
 
984
  gregorian_date_from_julian_day_number(julian_day, &_years, &_months, &_days);
 
985
  return *this;
 
986
}
 
987
#endif /* NOTYETIMPLEMENTED */
835
988
/*
836
989
 * Comparison operators between a Date and a Timestamp
837
990
 */
863
1016
}
864
1017
bool Date::operator>(const Timestamp& rhs)
865
1018
{
866
 
  return ! (*this <= rhs);
 
1019
  return ! (*this < rhs);
867
1020
}
868
1021
bool Date::operator>=(const Timestamp& rhs)
869
1022
{
870
 
  return ! (*this < rhs);
 
1023
  return ! (*this <= rhs);
871
1024
}
872
1025
/*
873
1026
 * Comparison operators between a Timestamp and a Date
900
1053
}
901
1054
bool Timestamp::operator>(const Date& rhs)
902
1055
{
903
 
  return ! (*this <= rhs);
 
1056
  return ! (*this < rhs);
904
1057
}
905
1058
bool Timestamp::operator>=(const Date& rhs)
906
1059
{
907
 
  return ! (*this < rhs);
 
1060
  return ! (*this <= rhs);
908
1061
}
909
1062
/*
910
1063
 * Comparison operators between a Timestamp and a DateTime
953
1106
}
954
1107
bool Timestamp::operator>(const DateTime& rhs)
955
1108
{
956
 
  return ! (*this <= rhs);
 
1109
  return ! (*this < rhs);
957
1110
}
958
1111
bool Timestamp::operator>=(const DateTime& rhs)
959
1112
{
960
 
  return ! (*this < rhs);
 
1113
  return ! (*this <= rhs);
961
1114
}
962
1115
/*
963
1116
 * Comparison operators between two Timestamps
980
1133
}
981
1134
bool Timestamp::operator>(const Timestamp& rhs)
982
1135
{
983
 
  return ! (*this <= rhs);
 
1136
  return ! (*this < rhs);
984
1137
}
985
1138
bool Timestamp::operator>=(const Timestamp& rhs)
986
1139
{
987
 
  return ! (*this < rhs);
 
1140
  return ! (*this <= rhs);
988
1141
}
989
1142
 
990
1143
/**
1185
1338
bool Time::from_int32_t(const int32_t from)
1186
1339
{
1187
1340
  uint32_t copy_from= (uint32_t) from;
1188
 
  _hours= copy_from / INT32_C(10000);
1189
 
  _minutes= (copy_from % INT32_C(10000)) / INT32_C(100);
1190
 
  _seconds= copy_from % INT32_C(100); /* Masks off all but last 2 digits */
 
1341
  _hours= copy_from % INT32_C(10000);
 
1342
  _minutes= copy_from % INT32_C(100);
 
1343
  _seconds= copy_from & 3; /* Masks off all but last 2 digits */
1191
1344
  return is_valid();
1192
1345
}
1193
1346
 
1226
1379
    else if (copy_from <  DRIZZLE_YY_PART_YEAR * 10000000000LL + 101000000LL)
1227
1380
      return false;
1228
1381
    else if (copy_from <= 991231235959LL)
1229
 
      copy_from= copy_from + 19000000000000LL;    /* YYMMDDHHMMSS, 1970-1999 */
 
1382
      copy_from= copy_from + 19000000000000LL;          /* YYMMDDHHMMSS, 1970-1999 */
1230
1383
  }
1231
1384
 
1232
1385
  part1= (int64_t) (copy_from / 1000000LL);
1405
1558
bool Timestamp::is_valid() const
1406
1559
{
1407
1560
  return DateTime::is_valid() 
1408
 
      && in_unix_epoch_range(_years, _months, _days, _hours, _minutes, _seconds)
1409
 
      && (_seconds <= 59);
 
1561
      && in_unix_epoch_range(_years, _months, _days, _hours, _minutes, _seconds);
1410
1562
}
1411
1563
 
1412
1564
bool MicroTimestamp::is_valid() const
1422
1574
      && (_nseconds <= UINT32_C(999999999));
1423
1575
}
1424
1576
 
1425
 
} /* namespace drizzled */
 
1577
} /* end namespace drizzled */