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 <drizzled/charset_info.h>
00040 #include <drizzled/type/decimal.h>
00041 #include <drizzled/calendar.h>
00042 #include <drizzled/temporal.h>
00043 #include <drizzled/temporal_format.h>
00044 #include <drizzled/time_functions.h>
00045 #include "time.h"
00046 
00047 #include <drizzled/util/gmtime.h>
00048 
00049 #include <time.h>
00050 
00051 #include <cstdio>
00052 #include <ostream>
00053 #include <iomanip>
00054 #include <vector>
00055 #include <string.h>
00056 
00057 namespace drizzled 
00058 {
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   /* 
00150    * Loop through the known date formats and see if 
00151    * there is a match.
00152    */
00153   bool matched= false;
00154   TemporalFormat *current_format;
00155   std::vector<TemporalFormat *>::iterator current= known_date_formats.begin();
00156 
00157   _useconds= 0; // We may not match on it, so we need to make sure we zero it out.
00158   while (current != known_date_formats.end())
00159   {
00160     current_format= *current;
00161     if (current_format->matches(from, from_len, this))
00162     {
00163       matched= true;
00164       break;
00165     }
00166     current++;
00167   }
00168 
00169   if (! matched)
00170     return false;
00171 
00172   set_epoch_seconds();
00173   return is_valid();
00174 }
00175 
00176 bool DateTime::from_string(const char *from, size_t from_len)
00177 {
00178   /* 
00179    * Loop through the known datetime formats and see if 
00180    * there is a match.
00181    */
00182   bool matched= false;
00183   TemporalFormat *current_format;
00184   std::vector<TemporalFormat *>::iterator current= known_datetime_formats.begin();
00185 
00186   while (current != known_datetime_formats.end())
00187   {
00188     current_format= *current;
00189     if (current_format->matches(from, from_len, this))
00190     {
00191       matched= true;
00192       break;
00193     }
00194     current++;
00195   }
00196 
00197   if (! matched)
00198     return false;
00199 
00200   set_epoch_seconds();
00201   return is_valid();
00202 }
00203 
00204 /*
00205  * Comparison operators for Time against another Time
00206  * are easy.  We simply compare the cumulative time
00207  * value of each.
00208  */
00209 bool Time::operator==(const Time& rhs)
00210 {
00211   return (
00212           _hours == rhs._hours
00213        && _minutes == rhs._minutes
00214        && _seconds == rhs._seconds
00215        && _useconds == rhs._useconds
00216        && _nseconds == rhs._nseconds
00217       );
00218 }
00219 bool Time::operator!=(const Time& rhs)
00220 {
00221   return ! (*this == rhs);
00222 }
00223 bool Time::operator<(const Time& rhs)
00224 {
00225   return (_cumulative_seconds_in_time() < rhs._cumulative_seconds_in_time());
00226 }
00227 bool Time::operator<=(const Time& rhs)
00228 {
00229   return (_cumulative_seconds_in_time() <= rhs._cumulative_seconds_in_time());
00230 }
00231 bool Time::operator>(const Time& rhs)
00232 {
00233   return (_cumulative_seconds_in_time() > rhs._cumulative_seconds_in_time());
00234 }
00235 bool Time::operator>=(const Time& rhs)
00236 {
00237   return (_cumulative_seconds_in_time() >= rhs._cumulative_seconds_in_time());
00238 }
00239 
00262 const Time Time::operator-(const Time& rhs)
00263 {
00264   Time result;
00265 
00266   int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
00267   result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
00268   second_diff%= DRIZZLE_SECONDS_IN_HOUR;
00269   result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
00270   second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
00271   result._seconds= (uint32_t) second_diff;
00272   
00273   return result;
00274 }
00275 const Time Time::operator+(const Time& rhs)
00276 {
00277   Time result;
00278   int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
00279   result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
00280   second_diff%= DRIZZLE_SECONDS_IN_HOUR;
00281   result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
00282   second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
00283   result._seconds= (uint32_t) second_diff;
00288   return result;
00289 }
00290 
00291 /*
00292  * Variation of + and - operator which returns a reference to the left-hand
00293  * side Time object and adds the right-hand side to itself.
00294  */
00295 Time& Time::operator+=(const Time& rhs)
00296 {
00297   int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
00298   _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
00299   second_diff%= DRIZZLE_SECONDS_IN_HOUR;
00300   _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
00301   second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
00302   _seconds= (uint32_t) second_diff;
00307   return *this;
00308 }
00309 Time& Time::operator-=(const Time& rhs)
00310 {
00311   int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
00312   _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
00313   second_diff%= DRIZZLE_SECONDS_IN_HOUR;
00314   _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
00315   second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
00316   _seconds= (uint32_t) second_diff;
00321   return *this;
00322 }
00323 
00324 /*
00325  * Comparison operators for Date against another Date
00326  * are easy.  We simply compare the cumulative
00327  * value of each.
00328  */
00329 bool Date::operator==(const Date& rhs)
00330 {
00331   return (
00332           _years == rhs._years
00333        && _months == rhs._months
00334        && _days == rhs._days
00335       );
00336 }
00337 bool Date::operator!=(const Date& rhs)
00338 {
00339   return ! (*this == rhs);
00340 }
00341 bool Date::operator<(const Date& rhs)
00342 {
00343   int64_t days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
00344   int64_t days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
00345   return (days_left < days_right);
00346 }
00347 bool Date::operator<=(const Date& rhs)
00348 {
00349   int64_t days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
00350   int64_t days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
00351   return (days_left <= days_right);
00352 }
00353 bool Date::operator>(const Date& rhs)
00354 {
00355   return ! (*this <= rhs);
00356 }
00357 bool Date::operator>=(const Date& rhs)
00358 {
00359   return ! (*this < rhs);
00360 }
00361 
00362 /*
00363  * Comparison operators for DateTime against another DateTime
00364  * are easy.  We simply compare the cumulative time
00365  * value of each.
00366  */
00367 bool Date::operator==(const DateTime& rhs)
00368 {
00369   return (
00370           _years == rhs._years
00371        && _months == rhs._months
00372        && _days == rhs._days
00373        && _hours == rhs._hours
00374        && _minutes == rhs._minutes
00375        && _seconds == rhs._seconds
00376        && _useconds == rhs._useconds
00377        && _nseconds == rhs._nseconds
00378       );
00379 }
00380 bool Date::operator!=(const DateTime& rhs)
00381 {
00382   return ! (*this == rhs);
00383 }
00384 bool Date::operator<(const DateTime& rhs)
00385 {
00386   int64_t days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
00387   int64_t days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
00388   if (days_left < days_right)
00389     return true;
00390   else if (days_left > days_right)
00391     return false;
00392   /* Here if both dates are the same, so compare times */
00393   return (_cumulative_seconds_in_time() < rhs._cumulative_seconds_in_time());
00394 }
00395 bool Date::operator<=(const DateTime& rhs)
00396 {
00397   int64_t days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
00398   int64_t days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
00399   if (days_left < days_right)
00400     return true;
00401   else if (days_left > days_right)
00402     return false;
00403   /* Here if both dates are the same, so compare times */
00404   return (_cumulative_seconds_in_time() <= rhs._cumulative_seconds_in_time());
00405 }
00406 bool Date::operator>(const DateTime& rhs)
00407 {
00408   return ! (*this <= rhs);
00409 }
00410 bool Date::operator>=(const DateTime& rhs)
00411 {
00412   return ! (*this < rhs);
00413 }
00414 
00419 const Date Date::operator-(const Time& rhs)
00420 {
00421   DateTime result;
00422 
00423   /* 
00424    * First, we set the resulting DATE pieces equal to our 
00425    * left-hand side DateTime's DATE components. Then, deal with 
00426    * the time components.
00427    */
00428   result._years= _years;
00429   result._months= _months;
00430   result._days= _days;
00431 
00432   int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
00433 
00434   /* 
00435    * The resulting diff might be negative.  If it is, that means that 
00436    * we have subtracting a larger time piece from the datetime, like so:
00437    *
00438    * x = DateTime("2007-06-09 09:30:00") - Time("16:30:00");
00439    *
00440    * In these cases, we need to subtract a day from the resulting
00441    * DateTime.
00442    */
00443   if (second_diff < 0)
00444     result._days--;
00445 
00446   result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
00447   second_diff%= DRIZZLE_SECONDS_IN_HOUR;
00448   result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
00449   second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
00450   result._seconds= (uint32_t) second_diff;
00451 
00452   /* Handle the microsecond precision */
00453   int64_t microsecond_diff= _useconds - rhs._useconds;
00454   if (microsecond_diff < 0)
00455   {
00456     microsecond_diff= (-1 * microsecond_diff);
00457     result._seconds--;
00458   }
00459   result._useconds= (uint32_t) microsecond_diff;
00460 
00461   return result;
00462 }
00463 const Date Date::operator+(const Time& rhs)
00464 {
00465   DateTime result;
00466 
00467   /* 
00468    * First, we set the resulting DATE pieces equal to our 
00469    * left-hand side DateTime's DATE components. Then, deal with 
00470    * the time components.
00471    */
00472   result._years= _years;
00473   result._months= _months;
00474   result._days= _days;
00475 
00476   int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
00477 
00478   /* 
00479    * The resulting seconds might be more than a day.  If do, 
00480    * adjust our resulting days up 1.
00481    */
00482   if (second_diff >= DRIZZLE_SECONDS_IN_DAY)
00483   {
00484     result._days++;
00485     second_diff%= DRIZZLE_SECONDS_IN_DAY;
00486   }
00487 
00488   result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
00489   second_diff%= DRIZZLE_SECONDS_IN_HOUR;
00490   result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
00491   second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
00492   result._seconds= (uint32_t) second_diff;
00493 
00494   /* Handle the microsecond precision */
00495   int64_t microsecond_diff= _useconds - rhs._useconds;
00496   if (microsecond_diff < 0)
00497   {
00498     microsecond_diff= (-1 * microsecond_diff);
00499     result._seconds--;
00500   }
00501   result._useconds= (uint32_t) microsecond_diff;
00502 
00503   return result;
00504 }
00505 
00506 /*
00507  * Variation of + and - operator which returns a reference to the left-hand
00508  * side DateTime object and adds the right-hand side Time to itself.
00509  */
00510 Date& Date::operator+=(const Time& rhs)
00511 {
00512   int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
00513   /* 
00514    * The resulting seconds might be more than a day.  If do, 
00515    * adjust our resulting days up 1.
00516    */
00517   if (second_diff >= DRIZZLE_SECONDS_IN_DAY)
00518   {
00519     _days++;
00520     second_diff%= DRIZZLE_SECONDS_IN_DAY;
00521   }
00522 
00523   _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
00524   second_diff%= DRIZZLE_SECONDS_IN_HOUR;
00525   _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
00526   second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
00527   _seconds= (uint32_t) second_diff;
00528 
00529   /* Handle the microsecond precision */
00530   int64_t microsecond_diff= _useconds - rhs._useconds;
00531   if (microsecond_diff < 0)
00532   {
00533     microsecond_diff= (-1 * microsecond_diff);
00534     _seconds--;
00535   }
00536   _useconds= (uint32_t) microsecond_diff;
00541   return *this;
00542 }
00543 Date& Date::operator-=(const Time& rhs)
00544 {
00545   int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
00546 
00547   /* 
00548    * The resulting diff might be negative.  If it is, that means that 
00549    * we have subtracting a larger time piece from the datetime, like so:
00550    *
00551    * x = DateTime("2007-06-09 09:30:00");
00552    * x-= Time("16:30:00");
00553    *
00554    * In these cases, we need to subtract a day from the resulting
00555    * DateTime.
00556    */
00557   if (second_diff < 0)
00558     _days--;
00559 
00560   _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
00561   second_diff%= DRIZZLE_SECONDS_IN_HOUR;
00562   _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
00563   second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
00564   _seconds= (uint32_t) second_diff;
00565 
00566   /* Handle the microsecond precision */
00567   int64_t microsecond_diff= _useconds - rhs._useconds;
00568   if (microsecond_diff < 0)
00569   {
00570     microsecond_diff= (-1 * microsecond_diff);
00571     _seconds--;
00572   }
00573   _useconds= (uint32_t) microsecond_diff;
00578   return *this;
00579 }
00580 
00585 const Date Date::operator-(const Date &rhs)
00586 {
00587   /* Figure out the difference in days between the two dates */
00588   int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
00589   int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
00590   int64_t day_diff= day_left - day_right;
00591 
00592   Date result;
00593   /* Now re-compose the Date's structure from the resulting Julian Day Number */
00594   gregorian_date_from_julian_day_number(day_diff, &result._years, &result._months, &result._days);
00595   return result;
00596 }
00597 const Date Date::operator+(const Date &rhs)
00598 {
00599   /* 
00600    * Figure out the new Julian Day Number by adding the JDNs of both
00601    * dates together.
00602    */
00603   int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
00604   int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
00605   int64_t day_diff= day_left + day_right;
00606 
00609   Date result;
00610   /* Now re-compose the Date's structure from the resulting Julian Day Number */
00611   gregorian_date_from_julian_day_number(day_diff, &result._years, &result._months, &result._days);
00612   return result;
00613 }
00614 /* Similar to the above, but we add/subtract the right side to this object itself */
00615 Date& Date::operator-=(const Date &rhs)
00616 {
00617   int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
00618   int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
00619   int64_t day_diff= day_left - day_right;
00620 
00621   /* Now re-compose the Date's structure from the resulting Julian Day Number */
00622   gregorian_date_from_julian_day_number(day_diff, &_years, &_months, &_days);
00623   return *this;
00624 }
00625 Date& Date::operator+=(const Date &rhs)
00626 {
00627   /* 
00628    * Figure out the new Julian Day Number by adding the JDNs of both
00629    * dates together.
00630    */
00631   int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
00632   int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
00633   int64_t day_diff= day_left + day_right;
00634 
00637   /* Now re-compose the Date's structure from the resulting Julian Day Number */
00638   gregorian_date_from_julian_day_number(day_diff, &_years, &_months, &_days);
00639   return *this;
00640 }
00641 
00642 Date& Date::operator=(const DateTime &rhs)
00643 {
00644   /* Only copy the Date components of the assigned DateTime... */
00645   _years= rhs._years;
00646   _months= rhs._months;
00647   _days= rhs._days;
00648   /* Zero-out everything else.. */
00649   _hours= _minutes= _seconds= _useconds= _nseconds= 0;
00650   return *this;
00651 }
00652 
00657 const Date Date::operator-(const DateTime &rhs)
00658 {
00659   /* Figure out the difference in days between the two dates. */
00660   int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
00661   int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
00662   int64_t day_diff= day_left - day_right;
00663 
00664   DateTime result;
00665   /* Now re-compose the Date's structure from the resulting Julian Day Number */
00666   gregorian_date_from_julian_day_number(day_diff, &result._years, &result._months, &result._days);
00667 
00668   /* And now handle the time components */
00669   int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
00670 
00671   /* 
00672    * The resulting diff might be negative.  If it is, that means that 
00673    * we have subtracting a larger time piece from the datetime, like so:
00674    *
00675    * x = DateTime("2007-06-09 09:30:00");
00676    * x-= Time("16:30:00");
00677    *
00678    * In these cases, we need to subtract a day from the resulting
00679    * DateTime.
00680    */
00681   if (second_diff < 0)
00682     _days--;
00683 
00684   result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
00685   second_diff%= DRIZZLE_SECONDS_IN_HOUR;
00686   result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
00687   second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
00688   result._seconds= (uint32_t) second_diff;
00689 
00690   /* Handle the microsecond precision */
00691   int64_t microsecond_diff= _useconds - rhs._useconds;
00692   if (microsecond_diff < 0)
00693   {
00694     microsecond_diff= (-1 * microsecond_diff);
00695     result._seconds--;
00696   }
00697   result._useconds= (uint32_t) microsecond_diff;
00698 
00699   return result;
00700 }
00701 const Date Date::operator+(const DateTime &rhs)
00702 {
00703   /*
00704    * Figure out the new Julian Day Number by adding the JDNs of both
00705    * dates together.
00706    */
00707   int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
00708   int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
00709   int64_t day_diff= day_left + day_right;
00710 
00713   DateTime result;
00714   /* Now re-compose the Date's structure from the resulting Julian Day Number */
00715   gregorian_date_from_julian_day_number(day_diff, &result._years, &result._months, &result._days);
00716 
00717   /* And now handle the time components */
00718   int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
00719 
00720   /* 
00721    * The resulting seconds might be more than a day.  If do, 
00722    * adjust our resulting days up 1.
00723    */
00724   if (second_diff >= DRIZZLE_SECONDS_IN_DAY)
00725   {
00726     result._days++;
00727     second_diff%= DRIZZLE_SECONDS_IN_DAY;
00728   }
00729 
00730   result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
00731   second_diff%= DRIZZLE_SECONDS_IN_HOUR;
00732   result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
00733   second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
00734   result._seconds= (uint32_t) second_diff;
00735 
00736   /* Handle the microsecond precision */
00737   int64_t microsecond_diff= _useconds - rhs._useconds;
00738   if (microsecond_diff < 0)
00739   {
00740     microsecond_diff= (-1 * microsecond_diff);
00741     result._seconds--;
00742   }
00743   result._useconds= (uint32_t) microsecond_diff;
00744 
00745   return result;
00746 }
00747 /* Similar to the above, but we add/subtract the right side to this object itself */
00748 Date& Date::operator-=(const DateTime &rhs)
00749 {
00750   /* Figure out the difference in days between the two dates.  */
00751   int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
00752   int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
00753   int64_t day_diff= day_left - day_right;
00754 
00755   /* Now re-compose the Date's structure from the ng Julian Day Number */
00756   gregorian_date_from_julian_day_number(day_diff, &_years, &_months, &_days);
00757 
00758   /* And now handle the time components */
00759   int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
00760 
00761   /* 
00762    * The resulting diff might be negative.  If it is, that means that 
00763    * we have subtracting a larger time piece from the datetime, like so:
00764    *
00765    * x = DateTime("2007-06-09 09:30:00");
00766    * x-= Time("16:30:00");
00767    *
00768    * In these cases, we need to subtract a day from the ng
00769    * DateTime.
00770    */
00771   if (second_diff < 0)
00772     _days--;
00773 
00774   _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
00775   second_diff%= DRIZZLE_SECONDS_IN_HOUR;
00776   _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
00777   second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
00778   _seconds= (uint32_t) second_diff;
00779 
00780   /* Handle the microsecond precision */
00781   int64_t microsecond_diff= _useconds - rhs._useconds;
00782   if (microsecond_diff < 0)
00783   {
00784     microsecond_diff= (-1 * microsecond_diff);
00785     _seconds--;
00786   }
00787   _useconds= (uint32_t) microsecond_diff;
00788 
00789   return *this;
00790 }
00791 Date& Date::operator+=(const DateTime &rhs)
00792 {
00793   /* 
00794    * Figure out the new Julian Day Number by adding the JDNs of both
00795    * dates together.
00796    */
00797   int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
00798   int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
00799   int64_t day_diff= day_left + day_right;
00800 
00803   /* Now re-compose the Date's structure from the ng Julian Day Number */
00804   gregorian_date_from_julian_day_number(day_diff, &_years, &_months, &_days);
00805 
00806   /* And now handle the time components */
00807   int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
00808 
00809   /* 
00810    * The resulting seconds might be more than a day.  If do, 
00811    * adjust our ng days up 1.
00812    */
00813   if (second_diff >= DRIZZLE_SECONDS_IN_DAY)
00814   {
00815     _days++;
00816     second_diff%= DRIZZLE_SECONDS_IN_DAY;
00817   }
00818 
00819   _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
00820   second_diff%= DRIZZLE_SECONDS_IN_HOUR;
00821   _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
00822   second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
00823   _seconds= (uint32_t) second_diff;
00824 
00825   /* Handle the microsecond precision */
00826   int64_t microsecond_diff= _useconds - rhs._useconds;
00827   if (microsecond_diff < 0)
00828   {
00829     microsecond_diff= (-1 * microsecond_diff);
00830     _seconds--;
00831   }
00832   _useconds= (uint32_t) microsecond_diff;
00833 
00834   return *this;
00835 }
00836 
00837 /*
00838  * Comparison operators between a Date and a Timestamp
00839  */
00840 bool Date::operator==(const Timestamp& rhs)
00841 {
00842   return (_years == rhs._years && _months == rhs._months && _days == rhs._days);
00843 }
00844 bool Date::operator!=(const Timestamp& rhs)
00845 {
00846   return ! (*this == rhs);
00847 }
00848 bool Date::operator<(const Timestamp& rhs)
00849 {
00850   if (_years < rhs._years)
00851     return true;
00852   if (_years > rhs._years)
00853     return false;
00854   /* In same year */
00855   if (_months < rhs._months)
00856     return true;
00857   if (_months > rhs._months)
00858     return false;
00859   /* Same month */
00860   return _days < rhs._days;
00861 }
00862 bool Date::operator<=(const Timestamp& rhs)
00863 {
00864   return (*this < rhs || *this == rhs);
00865 }
00866 bool Date::operator>(const Timestamp& rhs)
00867 {
00868   return ! (*this <= rhs);
00869 }
00870 bool Date::operator>=(const Timestamp& rhs)
00871 {
00872   return ! (*this < rhs);
00873 }
00874 /*
00875  * Comparison operators between a Timestamp and a Date
00876  */
00877 bool Timestamp::operator==(const Date& rhs)
00878 {
00879   return (_years == rhs._years && _months == rhs._months && _days == rhs._days);
00880 }
00881 bool Timestamp::operator!=(const Date& rhs)
00882 {
00883   return ! (*this == rhs);
00884 }
00885 bool Timestamp::operator<(const Date& rhs)
00886 {
00887   if (_years < rhs._years)
00888     return true;
00889   if (_years > rhs._years)
00890     return false;
00891   /* In same year */
00892   if (_months < rhs._months)
00893     return true;
00894   if (_months > rhs._months)
00895     return false;
00896   /* Same month */
00897   return _days < rhs._days;
00898 }
00899 bool Timestamp::operator<=(const Date& rhs)
00900 {
00901   return (*this < rhs || *this == rhs);
00902 }
00903 bool Timestamp::operator>(const Date& rhs)
00904 {
00905   return ! (*this <= rhs);
00906 }
00907 bool Timestamp::operator>=(const Date& rhs)
00908 {
00909   return ! (*this < rhs);
00910 }
00911 /*
00912  * Comparison operators between a Timestamp and a DateTime
00913  */
00914 bool Timestamp::operator==(const DateTime& rhs)
00915 {
00916   return (_years == rhs._years && _months == rhs._months && _days == rhs._days
00917           && _hours == rhs._hours && _minutes == rhs._minutes && _seconds == rhs._seconds);
00918 }
00919 bool Timestamp::operator!=(const DateTime& rhs)
00920 {
00921   return ! (*this == rhs);
00922 }
00923 bool Timestamp::operator<(const DateTime& rhs)
00924 {
00925   if (_years < rhs._years)
00926     return true;
00927   if (_years > rhs._years)
00928     return false;
00929   /* In same year */
00930   if (_months < rhs._months)
00931     return true;
00932   if (_months > rhs._months)
00933     return false;
00934   /* Same month */
00935   if (_days < rhs._days)
00936     return true;
00937   if (_days > rhs._days)
00938      return false;
00939   /* Same day */
00940   if (_hours < rhs._hours)
00941     return true;
00942   if (_hours > rhs._hours)
00943     return false;
00944   /* Same hour */
00945   if (_minutes < rhs._minutes)
00946     return true;
00947   if (_minutes > rhs._minutes)
00948     return false;
00949   /* Same minute */
00950   return _seconds < rhs._seconds;
00951 }
00952 bool Timestamp::operator<=(const DateTime& rhs)
00953 {
00954   return (*this < rhs || *this == rhs);
00955 }
00956 bool Timestamp::operator>(const DateTime& rhs)
00957 {
00958   return ! (*this <= rhs);
00959 }
00960 bool Timestamp::operator>=(const DateTime& rhs)
00961 {
00962   return ! (*this < rhs);
00963 }
00964 /*
00965  * Comparison operators between two Timestamps
00966  */
00967 bool Timestamp::operator==(const Timestamp& rhs)
00968 {
00969   return (_epoch_seconds == rhs._epoch_seconds);
00970 }
00971 bool Timestamp::operator!=(const Timestamp& rhs)
00972 {
00973   return ! (*this == rhs);
00974 }
00975 bool Timestamp::operator<(const Timestamp& rhs)
00976 {
00977   return (_epoch_seconds < rhs._epoch_seconds);
00978 }
00979 bool Timestamp::operator<=(const Timestamp& rhs)
00980 {
00981   return (_epoch_seconds <= rhs._epoch_seconds);
00982 }
00983 bool Timestamp::operator>(const Timestamp& rhs)
00984 {
00985   return ! (*this <= rhs);
00986 }
00987 bool Timestamp::operator>=(const Timestamp& rhs)
00988 {
00989   return ! (*this < rhs);
00990 }
00991 
00999 std::ostream& operator<<(std::ostream& os, const Timestamp& subject)
01000 {
01001   return os << subject.years() << '-' 
01002             << std::setw(2) << std::setfill('0') << subject.months() << '-'
01003             << std::setw(2) << std::setfill('0') << subject.days() << ' '
01004             << std::setw(2) << std::setfill('0') << subject.hours() << ':'
01005             << std::setw(2) << std::setfill('0') << subject.minutes() << ':'
01006             << std::setw(2) << std::setfill('0') << subject.seconds();
01007 }
01008 
01009 bool Time::from_string(const char *from, size_t from_len)
01010 {
01011   /*
01012    * Loop through the known time formats and see if
01013    * there is a match.
01014    */
01015   bool matched= false;
01016   TemporalFormat *current_format;
01017   std::vector<TemporalFormat *>::iterator current= known_time_formats.begin();
01018 
01019   while (current != known_time_formats.end())
01020   {
01021     current_format= *current;
01022     if (current_format->matches(from, from_len, this))
01023     {
01024       matched= true;
01025       break;
01026     }
01027     current++;
01028   }
01029 
01030   if (not matched)
01031     return false;
01032 
01033   return is_fuzzy_valid();
01034 }
01035 
01036 int Time::to_string(char *to, size_t to_len) const
01037 {
01038   return snprintf(to, to_len,
01039       "%02" PRIu32 ":%02" PRIu32 ":%02" PRIu32,
01040       _hours, _minutes, _seconds);
01041 }
01042 
01043 int Date::to_string(char *to, size_t to_len) const
01044 {
01045   return snprintf(to, to_len,
01046       "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32,
01047       _years, _months, _days);
01048 }
01049 
01050 int DateTime::to_string(char *to, size_t to_len) const
01051 {
01052   /* If the temporal has a microsecond component, use a slightly different output */
01053   if (_useconds == 0)
01054   {
01055     return snprintf(to, to_len,
01056         "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32
01057               " %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32,
01058         _years, _months, _days,
01059         _hours, _minutes, _seconds);
01060   }
01061   else
01062   {
01063     return snprintf(to, to_len,
01064         "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32
01065            " %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 ".%06" PRIu32,
01066         _years, _months, _days,
01067         _hours, _minutes, _seconds, _useconds);
01068   }
01069 }
01070 
01071 int MicroTimestamp::to_string(char *to, size_t to_len) const
01072 {
01073   return snprintf(to, to_len,
01074                   "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32
01075                   " %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 ".%06" PRIu32,
01076                   _years, _months, _days,
01077                   _hours, _minutes, _seconds, _useconds);
01078 }
01079 
01080 void Time::to_decimal(type::Decimal *to) const
01081 {
01082   int64_t time_portion= (((_hours * 100L) + _minutes) * 100L) + _seconds;
01083   (void) int2_class_decimal(E_DEC_FATAL_ERROR, time_portion, false, to);
01084   if (_useconds > 0)
01085   {
01086     to->buf[(to->intg-1) / 9 + 1]= _useconds * 1000;
01087     to->frac= 6;
01088   }
01089 }
01090 
01091 void Date::to_decimal(type::Decimal *to) const
01092 {
01093   int64_t date_portion= (((_years * 100L) + _months) * 100L) + _days;
01094   (void) int2_class_decimal(E_DEC_FATAL_ERROR, date_portion, false, to);
01095 }
01096 
01097 void DateTime::to_decimal(type::Decimal *to) const
01098 {
01099   int64_t date_portion= (((_years * 100L) + _months) * 100L) + _days;
01100   int64_t time_portion= (((((date_portion * 100L) + _hours) * 100L) + _minutes) * 100L) + _seconds;
01101   (void) int2_class_decimal(E_DEC_FATAL_ERROR, time_portion, false, to);
01102   if (_useconds > 0)
01103   {
01104     to->buf[(to->intg-1) / 9 + 1]= _useconds * 1000;
01105     to->frac= 6;
01106   }
01107 }
01108 
01109 void Date::to_int64_t(int64_t *to) const
01110 {
01111   *to= (_years * INT32_C(10000)) 
01112      + (_months * INT32_C(100)) 
01113      + _days;
01114 }
01115 
01116 void Date::to_int32_t(int32_t *to) const
01117 {
01118   *to= (_years * INT32_C(10000)) 
01119      + (_months * INT32_C(100)) 
01120      + _days;
01121 }
01122 
01123 void Time::to_int32_t(int32_t *to) const
01124 {
01125   *to= (_hours * INT32_C(10000)) 
01126      + (_minutes * INT32_C(100)) 
01127      + _seconds;
01128 }
01129 
01130 // We fill the structure based on just int
01131 void Time::to_uint64_t(uint64_t &to) const
01132 {
01133   to= (_hours * 60 * 60)
01134      + (_minutes * 60)
01135      + _seconds;
01136 }
01137 
01138 void DateTime::to_int64_t(int64_t *to) const
01139 {
01140   *to= ((
01141        (_years * INT64_C(10000)) 
01142      + (_months * INT64_C(100)) 
01143      + _days
01144        ) * INT64_C(1000000))
01145      + (
01146        (_hours * INT64_C(10000)) 
01147      + (_minutes * INT64_C(100) )
01148      + _seconds
01149      );
01150 }
01151 
01152 void Date::to_tm(struct tm *to) const
01153 {
01154   to->tm_sec= 0;
01155   to->tm_min= 0;
01156   to->tm_hour= 0;
01157   to->tm_mday= _days; /* Drizzle format uses ordinal, standard tm does too! */
01158   to->tm_mon= _months - 1; /* Drizzle format uses ordinal, standard tm does NOT! */
01159   to->tm_year= _years - 1900;
01160 }
01161 
01162 void DateTime::to_tm(struct tm *to) const
01163 {
01164   to->tm_sec= _seconds;
01165   to->tm_min= _minutes;
01166   to->tm_hour= _hours;
01167   to->tm_mday= _days; /* Drizzle format uses ordinal, standard tm does too! */
01168   to->tm_mon= _months - 1; /* Drizzle format uses ordinal, standard tm does NOT! */
01169   to->tm_year= _years - 1900;
01170 }
01171 
01172 bool Date::from_julian_day_number(const int64_t from)
01173 {
01174   gregorian_date_from_julian_day_number(from, &_years, &_months, &_days);
01175   return is_valid();
01176 }
01177 
01178 void Date::to_julian_day_number(int64_t *to) const
01179 {
01180   *to= julian_day_number_from_gregorian_date(_years, _months, _days);
01181 }
01182 
01186 bool Date::from_int32_t(const int32_t from)
01187 {
01188   return ((DateTime *) this)->from_int64_t((int64_t) from);
01189 }
01190 
01195 bool Time::from_int32_t(const int32_t from)
01196 {
01197   uint32_t copy_from= (uint32_t) from;
01198   _hours= copy_from / INT32_C(10000);
01199   _minutes= (copy_from % INT32_C(10000)) / INT32_C(100);
01200   _seconds= copy_from % INT32_C(100); /* Masks off all but last 2 digits */
01201   return is_valid();
01202 }
01203 
01209 bool DateTime::from_int64_t(const int64_t from, bool convert)
01210 {
01211   int64_t copy_from= from;
01212   int64_t part1;
01213   int64_t part2;
01214 
01215   if (copy_from == 0LL)
01216     return false;
01217 
01218   if (convert && copy_from < 10000101000000LL)
01219   {
01220     if (copy_from < 101)
01221       return false;
01222     else if (copy_from <= (DRIZZLE_YY_PART_YEAR-1)*10000L+1231L)
01223       copy_from= (copy_from+20000000L)*1000000L;                 /* YYMMDD, year: 2000-2069 */
01224     else if (copy_from < (DRIZZLE_YY_PART_YEAR)*10000L+101L)
01225       return false;
01226     else if (copy_from <= 991231L)
01227       copy_from= (copy_from+19000000L)*1000000L;                 /* YYMMDD, year: 1970-1999 */
01228     else if (copy_from < 10000101L)
01229       return false;
01230     else if (copy_from <= 99991231L)
01231       copy_from= copy_from*1000000L;
01232     else if (copy_from < 101000000L)
01233       return false;
01234     else if (copy_from <= (DRIZZLE_YY_PART_YEAR-1) * 10000000000LL + 1231235959LL)
01235       copy_from= copy_from + 20000000000000LL;                   /* YYMMDDHHMMSS, 2000-2069 */
01236     else if (copy_from <  DRIZZLE_YY_PART_YEAR * 10000000000LL + 101000000LL)
01237       return false;
01238     else if (copy_from <= 991231235959LL)
01239       copy_from= copy_from + 19000000000000LL;    /* YYMMDDHHMMSS, 1970-1999 */
01240   }
01241 
01242   part1= (int64_t) (copy_from / 1000000LL);
01243   part2= (int64_t) (copy_from - (int64_t) part1 * 1000000LL);
01244   _years=  (uint32_t) (part1/10000L);  
01245   
01246   part1%=10000L;
01247   _months= (uint32_t) part1 / 100;
01248   _days=   (uint32_t) part1 % 100;
01249   _hours=  (uint32_t) (part2/10000L);  
01250 
01251   part2%=10000L;
01252   _minutes= (uint32_t) part2 / 100;
01253   _seconds= (uint32_t) part2 % 100;
01254 
01255   set_epoch_seconds();
01256   return is_valid();
01257 }
01258 
01259 bool Date::in_unix_epoch() const
01260 {
01261   return in_unix_epoch_range(_years, _months, _days, 0, 0, 0);
01262 }
01263 
01264 bool DateTime::in_unix_epoch() const
01265 {
01266   return in_unix_epoch_range(_years, _months, _days, _hours, _minutes, _seconds);
01267 }
01268 
01269 bool Date::from_tm(const struct tm *from)
01270 {
01271   _years= 1900 + from->tm_year;
01272   _months= 1 + from->tm_mon; /* Month is NOT ordinal for struct tm! */
01273   _days= from->tm_mday; /* Day IS ordinal for struct tm */
01274   _hours= from->tm_hour;
01275   _minutes= from->tm_min;
01276   _seconds= from->tm_sec;
01277   /* Set hires precision to zero */
01278   _useconds= 0;
01279   _nseconds= 0;
01280 
01281   set_epoch_seconds();
01282   return is_valid();
01283 }
01284 
01285 /* 
01286  * We convert as if it's a Datetime, then simply
01287  * drop the date portions...
01288  */
01289 bool Time::from_time_t(const time_t from)
01290 {
01291   struct tm broken_time;
01292   struct tm *result;
01293 
01294   result= util::gmtime(from, &broken_time);
01295   if (result != NULL)
01296   {
01297     _years= 0;
01298     _months= 0;
01299     _days= 0;
01300     _hours= broken_time.tm_hour;
01301     _minutes= broken_time.tm_min;
01302     _seconds= broken_time.tm_sec;
01303     _epoch_seconds= 0; /* Don't store the time_t, since we only use part of it */
01304     /* Set hires precision to zero */
01305     _useconds= 0;
01306     _nseconds= 0;
01307     return true; /* Always true... */
01308   }
01309   else 
01310     return false;
01311 }
01312 
01313 bool Date::from_time_t(const time_t from)
01314 {
01315   struct tm broken_time;
01316   struct tm *result;
01317 
01318   result= util::gmtime(from, &broken_time);
01319   if (result != NULL)
01320   {
01321     _years= 1900 + broken_time.tm_year;
01322     _months= 1 + broken_time.tm_mon; /* Month is NOT ordinal for struct tm! */
01323     _days= broken_time.tm_mday; /* Day IS ordinal for struct tm */
01324     _hours= 0;
01325     _minutes= 0;
01326     _seconds= 0;
01327     _epoch_seconds= 0; /* Don't store the time_t, since we only use part of it */
01328     /* Set hires precision to zero */
01329     _useconds= 0;
01330     _nseconds= 0;
01331     return is_valid();
01332   }
01333   else 
01334     return false;
01335 }
01336 
01337 bool DateTime::from_timeval(struct timeval &timeval_arg)
01338 {
01339   struct tm broken_time;
01340   struct tm *result;
01341 
01342   result= util::gmtime(timeval_arg.tv_sec, &broken_time);
01343   if (result != NULL)
01344   {
01345     _years= 1900 + broken_time.tm_year;
01346     _months= 1 + broken_time.tm_mon; /* Month is NOT ordinal for struct tm! */
01347     _days= broken_time.tm_mday; /* Day IS ordinal for struct tm */
01348     _hours= broken_time.tm_hour;
01349     _minutes= broken_time.tm_min;
01350     _seconds= broken_time.tm_sec;
01351     _epoch_seconds= timeval_arg.tv_sec;
01352     /* Set hires precision to zero */
01353     _useconds= timeval_arg.tv_usec;
01354     _nseconds= 0;
01355     return is_valid();
01356   }
01357   else 
01358   {
01359     return false;
01360   }
01361 }
01362 
01363 bool DateTime::from_time_t(const time_t from)
01364 {
01365   struct tm broken_time;
01366   struct tm *result;
01367 
01368   result= util::gmtime(from, &broken_time);
01369   if (result != NULL)
01370   {
01371     _years= 1900 + broken_time.tm_year;
01372     _months= 1 + broken_time.tm_mon; /* Month is NOT ordinal for struct tm! */
01373     _days= broken_time.tm_mday; /* Day IS ordinal for struct tm */
01374     _hours= broken_time.tm_hour;
01375     _minutes= broken_time.tm_min;
01376     _seconds= broken_time.tm_sec;
01377     _epoch_seconds= from;
01378     /* Set hires precision to zero */
01379     _useconds= 0;
01380     _nseconds= 0;
01381     return is_valid();
01382   }
01383   else 
01384   {
01385     return false;
01386   }
01387 }
01388 
01389 void Date::to_time_t(time_t &to) const
01390 {
01391   if (in_unix_epoch())
01392   {
01393     to= _epoch_seconds;
01394   }
01395   else
01396   {
01397     to= 0;
01398   }
01399 }
01400 
01401 void Timestamp::to_time_t(time_t &to) const
01402 {
01403   to= _epoch_seconds;
01404 }
01405 
01406 void MicroTimestamp::to_timeval(struct timeval &to) const
01407 {
01408   to.tv_sec= _epoch_seconds;
01409   to.tv_usec= _useconds;
01410 }
01411 
01412 void NanoTimestamp::to_timespec(struct timespec *to) const
01413 {
01414   to->tv_sec= _epoch_seconds;
01415   to->tv_nsec= _nseconds;
01416 }
01417 
01418 bool Date::is_valid() const
01419 {
01420   return (_years >= DRIZZLE_MIN_YEARS_SQL && _years <= DRIZZLE_MAX_YEARS_SQL)
01421       && (_months >= 1 && _months <= DRIZZLE_MAX_MONTHS)
01422       && (_days >= 1 && _days <= days_in_gregorian_year_month(_years, _months));
01423 }
01424 
01425 bool Time::is_valid() const
01426 {
01427   return (_years == 0)
01428       && (_months == 0)
01429       && (_days == 0)
01430       && (_hours <= DRIZZLE_MAX_HOURS)
01431       && (_minutes <= DRIZZLE_MAX_MINUTES)
01432       && (_seconds <= DRIZZLE_MAX_SECONDS); /* No Leap second... TIME is for elapsed time... */
01433 }
01434 
01435 bool Time::is_fuzzy_valid() const
01436 {
01437   if (is_valid())
01438     return true;
01439 
01440   return (_years >= DRIZZLE_MIN_YEARS_SQL && _years <= DRIZZLE_MAX_YEARS_SQL)
01441       && (_months >= 1 && _months <= DRIZZLE_MAX_MONTHS)
01442       && (_days >= 1 && _days <= days_in_gregorian_year_month(_years, _months))
01443       && (_hours <= DRIZZLE_MAX_HOURS)
01444       && (_minutes <= DRIZZLE_MAX_MINUTES)
01445       && (_seconds <= DRIZZLE_MAX_SECONDS); /* No Leap second... TIME is for elapsed time... */
01446 }
01447 
01448 bool DateTime::is_valid() const
01449 {
01450   return (_years >= DRIZZLE_MIN_YEARS_SQL && _years <= DRIZZLE_MAX_YEARS_SQL)
01451       && (_months >= 1 && _months <= DRIZZLE_MAX_MONTHS)
01452       && (_days >= 1 && _days <= days_in_gregorian_year_month(_years, _months))
01453       && (_hours <= DRIZZLE_MAX_HOURS)
01454       && (_minutes <= DRIZZLE_MAX_MINUTES)
01455       && (_seconds <= DRIZZLE_MAX_SECONDS_WITH_LEAP); /* Leap second... */
01456 }
01457 
01458 bool Timestamp::is_valid() const
01459 {
01460   return DateTime::is_valid()
01461       && in_unix_epoch_range(_years, _months, _days, _hours, _minutes, _seconds)
01462       && (_seconds <= DRIZZLE_MAX_SECONDS);
01463 }
01464 
01465 bool MicroTimestamp::is_valid() const
01466 {
01467   return Timestamp::is_valid()
01468       && (_useconds <= UINT32_C(999999));
01469 }
01470 
01471 bool NanoTimestamp::is_valid() const
01472 {
01473   return Timestamp::is_valid()
01474       && (_useconds <= UINT32_C(999999))
01475       && (_nseconds <= UINT32_C(999999999));
01476 }
01477 
01478 } /* namespace drizzled */