Drizzled Public API Documentation

temporal.cc
Go to the documentation of this file.
00001 /* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2008 Sun Microsystems, Inc.
00005  *
00006  *  Authors:
00007  *
00008  *  Jay Pipes <jay.pipes@sun.com>
00009  *
00010  *  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU General Public License for more details.
00019  *
00020  *  You should have received a copy of the GNU General Public License
00021  *  along with this program; if not, write to the Free Software
00022  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00023  */
00024 
00037 #include <config.h>
00038 
00039 #include <boost/foreach.hpp>
00040 #include <drizzled/charset.h>
00041 #include <drizzled/type/decimal.h>
00042 #include <drizzled/calendar.h>
00043 #include <drizzled/temporal.h>
00044 #include <drizzled/temporal_format.h>
00045 #include <drizzled/time_functions.h>
00046 #include "time.h"
00047 
00048 #include <drizzled/util/gmtime.h>
00049 
00050 #include <time.h>
00051 
00052 #include <cstdio>
00053 #include <ostream>
00054 #include <iomanip>
00055 #include <vector>
00056 #include <string.h>
00057 
00058 namespace drizzled {
00059 
00060 extern std::vector<TemporalFormat *> known_datetime_formats;
00061 extern std::vector<TemporalFormat *> known_date_formats;
00062 extern std::vector<TemporalFormat *> known_time_formats;
00063 
00064 Temporal::Temporal() :
00065   _calendar(GREGORIAN),
00066   _years(0),
00067   _months(0),
00068   _days(0),
00069   _hours(0),
00070   _minutes(0),
00071   _seconds(0),
00072   _epoch_seconds(0),
00073   _useconds(0),
00074   _nseconds(0),
00075   _overflow(false)
00076 {}
00077 
00078 uint64_t Temporal::_cumulative_seconds_in_time() const
00079 {
00080   return (uint64_t) ((_hours * INT64_C(3600)) 
00081       + (_minutes * INT64_C(60)) 
00082       + _seconds);
00083 }
00084 
00085 #if defined(TARGET_OS_SOLARIS)
00086 /* @TODO: Replace this with Boost.DateTime */
00087 static time_t timegm(struct tm *my_time)
00088 {
00089   time_t local_secs, gm_secs;
00090   struct tm gm__rec, *gm_time;
00091 
00092   // Interpret 't' as the local time and convert it to seconds since the Epoch
00093   local_secs = mktime(my_time);
00094   if (local_secs == -1)
00095   {
00096     my_time->tm_hour--;
00097     local_secs = mktime (my_time);
00098     if (local_secs == -1)
00099       return -1; 
00100     local_secs += 3600;
00101   }
00102   
00103   // Get the gmtime based on the local seconds since the Epoch
00104   gm_time = util::gmtime(local_secs, &gm__rec);
00105   gm_time->tm_isdst = 0;
00106   
00107   // Interpret gmtime as the local time and convert it to seconds since the Epoch
00108   gm_secs = mktime (gm_time);
00109   if (gm_secs == -1)
00110   {
00111     gm_time->tm_hour--;
00112     gm_secs = mktime (gm_time);
00113     if (gm_secs == -1)
00114       return -1; 
00115     gm_secs += 3600;
00116   }
00117   
00118   // Return the local time adjusted by the difference from GM time.
00119   return (local_secs - (gm_secs - local_secs));
00120 }
00121 #endif
00122 
00123 void Temporal::set_epoch_seconds()
00124 {
00125   /* 
00126    * If the temporal is in the range of a timestamp, set 
00127    * the epoch_seconds member variable
00128    */
00129   if (in_unix_epoch_range(_years, _months, _days, _hours, _minutes, _seconds))
00130   {
00131     time_t result_time;
00132     struct tm broken_time;
00133 
00134     broken_time.tm_sec= _seconds;
00135     broken_time.tm_min= _minutes;
00136     broken_time.tm_hour= _hours;
00137     broken_time.tm_mday= _days; /* Drizzle format uses ordinal, standard tm does too! */
00138     broken_time.tm_mon= _months - 1; /* Drizzle format uses ordinal, standard tm does NOT! */
00139     broken_time.tm_year= _years - 1900; /* tm_year expects range of 70 - 38 */
00140 
00141     result_time= timegm(&broken_time);
00142 
00143     _epoch_seconds= result_time;
00144   }
00145 }
00146 
00147 bool Date::from_string(const char *from, size_t from_len)
00148 {
00149   _useconds= 0; // We may not match on it, so we need to make sure we zero it out.
00150   BOOST_FOREACH(TemporalFormat* it, known_date_formats)
00151   {
00152     if (not it->matches(from, from_len, this))
00153       continue;
00154     set_epoch_seconds();
00155     return is_valid();
00156   }
00157   return false;
00158 }
00159 
00160 bool DateTime::from_string(const char *from, size_t from_len)
00161 {
00162   BOOST_FOREACH(TemporalFormat* it, known_datetime_formats)
00163   {
00164     if (not it->matches(from, from_len, this))
00165       continue;
00166     set_epoch_seconds();
00167     return is_valid();
00168   }
00169   return false;
00170 
00171 }
00172 
00173 /*
00174  * Comparison operators for Time against another Time
00175  * are easy.  We simply compare the cumulative time
00176  * value of each.
00177  */
00178 bool Time::operator==(const Time& rhs)
00179 {
00180   return (
00181           _hours == rhs._hours
00182        && _minutes == rhs._minutes
00183        && _seconds == rhs._seconds
00184        && _useconds == rhs._useconds
00185        && _nseconds == rhs._nseconds
00186       );
00187 }
00188 bool Time::operator!=(const Time& rhs)
00189 {
00190   return ! (*this == rhs);
00191 }
00192 bool Time::operator<(const Time& rhs)
00193 {
00194   return (_cumulative_seconds_in_time() < rhs._cumulative_seconds_in_time());
00195 }
00196 bool Time::operator<=(const Time& rhs)
00197 {
00198   return (_cumulative_seconds_in_time() <= rhs._cumulative_seconds_in_time());
00199 }
00200 bool Time::operator>(const Time& rhs)
00201 {
00202   return (_cumulative_seconds_in_time() > rhs._cumulative_seconds_in_time());
00203 }
00204 bool Time::operator>=(const Time& rhs)
00205 {
00206   return (_cumulative_seconds_in_time() >= rhs._cumulative_seconds_in_time());
00207 }
00208 
00231 const Time Time::operator-(const Time& rhs)
00232 {
00233   Time result;
00234 
00235   int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
00236   result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
00237   second_diff%= DRIZZLE_SECONDS_IN_HOUR;
00238   result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
00239   second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
00240   result._seconds= (uint32_t) second_diff;
00241   
00242   return result;
00243 }
00244 const Time Time::operator+(const Time& rhs)
00245 {
00246   Time result;
00247   int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
00248   result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
00249   second_diff%= DRIZZLE_SECONDS_IN_HOUR;
00250   result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
00251   second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
00252   result._seconds= (uint32_t) second_diff;
00257   return result;
00258 }
00259 
00260 /*
00261  * Variation of + and - operator which returns a reference to the left-hand
00262  * side Time object and adds the right-hand side to itself.
00263  */
00264 Time& Time::operator+=(const Time& rhs)
00265 {
00266   int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
00267   _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
00268   second_diff%= DRIZZLE_SECONDS_IN_HOUR;
00269   _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
00270   second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
00271   _seconds= (uint32_t) second_diff;
00276   return *this;
00277 }
00278 Time& Time::operator-=(const Time& rhs)
00279 {
00280   int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
00281   _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
00282   second_diff%= DRIZZLE_SECONDS_IN_HOUR;
00283   _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
00284   second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
00285   _seconds= (uint32_t) second_diff;
00290   return *this;
00291 }
00292 
00293 /*
00294  * Comparison operators for Date against another Date
00295  * are easy.  We simply compare the cumulative
00296  * value of each.
00297  */
00298 bool Date::operator==(const Date& rhs)
00299 {
00300   return (
00301           _years == rhs._years
00302        && _months == rhs._months
00303        && _days == rhs._days
00304       );
00305 }
00306 bool Date::operator!=(const Date& rhs)
00307 {
00308   return ! (*this == rhs);
00309 }
00310 bool Date::operator<(const Date& rhs)
00311 {
00312   int64_t days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
00313   int64_t days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
00314   return (days_left < days_right);
00315 }
00316 bool Date::operator<=(const Date& rhs)
00317 {
00318   int64_t days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
00319   int64_t days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
00320   return (days_left <= days_right);
00321 }
00322 bool Date::operator>(const Date& rhs)
00323 {
00324   return ! (*this <= rhs);
00325 }
00326 bool Date::operator>=(const Date& rhs)
00327 {
00328   return ! (*this < rhs);
00329 }
00330 
00331 /*
00332  * Comparison operators for DateTime against another DateTime
00333  * are easy.  We simply compare the cumulative time
00334  * value of each.
00335  */
00336 bool Date::operator==(const DateTime& rhs)
00337 {
00338   return (
00339           _years == rhs._years
00340        && _months == rhs._months
00341        && _days == rhs._days
00342        && _hours == rhs._hours
00343        && _minutes == rhs._minutes
00344        && _seconds == rhs._seconds
00345        && _useconds == rhs._useconds
00346        && _nseconds == rhs._nseconds
00347       );
00348 }
00349 bool Date::operator!=(const DateTime& rhs)
00350 {
00351   return ! (*this == rhs);
00352 }
00353 bool Date::operator<(const DateTime& rhs)
00354 {
00355   int64_t days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
00356   int64_t days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
00357   if (days_left < days_right)
00358     return true;
00359   else if (days_left > days_right)
00360     return false;
00361   /* Here if both dates are the same, so compare times */
00362   return (_cumulative_seconds_in_time() < rhs._cumulative_seconds_in_time());
00363 }
00364 bool Date::operator<=(const DateTime& rhs)
00365 {
00366   int64_t days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
00367   int64_t days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
00368   if (days_left < days_right)
00369     return true;
00370   else if (days_left > days_right)
00371     return false;
00372   /* Here if both dates are the same, so compare times */
00373   return (_cumulative_seconds_in_time() <= rhs._cumulative_seconds_in_time());
00374 }
00375 bool Date::operator>(const DateTime& rhs)
00376 {
00377   return ! (*this <= rhs);
00378 }
00379 bool Date::operator>=(const DateTime& rhs)
00380 {
00381   return ! (*this < rhs);
00382 }
00383 
00388 const Date Date::operator-(const Time& rhs)
00389 {
00390   DateTime result;
00391 
00392   /* 
00393    * First, we set the resulting DATE pieces equal to our 
00394    * left-hand side DateTime's DATE components. Then, deal with 
00395    * the time components.
00396    */
00397   result._years= _years;
00398   result._months= _months;
00399   result._days= _days;
00400 
00401   int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
00402 
00403   /* 
00404    * The resulting diff might be negative.  If it is, that means that 
00405    * we have subtracting a larger time piece from the datetime, like so:
00406    *
00407    * x = DateTime("2007-06-09 09:30:00") - Time("16:30:00");
00408    *
00409    * In these cases, we need to subtract a day from the resulting
00410    * DateTime.
00411    */
00412   if (second_diff < 0)
00413     result._days--;
00414 
00415   result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
00416   second_diff%= DRIZZLE_SECONDS_IN_HOUR;
00417   result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
00418   second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
00419   result._seconds= (uint32_t) second_diff;
00420 
00421   /* Handle the microsecond precision */
00422   int64_t microsecond_diff= _useconds - rhs._useconds;
00423   if (microsecond_diff < 0)
00424   {
00425     microsecond_diff= (-1 * microsecond_diff);
00426     result._seconds--;
00427   }
00428   result._useconds= (uint32_t) microsecond_diff;
00429 
00430   return result;
00431 }
00432 const Date Date::operator+(const Time& rhs)
00433 {
00434   DateTime result;
00435 
00436   /* 
00437    * First, we set the resulting DATE pieces equal to our 
00438    * left-hand side DateTime's DATE components. Then, deal with 
00439    * the time components.
00440    */
00441   result._years= _years;
00442   result._months= _months;
00443   result._days= _days;
00444 
00445   int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
00446 
00447   /* 
00448    * The resulting seconds might be more than a day.  If do, 
00449    * adjust our resulting days up 1.
00450    */
00451   if (second_diff >= DRIZZLE_SECONDS_IN_DAY)
00452   {
00453     result._days++;
00454     second_diff%= DRIZZLE_SECONDS_IN_DAY;
00455   }
00456 
00457   result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
00458   second_diff%= DRIZZLE_SECONDS_IN_HOUR;
00459   result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
00460   second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
00461   result._seconds= (uint32_t) second_diff;
00462 
00463   /* Handle the microsecond precision */
00464   int64_t microsecond_diff= _useconds - rhs._useconds;
00465   if (microsecond_diff < 0)
00466   {
00467     microsecond_diff= (-1 * microsecond_diff);
00468     result._seconds--;
00469   }
00470   result._useconds= (uint32_t) microsecond_diff;
00471 
00472   return result;
00473 }
00474 
00475 /*
00476  * Variation of + and - operator which returns a reference to the left-hand
00477  * side DateTime object and adds the right-hand side Time to itself.
00478  */
00479 Date& Date::operator+=(const Time& rhs)
00480 {
00481   int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
00482   /* 
00483    * The resulting seconds might be more than a day.  If do, 
00484    * adjust our resulting days up 1.
00485    */
00486   if (second_diff >= DRIZZLE_SECONDS_IN_DAY)
00487   {
00488     _days++;
00489     second_diff%= DRIZZLE_SECONDS_IN_DAY;
00490   }
00491 
00492   _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
00493   second_diff%= DRIZZLE_SECONDS_IN_HOUR;
00494   _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
00495   second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
00496   _seconds= (uint32_t) second_diff;
00497 
00498   /* Handle the microsecond precision */
00499   int64_t microsecond_diff= _useconds - rhs._useconds;
00500   if (microsecond_diff < 0)
00501   {
00502     microsecond_diff= (-1 * microsecond_diff);
00503     _seconds--;
00504   }
00505   _useconds= (uint32_t) microsecond_diff;
00510   return *this;
00511 }
00512 Date& Date::operator-=(const Time& rhs)
00513 {
00514   int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
00515 
00516   /* 
00517    * The resulting diff might be negative.  If it is, that means that 
00518    * we have subtracting a larger time piece from the datetime, like so:
00519    *
00520    * x = DateTime("2007-06-09 09:30:00");
00521    * x-= Time("16:30:00");
00522    *
00523    * In these cases, we need to subtract a day from the resulting
00524    * DateTime.
00525    */
00526   if (second_diff < 0)
00527     _days--;
00528 
00529   _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
00530   second_diff%= DRIZZLE_SECONDS_IN_HOUR;
00531   _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
00532   second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
00533   _seconds= (uint32_t) second_diff;
00534 
00535   /* Handle the microsecond precision */
00536   int64_t microsecond_diff= _useconds - rhs._useconds;
00537   if (microsecond_diff < 0)
00538   {
00539     microsecond_diff= (-1 * microsecond_diff);
00540     _seconds--;
00541   }
00542   _useconds= (uint32_t) microsecond_diff;
00547   return *this;
00548 }
00549 
00554 const Date Date::operator-(const Date &rhs)
00555 {
00556   /* Figure out the difference in days between the two dates */
00557   int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
00558   int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
00559   int64_t day_diff= day_left - day_right;
00560 
00561   Date result;
00562   /* Now re-compose the Date's structure from the resulting Julian Day Number */
00563   gregorian_date_from_julian_day_number(day_diff, &result._years, &result._months, &result._days);
00564   return result;
00565 }
00566 const Date Date::operator+(const Date &rhs)
00567 {
00568   /* 
00569    * Figure out the new Julian Day Number by adding the JDNs of both
00570    * dates together.
00571    */
00572   int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
00573   int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
00574   int64_t day_diff= day_left + day_right;
00575 
00578   Date result;
00579   /* Now re-compose the Date's structure from the resulting Julian Day Number */
00580   gregorian_date_from_julian_day_number(day_diff, &result._years, &result._months, &result._days);
00581   return result;
00582 }
00583 /* Similar to the above, but we add/subtract the right side to this object itself */
00584 Date& Date::operator-=(const Date &rhs)
00585 {
00586   int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
00587   int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
00588   int64_t day_diff= day_left - day_right;
00589 
00590   /* Now re-compose the Date's structure from the resulting Julian Day Number */
00591   gregorian_date_from_julian_day_number(day_diff, &_years, &_months, &_days);
00592   return *this;
00593 }
00594 Date& Date::operator+=(const Date &rhs)
00595 {
00596   /* 
00597    * Figure out the new Julian Day Number by adding the JDNs of both
00598    * dates together.
00599    */
00600   int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
00601   int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
00602   int64_t day_diff= day_left + day_right;
00603 
00606   /* Now re-compose the Date's structure from the resulting Julian Day Number */
00607   gregorian_date_from_julian_day_number(day_diff, &_years, &_months, &_days);
00608   return *this;
00609 }
00610 
00611 Date& Date::operator=(const DateTime &rhs)
00612 {
00613   /* Only copy the Date components of the assigned DateTime... */
00614   _years= rhs._years;
00615   _months= rhs._months;
00616   _days= rhs._days;
00617   /* Zero-out everything else.. */
00618   _hours= _minutes= _seconds= _useconds= _nseconds= 0;
00619   return *this;
00620 }
00621 
00626 const Date Date::operator-(const DateTime &rhs)
00627 {
00628   /* Figure out the difference in days between the two dates. */
00629   int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
00630   int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
00631   int64_t day_diff= day_left - day_right;
00632 
00633   DateTime result;
00634   /* Now re-compose the Date's structure from the resulting Julian Day Number */
00635   gregorian_date_from_julian_day_number(day_diff, &result._years, &result._months, &result._days);
00636 
00637   /* And now handle the time components */
00638   int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
00639 
00640   /* 
00641    * The resulting diff might be negative.  If it is, that means that 
00642    * we have subtracting a larger time piece from the datetime, like so:
00643    *
00644    * x = DateTime("2007-06-09 09:30:00");
00645    * x-= Time("16:30:00");
00646    *
00647    * In these cases, we need to subtract a day from the resulting
00648    * DateTime.
00649    */
00650   if (second_diff < 0)
00651     _days--;
00652 
00653   result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
00654   second_diff%= DRIZZLE_SECONDS_IN_HOUR;
00655   result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
00656   second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
00657   result._seconds= (uint32_t) second_diff;
00658 
00659   /* Handle the microsecond precision */
00660   int64_t microsecond_diff= _useconds - rhs._useconds;
00661   if (microsecond_diff < 0)
00662   {
00663     microsecond_diff= (-1 * microsecond_diff);
00664     result._seconds--;
00665   }
00666   result._useconds= (uint32_t) microsecond_diff;
00667 
00668   return result;
00669 }
00670 const Date Date::operator+(const DateTime &rhs)
00671 {
00672   /*
00673    * Figure out the new Julian Day Number by adding the JDNs of both
00674    * dates together.
00675    */
00676   int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
00677   int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
00678   int64_t day_diff= day_left + day_right;
00679 
00682   DateTime result;
00683   /* Now re-compose the Date's structure from the resulting Julian Day Number */
00684   gregorian_date_from_julian_day_number(day_diff, &result._years, &result._months, &result._days);
00685 
00686   /* And now handle the time components */
00687   int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
00688 
00689   /* 
00690    * The resulting seconds might be more than a day.  If do, 
00691    * adjust our resulting days up 1.
00692    */
00693   if (second_diff >= DRIZZLE_SECONDS_IN_DAY)
00694   {
00695     result._days++;
00696     second_diff%= DRIZZLE_SECONDS_IN_DAY;
00697   }
00698 
00699   result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
00700   second_diff%= DRIZZLE_SECONDS_IN_HOUR;
00701   result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
00702   second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
00703   result._seconds= (uint32_t) second_diff;
00704 
00705   /* Handle the microsecond precision */
00706   int64_t microsecond_diff= _useconds - rhs._useconds;
00707   if (microsecond_diff < 0)
00708   {
00709     microsecond_diff= (-1 * microsecond_diff);
00710     result._seconds--;
00711   }
00712   result._useconds= (uint32_t) microsecond_diff;
00713 
00714   return result;
00715 }
00716 /* Similar to the above, but we add/subtract the right side to this object itself */
00717 Date& Date::operator-=(const DateTime &rhs)
00718 {
00719   /* Figure out the difference in days between the two dates.  */
00720   int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
00721   int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
00722   int64_t day_diff= day_left - day_right;
00723 
00724   /* Now re-compose the Date's structure from the ng Julian Day Number */
00725   gregorian_date_from_julian_day_number(day_diff, &_years, &_months, &_days);
00726 
00727   /* And now handle the time components */
00728   int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
00729 
00730   /* 
00731    * The resulting diff might be negative.  If it is, that means that 
00732    * we have subtracting a larger time piece from the datetime, like so:
00733    *
00734    * x = DateTime("2007-06-09 09:30:00");
00735    * x-= Time("16:30:00");
00736    *
00737    * In these cases, we need to subtract a day from the ng
00738    * DateTime.
00739    */
00740   if (second_diff < 0)
00741     _days--;
00742 
00743   _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
00744   second_diff%= DRIZZLE_SECONDS_IN_HOUR;
00745   _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
00746   second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
00747   _seconds= (uint32_t) second_diff;
00748 
00749   /* Handle the microsecond precision */
00750   int64_t microsecond_diff= _useconds - rhs._useconds;
00751   if (microsecond_diff < 0)
00752   {
00753     microsecond_diff= (-1 * microsecond_diff);
00754     _seconds--;
00755   }
00756   _useconds= (uint32_t) microsecond_diff;
00757 
00758   return *this;
00759 }
00760 Date& Date::operator+=(const DateTime &rhs)
00761 {
00762   /* 
00763    * Figure out the new Julian Day Number by adding the JDNs of both
00764    * dates together.
00765    */
00766   int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
00767   int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
00768   int64_t day_diff= day_left + day_right;
00769 
00772   /* Now re-compose the Date's structure from the ng Julian Day Number */
00773   gregorian_date_from_julian_day_number(day_diff, &_years, &_months, &_days);
00774 
00775   /* And now handle the time components */
00776   int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
00777 
00778   /* 
00779    * The resulting seconds might be more than a day.  If do, 
00780    * adjust our ng days up 1.
00781    */
00782   if (second_diff >= DRIZZLE_SECONDS_IN_DAY)
00783   {
00784     _days++;
00785     second_diff%= DRIZZLE_SECONDS_IN_DAY;
00786   }
00787 
00788   _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
00789   second_diff%= DRIZZLE_SECONDS_IN_HOUR;
00790   _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
00791   second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
00792   _seconds= (uint32_t) second_diff;
00793 
00794   /* Handle the microsecond precision */
00795   int64_t microsecond_diff= _useconds - rhs._useconds;
00796   if (microsecond_diff < 0)
00797   {
00798     microsecond_diff= (-1 * microsecond_diff);
00799     _seconds--;
00800   }
00801   _useconds= (uint32_t) microsecond_diff;
00802 
00803   return *this;
00804 }
00805 
00806 /*
00807  * Comparison operators between a Date and a Timestamp
00808  */
00809 bool Date::operator==(const Timestamp& rhs)
00810 {
00811   return (_years == rhs._years && _months == rhs._months && _days == rhs._days);
00812 }
00813 bool Date::operator!=(const Timestamp& rhs)
00814 {
00815   return ! (*this == rhs);
00816 }
00817 bool Date::operator<(const Timestamp& rhs)
00818 {
00819   if (_years < rhs._years)
00820     return true;
00821   if (_years > rhs._years)
00822     return false;
00823   /* In same year */
00824   if (_months < rhs._months)
00825     return true;
00826   if (_months > rhs._months)
00827     return false;
00828   /* Same month */
00829   return _days < rhs._days;
00830 }
00831 bool Date::operator<=(const Timestamp& rhs)
00832 {
00833   return (*this < rhs || *this == rhs);
00834 }
00835 bool Date::operator>(const Timestamp& rhs)
00836 {
00837   return ! (*this <= rhs);
00838 }
00839 bool Date::operator>=(const Timestamp& rhs)
00840 {
00841   return ! (*this < rhs);
00842 }
00843 /*
00844  * Comparison operators between a Timestamp and a Date
00845  */
00846 bool Timestamp::operator==(const Date& rhs)
00847 {
00848   return (_years == rhs._years && _months == rhs._months && _days == rhs._days);
00849 }
00850 bool Timestamp::operator!=(const Date& rhs)
00851 {
00852   return ! (*this == rhs);
00853 }
00854 bool Timestamp::operator<(const Date& rhs)
00855 {
00856   if (_years < rhs._years)
00857     return true;
00858   if (_years > rhs._years)
00859     return false;
00860   /* In same year */
00861   if (_months < rhs._months)
00862     return true;
00863   if (_months > rhs._months)
00864     return false;
00865   /* Same month */
00866   return _days < rhs._days;
00867 }
00868 bool Timestamp::operator<=(const Date& rhs)
00869 {
00870   return (*this < rhs || *this == rhs);
00871 }
00872 bool Timestamp::operator>(const Date& rhs)
00873 {
00874   return ! (*this <= rhs);
00875 }
00876 bool Timestamp::operator>=(const Date& rhs)
00877 {
00878   return ! (*this < rhs);
00879 }
00880 /*
00881  * Comparison operators between a Timestamp and a DateTime
00882  */
00883 bool Timestamp::operator==(const DateTime& rhs)
00884 {
00885   return (_years == rhs._years && _months == rhs._months && _days == rhs._days
00886           && _hours == rhs._hours && _minutes == rhs._minutes && _seconds == rhs._seconds);
00887 }
00888 bool Timestamp::operator!=(const DateTime& rhs)
00889 {
00890   return ! (*this == rhs);
00891 }
00892 bool Timestamp::operator<(const DateTime& rhs)
00893 {
00894   if (_years < rhs._years)
00895     return true;
00896   if (_years > rhs._years)
00897     return false;
00898   /* In same year */
00899   if (_months < rhs._months)
00900     return true;
00901   if (_months > rhs._months)
00902     return false;
00903   /* Same month */
00904   if (_days < rhs._days)
00905     return true;
00906   if (_days > rhs._days)
00907      return false;
00908   /* Same day */
00909   if (_hours < rhs._hours)
00910     return true;
00911   if (_hours > rhs._hours)
00912     return false;
00913   /* Same hour */
00914   if (_minutes < rhs._minutes)
00915     return true;
00916   if (_minutes > rhs._minutes)
00917     return false;
00918   /* Same minute */
00919   return _seconds < rhs._seconds;
00920 }
00921 bool Timestamp::operator<=(const DateTime& rhs)
00922 {
00923   return (*this < rhs || *this == rhs);
00924 }
00925 bool Timestamp::operator>(const DateTime& rhs)
00926 {
00927   return ! (*this <= rhs);
00928 }
00929 bool Timestamp::operator>=(const DateTime& rhs)
00930 {
00931   return ! (*this < rhs);
00932 }
00933 /*
00934  * Comparison operators between two Timestamps
00935  */
00936 bool Timestamp::operator==(const Timestamp& rhs)
00937 {
00938   return (_epoch_seconds == rhs._epoch_seconds);
00939 }
00940 bool Timestamp::operator!=(const Timestamp& rhs)
00941 {
00942   return ! (*this == rhs);
00943 }
00944 bool Timestamp::operator<(const Timestamp& rhs)
00945 {
00946   return (_epoch_seconds < rhs._epoch_seconds);
00947 }
00948 bool Timestamp::operator<=(const Timestamp& rhs)
00949 {
00950   return (_epoch_seconds <= rhs._epoch_seconds);
00951 }
00952 bool Timestamp::operator>(const Timestamp& rhs)
00953 {
00954   return ! (*this <= rhs);
00955 }
00956 bool Timestamp::operator>=(const Timestamp& rhs)
00957 {
00958   return ! (*this < rhs);
00959 }
00960 
00968 std::ostream& operator<<(std::ostream& os, const Timestamp& subject)
00969 {
00970   return os << subject.years() << '-' 
00971             << std::setw(2) << std::setfill('0') << subject.months() << '-'
00972             << std::setw(2) << std::setfill('0') << subject.days() << ' '
00973             << std::setw(2) << std::setfill('0') << subject.hours() << ':'
00974             << std::setw(2) << std::setfill('0') << subject.minutes() << ':'
00975             << std::setw(2) << std::setfill('0') << subject.seconds();
00976 }
00977 
00978 bool Time::from_string(const char *from, size_t from_len)
00979 {
00980   BOOST_FOREACH(TemporalFormat* it, known_time_formats)
00981   {
00982     if (not it->matches(from, from_len, this))
00983       continue;
00984     return is_fuzzy_valid();
00985   }
00986   return false;
00987 }
00988 
00989 int Time::to_string(char *to, size_t to_len) const
00990 {
00991   return snprintf(to, to_len, "%02" PRIu32 ":%02" PRIu32 ":%02" PRIu32, _hours, _minutes, _seconds);
00992 }
00993 
00994 int Date::to_string(char *to, size_t to_len) const
00995 {
00996   return snprintf(to, to_len, "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32, _years, _months, _days);
00997 }
00998 
00999 int DateTime::to_string(char *to, size_t to_len) const
01000 {
01001   /* If the temporal has a microsecond component, use a slightly different output */
01002   if (_useconds == 0)
01003   {
01004     return snprintf(to, to_len,
01005         "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32 " %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32,
01006         _years, _months, _days, _hours, _minutes, _seconds);
01007   }
01008   else
01009   {
01010     return snprintf(to, to_len,
01011         "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32 " %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 ".%06" PRIu32,
01012         _years, _months, _days, _hours, _minutes, _seconds, _useconds);
01013   }
01014 }
01015 
01016 int MicroTimestamp::to_string(char *to, size_t to_len) const
01017 {
01018   return snprintf(to, to_len,
01019                   "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32 " %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 ".%06" PRIu32,
01020                   _years, _months, _days, _hours, _minutes, _seconds, _useconds);
01021 }
01022 
01023 void Time::to_decimal(type::Decimal *to) const
01024 {
01025   int64_t time_portion= (((_hours * 100L) + _minutes) * 100L) + _seconds;
01026   (void) int2_class_decimal(E_DEC_FATAL_ERROR, time_portion, false, to);
01027   if (_useconds > 0)
01028   {
01029     to->buf[(to->intg-1) / 9 + 1]= _useconds * 1000;
01030     to->frac= 6;
01031   }
01032 }
01033 
01034 void Date::to_decimal(type::Decimal *to) const
01035 {
01036   int64_t date_portion= (((_years * 100L) + _months) * 100L) + _days;
01037   (void) int2_class_decimal(E_DEC_FATAL_ERROR, date_portion, false, to);
01038 }
01039 
01040 void DateTime::to_decimal(type::Decimal *to) const
01041 {
01042   int64_t date_portion= (((_years * 100L) + _months) * 100L) + _days;
01043   int64_t time_portion= (((((date_portion * 100L) + _hours) * 100L) + _minutes) * 100L) + _seconds;
01044   (void) int2_class_decimal(E_DEC_FATAL_ERROR, time_portion, false, to);
01045   if (_useconds > 0)
01046   {
01047     to->buf[(to->intg-1) / 9 + 1]= _useconds * 1000;
01048     to->frac= 6;
01049   }
01050 }
01051 
01052 void Date::to_int64_t(int64_t *to) const
01053 {
01054   *to= (_years * INT32_C(10000)) + (_months * INT32_C(100)) + _days;
01055 }
01056 
01057 void Date::to_int32_t(int32_t *to) const
01058 {
01059   *to= (_years * INT32_C(10000)) + (_months * INT32_C(100)) + _days;
01060 }
01061 
01062 void Time::to_int32_t(int32_t *to) const
01063 {
01064   *to= (_hours * INT32_C(10000)) + (_minutes * INT32_C(100)) + _seconds;
01065 }
01066 
01067 // We fill the structure based on just int
01068 void Time::to_uint64_t(uint64_t &to) const
01069 {
01070   to= (_hours * 60 * 60) + (_minutes * 60) + _seconds;
01071 }
01072 
01073 void DateTime::to_int64_t(int64_t *to) const
01074 {
01075   *to= ((
01076        (_years * INT64_C(10000)) 
01077      + (_months * INT64_C(100)) 
01078      + _days
01079        ) * INT64_C(1000000))
01080      + (
01081        (_hours * INT64_C(10000)) 
01082      + (_minutes * INT64_C(100) )
01083      + _seconds
01084      );
01085 }
01086 
01087 void Date::to_tm(struct tm *to) const
01088 {
01089   to->tm_sec= 0;
01090   to->tm_min= 0;
01091   to->tm_hour= 0;
01092   to->tm_mday= _days; /* Drizzle format uses ordinal, standard tm does too! */
01093   to->tm_mon= _months - 1; /* Drizzle format uses ordinal, standard tm does NOT! */
01094   to->tm_year= _years - 1900;
01095 }
01096 
01097 void DateTime::to_tm(struct tm *to) const
01098 {
01099   to->tm_sec= _seconds;
01100   to->tm_min= _minutes;
01101   to->tm_hour= _hours;
01102   to->tm_mday= _days; /* Drizzle format uses ordinal, standard tm does too! */
01103   to->tm_mon= _months - 1; /* Drizzle format uses ordinal, standard tm does NOT! */
01104   to->tm_year= _years - 1900;
01105 }
01106 
01107 bool Date::from_julian_day_number(const int64_t from)
01108 {
01109   gregorian_date_from_julian_day_number(from, &_years, &_months, &_days);
01110   return is_valid();
01111 }
01112 
01113 void Date::to_julian_day_number(int64_t *to) const
01114 {
01115   *to= julian_day_number_from_gregorian_date(_years, _months, _days);
01116 }
01117 
01121 bool Date::from_int32_t(const int32_t from)
01122 {
01123   return ((DateTime *) this)->from_int64_t((int64_t) from);
01124 }
01125 
01130 bool Time::from_int32_t(const int32_t from)
01131 {
01132   uint32_t copy_from= (uint32_t) from;
01133   _hours= copy_from / INT32_C(10000);
01134   _minutes= (copy_from % INT32_C(10000)) / INT32_C(100);
01135   _seconds= copy_from % INT32_C(100); /* Masks off all but last 2 digits */
01136   return is_valid();
01137 }
01138 
01144 bool DateTime::from_int64_t(const int64_t from, bool convert)
01145 {
01146   int64_t copy_from= from;
01147   int64_t part1;
01148   int64_t part2;
01149 
01150   if (copy_from == 0LL)
01151     return false;
01152 
01153   if (convert && copy_from < 10000101000000LL)
01154   {
01155     if (copy_from < 101)
01156       return false;
01157     else if (copy_from <= (DRIZZLE_YY_PART_YEAR-1)*10000L+1231L)
01158       copy_from= (copy_from+20000000L)*1000000L;                 /* YYMMDD, year: 2000-2069 */
01159     else if (copy_from < (DRIZZLE_YY_PART_YEAR)*10000L+101L)
01160       return false;
01161     else if (copy_from <= 991231L)
01162       copy_from= (copy_from+19000000L)*1000000L;                 /* YYMMDD, year: 1970-1999 */
01163     else if (copy_from < 10000101L)
01164       return false;
01165     else if (copy_from <= 99991231L)
01166       copy_from= copy_from*1000000L;
01167     else if (copy_from < 101000000L)
01168       return false;
01169     else if (copy_from <= (DRIZZLE_YY_PART_YEAR-1) * 10000000000LL + 1231235959LL)
01170       copy_from= copy_from + 20000000000000LL;                   /* YYMMDDHHMMSS, 2000-2069 */
01171     else if (copy_from <  DRIZZLE_YY_PART_YEAR * 10000000000LL + 101000000LL)
01172       return false;
01173     else if (copy_from <= 991231235959LL)
01174       copy_from= copy_from + 19000000000000LL;    /* YYMMDDHHMMSS, 1970-1999 */
01175   }
01176 
01177   part1= (int64_t) (copy_from / 1000000LL);
01178   part2= (int64_t) (copy_from - (int64_t) part1 * 1000000LL);
01179   _years=  (uint32_t) (part1/10000L);  
01180   
01181   part1%=10000L;
01182   _months= (uint32_t) part1 / 100;
01183   _days=   (uint32_t) part1 % 100;
01184   _hours=  (uint32_t) (part2/10000L);  
01185 
01186   part2%=10000L;
01187   _minutes= (uint32_t) part2 / 100;
01188   _seconds= (uint32_t) part2 % 100;
01189 
01190   set_epoch_seconds();
01191   return is_valid();
01192 }
01193 
01194 bool Date::in_unix_epoch() const
01195 {
01196   return in_unix_epoch_range(_years, _months, _days, 0, 0, 0);
01197 }
01198 
01199 bool DateTime::in_unix_epoch() const
01200 {
01201   return in_unix_epoch_range(_years, _months, _days, _hours, _minutes, _seconds);
01202 }
01203 
01204 bool Date::from_tm(const struct tm *from)
01205 {
01206   _years= 1900 + from->tm_year;
01207   _months= 1 + from->tm_mon; /* Month is NOT ordinal for struct tm! */
01208   _days= from->tm_mday; /* Day IS ordinal for struct tm */
01209   _hours= from->tm_hour;
01210   _minutes= from->tm_min;
01211   _seconds= from->tm_sec;
01212   /* Set hires precision to zero */
01213   _useconds= 0;
01214   _nseconds= 0;
01215 
01216   set_epoch_seconds();
01217   return is_valid();
01218 }
01219 
01220 /* 
01221  * We convert as if it's a Datetime, then simply
01222  * drop the date portions...
01223  */
01224 bool Time::from_time_t(const time_t from)
01225 {
01226   struct tm broken_time;
01227   struct tm *result;
01228 
01229   result= util::gmtime(from, &broken_time);
01230   if (result != NULL)
01231   {
01232     _years= 0;
01233     _months= 0;
01234     _days= 0;
01235     _hours= broken_time.tm_hour;
01236     _minutes= broken_time.tm_min;
01237     _seconds= broken_time.tm_sec;
01238     _epoch_seconds= 0; /* Don't store the time_t, since we only use part of it */
01239     /* Set hires precision to zero */
01240     _useconds= 0;
01241     _nseconds= 0;
01242     return true; /* Always true... */
01243   }
01244   else 
01245     return false;
01246 }
01247 
01248 bool Date::from_time_t(const time_t from)
01249 {
01250   struct tm broken_time;
01251   struct tm *result;
01252 
01253   result= util::gmtime(from, &broken_time);
01254   if (result != NULL)
01255   {
01256     _years= 1900 + broken_time.tm_year;
01257     _months= 1 + broken_time.tm_mon; /* Month is NOT ordinal for struct tm! */
01258     _days= broken_time.tm_mday; /* Day IS ordinal for struct tm */
01259     _hours= 0;
01260     _minutes= 0;
01261     _seconds= 0;
01262     _epoch_seconds= 0; /* Don't store the time_t, since we only use part of it */
01263     /* Set hires precision to zero */
01264     _useconds= 0;
01265     _nseconds= 0;
01266     return is_valid();
01267   }
01268   else 
01269     return false;
01270 }
01271 
01272 bool DateTime::from_timeval(struct timeval &timeval_arg)
01273 {
01274   struct tm broken_time;
01275   struct tm *result;
01276 
01277   result= util::gmtime(timeval_arg.tv_sec, &broken_time);
01278   if (result != NULL)
01279   {
01280     _years= 1900 + broken_time.tm_year;
01281     _months= 1 + broken_time.tm_mon; /* Month is NOT ordinal for struct tm! */
01282     _days= broken_time.tm_mday; /* Day IS ordinal for struct tm */
01283     _hours= broken_time.tm_hour;
01284     _minutes= broken_time.tm_min;
01285     _seconds= broken_time.tm_sec;
01286     _epoch_seconds= timeval_arg.tv_sec;
01287     /* Set hires precision to zero */
01288     _useconds= timeval_arg.tv_usec;
01289     _nseconds= 0;
01290     return is_valid();
01291   }
01292   else 
01293   {
01294     return false;
01295   }
01296 }
01297 
01298 bool DateTime::from_time_t(const time_t from)
01299 {
01300   struct tm broken_time;
01301   struct tm *result;
01302 
01303   result= util::gmtime(from, &broken_time);
01304   if (result != NULL)
01305   {
01306     _years= 1900 + broken_time.tm_year;
01307     _months= 1 + broken_time.tm_mon; /* Month is NOT ordinal for struct tm! */
01308     _days= broken_time.tm_mday; /* Day IS ordinal for struct tm */
01309     _hours= broken_time.tm_hour;
01310     _minutes= broken_time.tm_min;
01311     _seconds= broken_time.tm_sec;
01312     _epoch_seconds= from;
01313     /* Set hires precision to zero */
01314     _useconds= 0;
01315     _nseconds= 0;
01316     return is_valid();
01317   }
01318   else 
01319   {
01320     return false;
01321   }
01322 }
01323 
01324 void Date::to_time_t(time_t &to) const
01325 {
01326   if (in_unix_epoch())
01327   {
01328     to= _epoch_seconds;
01329   }
01330   else
01331   {
01332     to= 0;
01333   }
01334 }
01335 
01336 void Timestamp::to_time_t(time_t &to) const
01337 {
01338   to= _epoch_seconds;
01339 }
01340 
01341 void MicroTimestamp::to_timeval(struct timeval &to) const
01342 {
01343   to.tv_sec= _epoch_seconds;
01344   to.tv_usec= _useconds;
01345 }
01346 
01347 void NanoTimestamp::to_timespec(struct timespec *to) const
01348 {
01349   to->tv_sec= _epoch_seconds;
01350   to->tv_nsec= _nseconds;
01351 }
01352 
01353 bool Date::is_valid() const
01354 {
01355   return (_years >= DRIZZLE_MIN_YEARS_SQL && _years <= DRIZZLE_MAX_YEARS_SQL)
01356       && (_months >= 1 && _months <= DRIZZLE_MAX_MONTHS)
01357       && (_days >= 1 && _days <= days_in_gregorian_year_month(_years, _months));
01358 }
01359 
01360 bool Time::is_valid() const
01361 {
01362   return (_years == 0)
01363       && (_months == 0)
01364       && (_days == 0)
01365       && (_hours <= DRIZZLE_MAX_HOURS)
01366       && (_minutes <= DRIZZLE_MAX_MINUTES)
01367       && (_seconds <= DRIZZLE_MAX_SECONDS); /* No Leap second... TIME is for elapsed time... */
01368 }
01369 
01370 bool Time::is_fuzzy_valid() const
01371 {
01372   if (is_valid())
01373     return true;
01374 
01375   return (_years >= DRIZZLE_MIN_YEARS_SQL && _years <= DRIZZLE_MAX_YEARS_SQL)
01376       && (_months >= 1 && _months <= DRIZZLE_MAX_MONTHS)
01377       && (_days >= 1 && _days <= days_in_gregorian_year_month(_years, _months))
01378       && (_hours <= DRIZZLE_MAX_HOURS)
01379       && (_minutes <= DRIZZLE_MAX_MINUTES)
01380       && (_seconds <= DRIZZLE_MAX_SECONDS); /* No Leap second... TIME is for elapsed time... */
01381 }
01382 
01383 bool DateTime::is_valid() const
01384 {
01385   return (_years >= DRIZZLE_MIN_YEARS_SQL && _years <= DRIZZLE_MAX_YEARS_SQL)
01386       && (_months >= 1 && _months <= DRIZZLE_MAX_MONTHS)
01387       && (_days >= 1 && _days <= days_in_gregorian_year_month(_years, _months))
01388       && (_hours <= DRIZZLE_MAX_HOURS)
01389       && (_minutes <= DRIZZLE_MAX_MINUTES)
01390       && (_seconds <= DRIZZLE_MAX_SECONDS_WITH_LEAP); /* Leap second... */
01391 }
01392 
01393 bool Timestamp::is_valid() const
01394 {
01395   return DateTime::is_valid()
01396       && in_unix_epoch_range(_years, _months, _days, _hours, _minutes, _seconds)
01397       && (_seconds <= DRIZZLE_MAX_SECONDS);
01398 }
01399 
01400 bool MicroTimestamp::is_valid() const
01401 {
01402   return Timestamp::is_valid()
01403       && (_useconds <= UINT32_C(999999));
01404 }
01405 
01406 bool NanoTimestamp::is_valid() const
01407 {
01408   return Timestamp::is_valid()
01409       && (_useconds <= UINT32_C(999999))
01410       && (_nseconds <= UINT32_C(999999999));
01411 }
01412 
01413 } /* namespace drizzled */