Drizzled Public API Documentation

temporal.cc
Go to the documentation of this file.
1 /* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3  *
4  * Copyright (C) 2008 Sun Microsystems, Inc.
5  *
6  * Authors:
7  *
8  * Jay Pipes <jay.pipes@sun.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23  */
24 
37 #include <config.h>
38 
39 #include <boost/foreach.hpp>
40 #include <drizzled/charset.h>
41 #include <drizzled/type/decimal.h>
42 #include <drizzled/calendar.h>
43 #include <drizzled/temporal.h>
45 #include <drizzled/time_functions.h>
46 #include "time.h"
47 
48 #include <drizzled/util/gmtime.h>
49 
50 #include <time.h>
51 
52 #include <cstdio>
53 #include <ostream>
54 #include <iomanip>
55 #include <vector>
56 #include <string.h>
57 
58 namespace drizzled {
59 
60 extern std::vector<TemporalFormat *> known_datetime_formats;
61 extern std::vector<TemporalFormat *> known_date_formats;
62 extern std::vector<TemporalFormat *> known_time_formats;
63 
64 Temporal::Temporal() :
65  _calendar(GREGORIAN),
66  _years(0),
67  _months(0),
68  _days(0),
69  _hours(0),
70  _minutes(0),
71  _seconds(0),
72  _epoch_seconds(0),
73  _useconds(0),
74  _nseconds(0),
75  _overflow(false)
76 {}
77 
79 {
80  return (uint64_t) ((_hours * INT64_C(3600))
81  + (_minutes * INT64_C(60))
82  + _seconds);
83 }
84 
85 #if defined(TARGET_OS_SOLARIS)
86 /* @TODO: Replace this with Boost.DateTime */
87 static time_t timegm(struct tm *my_time)
88 {
89  time_t local_secs, gm_secs;
90  struct tm gm__rec, *gm_time;
91 
92  // Interpret 't' as the local time and convert it to seconds since the Epoch
93  local_secs = mktime(my_time);
94  if (local_secs == -1)
95  {
96  my_time->tm_hour--;
97  local_secs = mktime (my_time);
98  if (local_secs == -1)
99  return -1;
100  local_secs += 3600;
101  }
102 
103  // Get the gmtime based on the local seconds since the Epoch
104  gm_time = util::gmtime(local_secs, &gm__rec);
105  gm_time->tm_isdst = 0;
106 
107  // Interpret gmtime as the local time and convert it to seconds since the Epoch
108  gm_secs = mktime (gm_time);
109  if (gm_secs == -1)
110  {
111  gm_time->tm_hour--;
112  gm_secs = mktime (gm_time);
113  if (gm_secs == -1)
114  return -1;
115  gm_secs += 3600;
116  }
117 
118  // Return the local time adjusted by the difference from GM time.
119  return (local_secs - (gm_secs - local_secs));
120 }
121 #endif
122 
124 {
125  /*
126  * If the temporal is in the range of a timestamp, set
127  * the epoch_seconds member variable
128  */
129  if (in_unix_epoch_range(_years, _months, _days, _hours, _minutes, _seconds))
130  {
131  time_t result_time;
132  struct tm broken_time;
133 
134  broken_time.tm_sec= _seconds;
135  broken_time.tm_min= _minutes;
136  broken_time.tm_hour= _hours;
137  broken_time.tm_mday= _days; /* Drizzle format uses ordinal, standard tm does too! */
138  broken_time.tm_mon= _months - 1; /* Drizzle format uses ordinal, standard tm does NOT! */
139  broken_time.tm_year= _years - 1900; /* tm_year expects range of 70 - 38 */
140 
141  result_time= timegm(&broken_time);
142 
143  _epoch_seconds= result_time;
144  }
145 }
146 
147 bool Date::from_string(const char *from, size_t from_len)
148 {
149  _useconds= 0; // We may not match on it, so we need to make sure we zero it out.
150  BOOST_FOREACH(TemporalFormat* it, known_date_formats)
151  {
152  if (not it->matches(from, from_len, this))
153  continue;
155  return is_valid();
156  }
157  return false;
158 }
159 
160 bool DateTime::from_string(const char *from, size_t from_len)
161 {
162  BOOST_FOREACH(TemporalFormat* it, known_datetime_formats)
163  {
164  if (not it->matches(from, from_len, this))
165  continue;
167  return is_valid();
168  }
169  return false;
170 
171 }
172 
173 /*
174  * Comparison operators for Time against another Time
175  * are easy. We simply compare the cumulative time
176  * value of each.
177  */
178 bool Time::operator==(const Time& rhs)
179 {
180  return (
181  _hours == rhs._hours
182  && _minutes == rhs._minutes
183  && _seconds == rhs._seconds
184  && _useconds == rhs._useconds
185  && _nseconds == rhs._nseconds
186  );
187 }
188 bool Time::operator!=(const Time& rhs)
189 {
190  return ! (*this == rhs);
191 }
192 bool Time::operator<(const Time& rhs)
193 {
194  return (_cumulative_seconds_in_time() < rhs._cumulative_seconds_in_time());
195 }
196 bool Time::operator<=(const Time& rhs)
197 {
198  return (_cumulative_seconds_in_time() <= rhs._cumulative_seconds_in_time());
199 }
200 bool Time::operator>(const Time& rhs)
201 {
202  return (_cumulative_seconds_in_time() > rhs._cumulative_seconds_in_time());
203 }
204 bool Time::operator>=(const Time& rhs)
205 {
206  return (_cumulative_seconds_in_time() >= rhs._cumulative_seconds_in_time());
207 }
208 
231 const Time Time::operator-(const Time& rhs)
232 {
233  Time result;
234 
235  int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
236  result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
237  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
238  result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
239  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
240  result._seconds= (uint32_t) second_diff;
241 
242  return result;
243 }
244 const Time Time::operator+(const Time& rhs)
245 {
246  Time result;
247  int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
248  result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
249  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
250  result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
251  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
252  result._seconds= (uint32_t) second_diff;
257  return result;
258 }
259 
260 /*
261  * Variation of + and - operator which returns a reference to the left-hand
262  * side Time object and adds the right-hand side to itself.
263  */
265 {
266  int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
267  _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
268  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
269  _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
270  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
271  _seconds= (uint32_t) second_diff;
276  return *this;
277 }
279 {
280  int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
281  _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
282  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
283  _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
284  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
285  _seconds= (uint32_t) second_diff;
290  return *this;
291 }
292 
293 /*
294  * Comparison operators for Date against another Date
295  * are easy. We simply compare the cumulative
296  * value of each.
297  */
298 bool Date::operator==(const Date& rhs)
299 {
300  return (
301  _years == rhs._years
302  && _months == rhs._months
303  && _days == rhs._days
304  );
305 }
306 bool Date::operator!=(const Date& rhs)
307 {
308  return ! (*this == rhs);
309 }
310 bool Date::operator<(const Date& rhs)
311 {
312  int64_t days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
313  int64_t days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
314  return (days_left < days_right);
315 }
316 bool Date::operator<=(const Date& rhs)
317 {
318  int64_t days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
319  int64_t days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
320  return (days_left <= days_right);
321 }
322 bool Date::operator>(const Date& rhs)
323 {
324  return ! (*this <= rhs);
325 }
326 bool Date::operator>=(const Date& rhs)
327 {
328  return ! (*this < rhs);
329 }
330 
331 /*
332  * Comparison operators for DateTime against another DateTime
333  * are easy. We simply compare the cumulative time
334  * value of each.
335  */
336 bool Date::operator==(const DateTime& rhs)
337 {
338  return (
339  _years == rhs._years
340  && _months == rhs._months
341  && _days == rhs._days
342  && _hours == rhs._hours
343  && _minutes == rhs._minutes
344  && _seconds == rhs._seconds
345  && _useconds == rhs._useconds
346  && _nseconds == rhs._nseconds
347  );
348 }
349 bool Date::operator!=(const DateTime& rhs)
350 {
351  return ! (*this == rhs);
352 }
353 bool Date::operator<(const DateTime& rhs)
354 {
355  int64_t days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
356  int64_t days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
357  if (days_left < days_right)
358  return true;
359  else if (days_left > days_right)
360  return false;
361  /* Here if both dates are the same, so compare times */
362  return (_cumulative_seconds_in_time() < rhs._cumulative_seconds_in_time());
363 }
364 bool Date::operator<=(const DateTime& rhs)
365 {
366  int64_t days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
367  int64_t days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
368  if (days_left < days_right)
369  return true;
370  else if (days_left > days_right)
371  return false;
372  /* Here if both dates are the same, so compare times */
373  return (_cumulative_seconds_in_time() <= rhs._cumulative_seconds_in_time());
374 }
375 bool Date::operator>(const DateTime& rhs)
376 {
377  return ! (*this <= rhs);
378 }
379 bool Date::operator>=(const DateTime& rhs)
380 {
381  return ! (*this < rhs);
382 }
383 
388 const Date Date::operator-(const Time& rhs)
389 {
390  DateTime result;
391 
392  /*
393  * First, we set the resulting DATE pieces equal to our
394  * left-hand side DateTime's DATE components. Then, deal with
395  * the time components.
396  */
397  result._years= _years;
398  result._months= _months;
399  result._days= _days;
400 
401  int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
402 
403  /*
404  * The resulting diff might be negative. If it is, that means that
405  * we have subtracting a larger time piece from the datetime, like so:
406  *
407  * x = DateTime("2007-06-09 09:30:00") - Time("16:30:00");
408  *
409  * In these cases, we need to subtract a day from the resulting
410  * DateTime.
411  */
412  if (second_diff < 0)
413  result._days--;
414 
415  result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
416  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
417  result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
418  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
419  result._seconds= (uint32_t) second_diff;
420 
421  /* Handle the microsecond precision */
422  int64_t microsecond_diff= _useconds - rhs._useconds;
423  if (microsecond_diff < 0)
424  {
425  microsecond_diff= (-1 * microsecond_diff);
426  result._seconds--;
427  }
428  result._useconds= (uint32_t) microsecond_diff;
429 
430  return result;
431 }
432 const Date Date::operator+(const Time& rhs)
433 {
434  DateTime result;
435 
436  /*
437  * First, we set the resulting DATE pieces equal to our
438  * left-hand side DateTime's DATE components. Then, deal with
439  * the time components.
440  */
441  result._years= _years;
442  result._months= _months;
443  result._days= _days;
444 
445  int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
446 
447  /*
448  * The resulting seconds might be more than a day. If do,
449  * adjust our resulting days up 1.
450  */
451  if (second_diff >= DRIZZLE_SECONDS_IN_DAY)
452  {
453  result._days++;
454  second_diff%= DRIZZLE_SECONDS_IN_DAY;
455  }
456 
457  result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
458  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
459  result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
460  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
461  result._seconds= (uint32_t) second_diff;
462 
463  /* Handle the microsecond precision */
464  int64_t microsecond_diff= _useconds - rhs._useconds;
465  if (microsecond_diff < 0)
466  {
467  microsecond_diff= (-1 * microsecond_diff);
468  result._seconds--;
469  }
470  result._useconds= (uint32_t) microsecond_diff;
471 
472  return result;
473 }
474 
475 /*
476  * Variation of + and - operator which returns a reference to the left-hand
477  * side DateTime object and adds the right-hand side Time to itself.
478  */
480 {
481  int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
482  /*
483  * The resulting seconds might be more than a day. If do,
484  * adjust our resulting days up 1.
485  */
486  if (second_diff >= DRIZZLE_SECONDS_IN_DAY)
487  {
488  _days++;
489  second_diff%= DRIZZLE_SECONDS_IN_DAY;
490  }
491 
492  _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
493  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
494  _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
495  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
496  _seconds= (uint32_t) second_diff;
497 
498  /* Handle the microsecond precision */
499  int64_t microsecond_diff= _useconds - rhs._useconds;
500  if (microsecond_diff < 0)
501  {
502  microsecond_diff= (-1 * microsecond_diff);
503  _seconds--;
504  }
505  _useconds= (uint32_t) microsecond_diff;
510  return *this;
511 }
512 Date& Date::operator-=(const Time& rhs)
513 {
514  int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
515 
516  /*
517  * The resulting diff might be negative. If it is, that means that
518  * we have subtracting a larger time piece from the datetime, like so:
519  *
520  * x = DateTime("2007-06-09 09:30:00");
521  * x-= Time("16:30:00");
522  *
523  * In these cases, we need to subtract a day from the resulting
524  * DateTime.
525  */
526  if (second_diff < 0)
527  _days--;
528 
529  _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
530  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
531  _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
532  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
533  _seconds= (uint32_t) second_diff;
534 
535  /* Handle the microsecond precision */
536  int64_t microsecond_diff= _useconds - rhs._useconds;
537  if (microsecond_diff < 0)
538  {
539  microsecond_diff= (-1 * microsecond_diff);
540  _seconds--;
541  }
542  _useconds= (uint32_t) microsecond_diff;
547  return *this;
548 }
549 
554 const Date Date::operator-(const Date &rhs)
555 {
556  /* Figure out the difference in days between the two dates */
557  int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
558  int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
559  int64_t day_diff= day_left - day_right;
560 
561  Date result;
562  /* Now re-compose the Date's structure from the resulting Julian Day Number */
563  gregorian_date_from_julian_day_number(day_diff, &result._years, &result._months, &result._days);
564  return result;
565 }
566 const Date Date::operator+(const Date &rhs)
567 {
568  /*
569  * Figure out the new Julian Day Number by adding the JDNs of both
570  * dates together.
571  */
572  int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
573  int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
574  int64_t day_diff= day_left + day_right;
575 
578  Date result;
579  /* Now re-compose the Date's structure from the resulting Julian Day Number */
580  gregorian_date_from_julian_day_number(day_diff, &result._years, &result._months, &result._days);
581  return result;
582 }
583 /* Similar to the above, but we add/subtract the right side to this object itself */
584 Date& Date::operator-=(const Date &rhs)
585 {
586  int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
587  int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
588  int64_t day_diff= day_left - day_right;
589 
590  /* Now re-compose the Date's structure from the resulting Julian Day Number */
591  gregorian_date_from_julian_day_number(day_diff, &_years, &_months, &_days);
592  return *this;
593 }
595 {
596  /*
597  * Figure out the new Julian Day Number by adding the JDNs of both
598  * dates together.
599  */
600  int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
601  int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
602  int64_t day_diff= day_left + day_right;
603 
606  /* Now re-compose the Date's structure from the resulting Julian Day Number */
607  gregorian_date_from_julian_day_number(day_diff, &_years, &_months, &_days);
608  return *this;
609 }
610 
612 {
613  /* Only copy the Date components of the assigned DateTime... */
614  _years= rhs._years;
615  _months= rhs._months;
616  _days= rhs._days;
617  /* Zero-out everything else.. */
618  _hours= _minutes= _seconds= _useconds= _nseconds= 0;
619  return *this;
620 }
621 
626 const Date Date::operator-(const DateTime &rhs)
627 {
628  /* Figure out the difference in days between the two dates. */
629  int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
630  int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
631  int64_t day_diff= day_left - day_right;
632 
633  DateTime result;
634  /* Now re-compose the Date's structure from the resulting Julian Day Number */
635  gregorian_date_from_julian_day_number(day_diff, &result._years, &result._months, &result._days);
636 
637  /* And now handle the time components */
638  int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
639 
640  /*
641  * The resulting diff might be negative. If it is, that means that
642  * we have subtracting a larger time piece from the datetime, like so:
643  *
644  * x = DateTime("2007-06-09 09:30:00");
645  * x-= Time("16:30:00");
646  *
647  * In these cases, we need to subtract a day from the resulting
648  * DateTime.
649  */
650  if (second_diff < 0)
651  _days--;
652 
653  result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
654  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
655  result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
656  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
657  result._seconds= (uint32_t) second_diff;
658 
659  /* Handle the microsecond precision */
660  int64_t microsecond_diff= _useconds - rhs._useconds;
661  if (microsecond_diff < 0)
662  {
663  microsecond_diff= (-1 * microsecond_diff);
664  result._seconds--;
665  }
666  result._useconds= (uint32_t) microsecond_diff;
667 
668  return result;
669 }
670 const Date Date::operator+(const DateTime &rhs)
671 {
672  /*
673  * Figure out the new Julian Day Number by adding the JDNs of both
674  * dates together.
675  */
676  int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
677  int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
678  int64_t day_diff= day_left + day_right;
679 
682  DateTime result;
683  /* Now re-compose the Date's structure from the resulting Julian Day Number */
684  gregorian_date_from_julian_day_number(day_diff, &result._years, &result._months, &result._days);
685 
686  /* And now handle the time components */
687  int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
688 
689  /*
690  * The resulting seconds might be more than a day. If do,
691  * adjust our resulting days up 1.
692  */
693  if (second_diff >= DRIZZLE_SECONDS_IN_DAY)
694  {
695  result._days++;
696  second_diff%= DRIZZLE_SECONDS_IN_DAY;
697  }
698 
699  result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
700  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
701  result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
702  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
703  result._seconds= (uint32_t) second_diff;
704 
705  /* Handle the microsecond precision */
706  int64_t microsecond_diff= _useconds - rhs._useconds;
707  if (microsecond_diff < 0)
708  {
709  microsecond_diff= (-1 * microsecond_diff);
710  result._seconds--;
711  }
712  result._useconds= (uint32_t) microsecond_diff;
713 
714  return result;
715 }
716 /* Similar to the above, but we add/subtract the right side to this object itself */
717 Date& Date::operator-=(const DateTime &rhs)
718 {
719  /* Figure out the difference in days between the two dates. */
720  int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
721  int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
722  int64_t day_diff= day_left - day_right;
723 
724  /* Now re-compose the Date's structure from the ng Julian Day Number */
725  gregorian_date_from_julian_day_number(day_diff, &_years, &_months, &_days);
726 
727  /* And now handle the time components */
728  int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
729 
730  /*
731  * The resulting diff might be negative. If it is, that means that
732  * we have subtracting a larger time piece from the datetime, like so:
733  *
734  * x = DateTime("2007-06-09 09:30:00");
735  * x-= Time("16:30:00");
736  *
737  * In these cases, we need to subtract a day from the ng
738  * DateTime.
739  */
740  if (second_diff < 0)
741  _days--;
742 
743  _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
744  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
745  _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
746  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
747  _seconds= (uint32_t) second_diff;
748 
749  /* Handle the microsecond precision */
750  int64_t microsecond_diff= _useconds - rhs._useconds;
751  if (microsecond_diff < 0)
752  {
753  microsecond_diff= (-1 * microsecond_diff);
754  _seconds--;
755  }
756  _useconds= (uint32_t) microsecond_diff;
757 
758  return *this;
759 }
761 {
762  /*
763  * Figure out the new Julian Day Number by adding the JDNs of both
764  * dates together.
765  */
766  int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
767  int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
768  int64_t day_diff= day_left + day_right;
769 
772  /* Now re-compose the Date's structure from the ng Julian Day Number */
773  gregorian_date_from_julian_day_number(day_diff, &_years, &_months, &_days);
774 
775  /* And now handle the time components */
776  int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
777 
778  /*
779  * The resulting seconds might be more than a day. If do,
780  * adjust our ng days up 1.
781  */
782  if (second_diff >= DRIZZLE_SECONDS_IN_DAY)
783  {
784  _days++;
785  second_diff%= DRIZZLE_SECONDS_IN_DAY;
786  }
787 
788  _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
789  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
790  _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
791  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
792  _seconds= (uint32_t) second_diff;
793 
794  /* Handle the microsecond precision */
795  int64_t microsecond_diff= _useconds - rhs._useconds;
796  if (microsecond_diff < 0)
797  {
798  microsecond_diff= (-1 * microsecond_diff);
799  _seconds--;
800  }
801  _useconds= (uint32_t) microsecond_diff;
802 
803  return *this;
804 }
805 
806 /*
807  * Comparison operators between a Date and a Timestamp
808  */
809 bool Date::operator==(const Timestamp& rhs)
810 {
811  return (_years == rhs._years && _months == rhs._months && _days == rhs._days);
812 }
813 bool Date::operator!=(const Timestamp& rhs)
814 {
815  return ! (*this == rhs);
816 }
817 bool Date::operator<(const Timestamp& rhs)
818 {
819  if (_years < rhs._years)
820  return true;
821  if (_years > rhs._years)
822  return false;
823  /* In same year */
824  if (_months < rhs._months)
825  return true;
826  if (_months > rhs._months)
827  return false;
828  /* Same month */
829  return _days < rhs._days;
830 }
831 bool Date::operator<=(const Timestamp& rhs)
832 {
833  return (*this < rhs || *this == rhs);
834 }
835 bool Date::operator>(const Timestamp& rhs)
836 {
837  return ! (*this <= rhs);
838 }
839 bool Date::operator>=(const Timestamp& rhs)
840 {
841  return ! (*this < rhs);
842 }
843 /*
844  * Comparison operators between a Timestamp and a Date
845  */
846 bool Timestamp::operator==(const Date& rhs)
847 {
848  return (_years == rhs._years && _months == rhs._months && _days == rhs._days);
849 }
850 bool Timestamp::operator!=(const Date& rhs)
851 {
852  return ! (*this == rhs);
853 }
854 bool Timestamp::operator<(const Date& rhs)
855 {
856  if (_years < rhs._years)
857  return true;
858  if (_years > rhs._years)
859  return false;
860  /* In same year */
861  if (_months < rhs._months)
862  return true;
863  if (_months > rhs._months)
864  return false;
865  /* Same month */
866  return _days < rhs._days;
867 }
868 bool Timestamp::operator<=(const Date& rhs)
869 {
870  return (*this < rhs || *this == rhs);
871 }
872 bool Timestamp::operator>(const Date& rhs)
873 {
874  return ! (*this <= rhs);
875 }
876 bool Timestamp::operator>=(const Date& rhs)
877 {
878  return ! (*this < rhs);
879 }
880 /*
881  * Comparison operators between a Timestamp and a DateTime
882  */
884 {
885  return (_years == rhs._years && _months == rhs._months && _days == rhs._days
886  && _hours == rhs._hours && _minutes == rhs._minutes && _seconds == rhs._seconds);
887 }
888 bool Timestamp::operator!=(const DateTime& rhs)
889 {
890  return ! (*this == rhs);
891 }
892 bool Timestamp::operator<(const DateTime& rhs)
893 {
894  if (_years < rhs._years)
895  return true;
896  if (_years > rhs._years)
897  return false;
898  /* In same year */
899  if (_months < rhs._months)
900  return true;
901  if (_months > rhs._months)
902  return false;
903  /* Same month */
904  if (_days < rhs._days)
905  return true;
906  if (_days > rhs._days)
907  return false;
908  /* Same day */
909  if (_hours < rhs._hours)
910  return true;
911  if (_hours > rhs._hours)
912  return false;
913  /* Same hour */
914  if (_minutes < rhs._minutes)
915  return true;
916  if (_minutes > rhs._minutes)
917  return false;
918  /* Same minute */
919  return _seconds < rhs._seconds;
920 }
921 bool Timestamp::operator<=(const DateTime& rhs)
922 {
923  return (*this < rhs || *this == rhs);
924 }
925 bool Timestamp::operator>(const DateTime& rhs)
926 {
927  return ! (*this <= rhs);
928 }
929 bool Timestamp::operator>=(const DateTime& rhs)
930 {
931  return ! (*this < rhs);
932 }
933 /*
934  * Comparison operators between two Timestamps
935  */
937 {
938  return (_epoch_seconds == rhs._epoch_seconds);
939 }
940 bool Timestamp::operator!=(const Timestamp& rhs)
941 {
942  return ! (*this == rhs);
943 }
944 bool Timestamp::operator<(const Timestamp& rhs)
945 {
946  return (_epoch_seconds < rhs._epoch_seconds);
947 }
948 bool Timestamp::operator<=(const Timestamp& rhs)
949 {
950  return (_epoch_seconds <= rhs._epoch_seconds);
951 }
952 bool Timestamp::operator>(const Timestamp& rhs)
953 {
954  return ! (*this <= rhs);
955 }
956 bool Timestamp::operator>=(const Timestamp& rhs)
957 {
958  return ! (*this < rhs);
959 }
960 
968 std::ostream& operator<<(std::ostream& os, const Timestamp& subject)
969 {
970  return os << subject.years() << '-'
971  << std::setw(2) << std::setfill('0') << subject.months() << '-'
972  << std::setw(2) << std::setfill('0') << subject.days() << ' '
973  << std::setw(2) << std::setfill('0') << subject.hours() << ':'
974  << std::setw(2) << std::setfill('0') << subject.minutes() << ':'
975  << std::setw(2) << std::setfill('0') << subject.seconds();
976 }
977 
978 bool Time::from_string(const char *from, size_t from_len)
979 {
980  BOOST_FOREACH(TemporalFormat* it, known_time_formats)
981  {
982  if (not it->matches(from, from_len, this))
983  continue;
984  return is_fuzzy_valid();
985  }
986  return false;
987 }
988 
989 int Time::to_string(char *to, size_t to_len) const
990 {
991  return snprintf(to, to_len, "%02" PRIu32 ":%02" PRIu32 ":%02" PRIu32, _hours, _minutes, _seconds);
992 }
993 
994 int Date::to_string(char *to, size_t to_len) const
995 {
996  return snprintf(to, to_len, "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32, _years, _months, _days);
997 }
998 
999 int DateTime::to_string(char *to, size_t to_len) const
1000 {
1001  /* If the temporal has a microsecond component, use a slightly different output */
1002  if (_useconds == 0)
1003  {
1004  return snprintf(to, to_len,
1005  "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32 " %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32,
1006  _years, _months, _days, _hours, _minutes, _seconds);
1007  }
1008  else
1009  {
1010  return snprintf(to, to_len,
1011  "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32 " %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 ".%06" PRIu32,
1012  _years, _months, _days, _hours, _minutes, _seconds, _useconds);
1013  }
1014 }
1015 
1016 int MicroTimestamp::to_string(char *to, size_t to_len) const
1017 {
1018  return snprintf(to, to_len,
1019  "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32 " %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 ".%06" PRIu32,
1020  _years, _months, _days, _hours, _minutes, _seconds, _useconds);
1021 }
1022 
1024 {
1025  int64_t time_portion= (((_hours * 100L) + _minutes) * 100L) + _seconds;
1026  (void) int2_class_decimal(E_DEC_FATAL_ERROR, time_portion, false, to);
1027  if (_useconds > 0)
1028  {
1029  to->buf[(to->intg-1) / 9 + 1]= _useconds * 1000;
1030  to->frac= 6;
1031  }
1032 }
1033 
1035 {
1036  int64_t date_portion= (((_years * 100L) + _months) * 100L) + _days;
1037  (void) int2_class_decimal(E_DEC_FATAL_ERROR, date_portion, false, to);
1038 }
1039 
1041 {
1042  int64_t date_portion= (((_years * 100L) + _months) * 100L) + _days;
1043  int64_t time_portion= (((((date_portion * 100L) + _hours) * 100L) + _minutes) * 100L) + _seconds;
1044  (void) int2_class_decimal(E_DEC_FATAL_ERROR, time_portion, false, to);
1045  if (_useconds > 0)
1046  {
1047  to->buf[(to->intg-1) / 9 + 1]= _useconds * 1000;
1048  to->frac= 6;
1049  }
1050 }
1051 
1052 void Date::to_int64_t(int64_t *to) const
1053 {
1054  *to= (_years * INT32_C(10000)) + (_months * INT32_C(100)) + _days;
1055 }
1056 
1057 void Date::to_int32_t(int32_t *to) const
1058 {
1059  *to= (_years * INT32_C(10000)) + (_months * INT32_C(100)) + _days;
1060 }
1061 
1062 void Time::to_int32_t(int32_t *to) const
1063 {
1064  *to= (_hours * INT32_C(10000)) + (_minutes * INT32_C(100)) + _seconds;
1065 }
1066 
1067 // We fill the structure based on just int
1068 void Time::to_uint64_t(uint64_t &to) const
1069 {
1070  to= (_hours * 60 * 60) + (_minutes * 60) + _seconds;
1071 }
1072 
1073 void DateTime::to_int64_t(int64_t *to) const
1074 {
1075  *to= ((
1076  (_years * INT64_C(10000))
1077  + (_months * INT64_C(100))
1078  + _days
1079  ) * INT64_C(1000000))
1080  + (
1081  (_hours * INT64_C(10000))
1082  + (_minutes * INT64_C(100) )
1083  + _seconds
1084  );
1085 }
1086 
1087 void Date::to_tm(struct tm *to) const
1088 {
1089  to->tm_sec= 0;
1090  to->tm_min= 0;
1091  to->tm_hour= 0;
1092  to->tm_mday= _days; /* Drizzle format uses ordinal, standard tm does too! */
1093  to->tm_mon= _months - 1; /* Drizzle format uses ordinal, standard tm does NOT! */
1094  to->tm_year= _years - 1900;
1095 }
1096 
1097 void DateTime::to_tm(struct tm *to) const
1098 {
1099  to->tm_sec= _seconds;
1100  to->tm_min= _minutes;
1101  to->tm_hour= _hours;
1102  to->tm_mday= _days; /* Drizzle format uses ordinal, standard tm does too! */
1103  to->tm_mon= _months - 1; /* Drizzle format uses ordinal, standard tm does NOT! */
1104  to->tm_year= _years - 1900;
1105 }
1106 
1107 bool Date::from_julian_day_number(const int64_t from)
1108 {
1109  gregorian_date_from_julian_day_number(from, &_years, &_months, &_days);
1110  return is_valid();
1111 }
1112 
1113 void Date::to_julian_day_number(int64_t *to) const
1114 {
1115  *to= julian_day_number_from_gregorian_date(_years, _months, _days);
1116 }
1117 
1121 bool Date::from_int32_t(const int32_t from)
1122 {
1123  return ((DateTime *) this)->from_int64_t((int64_t) from);
1124 }
1125 
1130 bool Time::from_int32_t(const int32_t from)
1131 {
1132  uint32_t copy_from= (uint32_t) from;
1133  _hours= copy_from / INT32_C(10000);
1134  _minutes= (copy_from % INT32_C(10000)) / INT32_C(100);
1135  _seconds= copy_from % INT32_C(100); /* Masks off all but last 2 digits */
1136  return is_valid();
1137 }
1138 
1144 bool DateTime::from_int64_t(const int64_t from, bool convert)
1145 {
1146  int64_t copy_from= from;
1147  int64_t part1;
1148  int64_t part2;
1149 
1150  if (copy_from == 0LL)
1151  return false;
1152 
1153  if (convert && copy_from < 10000101000000LL)
1154  {
1155  if (copy_from < 101)
1156  return false;
1157  else if (copy_from <= (DRIZZLE_YY_PART_YEAR-1)*10000L+1231L)
1158  copy_from= (copy_from+20000000L)*1000000L; /* YYMMDD, year: 2000-2069 */
1159  else if (copy_from < (DRIZZLE_YY_PART_YEAR)*10000L+101L)
1160  return false;
1161  else if (copy_from <= 991231L)
1162  copy_from= (copy_from+19000000L)*1000000L; /* YYMMDD, year: 1970-1999 */
1163  else if (copy_from < 10000101L)
1164  return false;
1165  else if (copy_from <= 99991231L)
1166  copy_from= copy_from*1000000L;
1167  else if (copy_from < 101000000L)
1168  return false;
1169  else if (copy_from <= (DRIZZLE_YY_PART_YEAR-1) * 10000000000LL + 1231235959LL)
1170  copy_from= copy_from + 20000000000000LL; /* YYMMDDHHMMSS, 2000-2069 */
1171  else if (copy_from < DRIZZLE_YY_PART_YEAR * 10000000000LL + 101000000LL)
1172  return false;
1173  else if (copy_from <= 991231235959LL)
1174  copy_from= copy_from + 19000000000000LL; /* YYMMDDHHMMSS, 1970-1999 */
1175  }
1176 
1177  part1= (int64_t) (copy_from / 1000000LL);
1178  part2= (int64_t) (copy_from - (int64_t) part1 * 1000000LL);
1179  _years= (uint32_t) (part1/10000L);
1180 
1181  part1%=10000L;
1182  _months= (uint32_t) part1 / 100;
1183  _days= (uint32_t) part1 % 100;
1184  _hours= (uint32_t) (part2/10000L);
1185 
1186  part2%=10000L;
1187  _minutes= (uint32_t) part2 / 100;
1188  _seconds= (uint32_t) part2 % 100;
1189 
1191  return is_valid();
1192 }
1193 
1194 bool Date::in_unix_epoch() const
1195 {
1196  return in_unix_epoch_range(_years, _months, _days, 0, 0, 0);
1197 }
1198 
1200 {
1201  return in_unix_epoch_range(_years, _months, _days, _hours, _minutes, _seconds);
1202 }
1203 
1204 bool Date::from_tm(const struct tm *from)
1205 {
1206  _years= 1900 + from->tm_year;
1207  _months= 1 + from->tm_mon; /* Month is NOT ordinal for struct tm! */
1208  _days= from->tm_mday; /* Day IS ordinal for struct tm */
1209  _hours= from->tm_hour;
1210  _minutes= from->tm_min;
1211  _seconds= from->tm_sec;
1212  /* Set hires precision to zero */
1213  _useconds= 0;
1214  _nseconds= 0;
1215 
1217  return is_valid();
1218 }
1219 
1220 /*
1221  * We convert as if it's a Datetime, then simply
1222  * drop the date portions...
1223  */
1224 bool Time::from_time_t(const time_t from)
1225 {
1226  struct tm broken_time;
1227  struct tm *result;
1228 
1229  result= util::gmtime(from, &broken_time);
1230  if (result != NULL)
1231  {
1232  _years= 0;
1233  _months= 0;
1234  _days= 0;
1235  _hours= broken_time.tm_hour;
1236  _minutes= broken_time.tm_min;
1237  _seconds= broken_time.tm_sec;
1238  _epoch_seconds= 0; /* Don't store the time_t, since we only use part of it */
1239  /* Set hires precision to zero */
1240  _useconds= 0;
1241  _nseconds= 0;
1242  return true; /* Always true... */
1243  }
1244  else
1245  return false;
1246 }
1247 
1248 bool Date::from_time_t(const time_t from)
1249 {
1250  struct tm broken_time;
1251  struct tm *result;
1252 
1253  result= util::gmtime(from, &broken_time);
1254  if (result != NULL)
1255  {
1256  _years= 1900 + broken_time.tm_year;
1257  _months= 1 + broken_time.tm_mon; /* Month is NOT ordinal for struct tm! */
1258  _days= broken_time.tm_mday; /* Day IS ordinal for struct tm */
1259  _hours= 0;
1260  _minutes= 0;
1261  _seconds= 0;
1262  _epoch_seconds= 0; /* Don't store the time_t, since we only use part of it */
1263  /* Set hires precision to zero */
1264  _useconds= 0;
1265  _nseconds= 0;
1266  return is_valid();
1267  }
1268  else
1269  return false;
1270 }
1271 
1272 bool DateTime::from_timeval(struct timeval &timeval_arg)
1273 {
1274  struct tm broken_time;
1275  struct tm *result;
1276 
1277  result= util::gmtime(timeval_arg.tv_sec, &broken_time);
1278  if (result != NULL)
1279  {
1280  _years= 1900 + broken_time.tm_year;
1281  _months= 1 + broken_time.tm_mon; /* Month is NOT ordinal for struct tm! */
1282  _days= broken_time.tm_mday; /* Day IS ordinal for struct tm */
1283  _hours= broken_time.tm_hour;
1284  _minutes= broken_time.tm_min;
1285  _seconds= broken_time.tm_sec;
1286  _epoch_seconds= timeval_arg.tv_sec;
1287  /* Set hires precision to zero */
1288  _useconds= timeval_arg.tv_usec;
1289  _nseconds= 0;
1290  return is_valid();
1291  }
1292  else
1293  {
1294  return false;
1295  }
1296 }
1297 
1298 bool DateTime::from_time_t(const time_t from)
1299 {
1300  struct tm broken_time;
1301  struct tm *result;
1302 
1303  result= util::gmtime(from, &broken_time);
1304  if (result != NULL)
1305  {
1306  _years= 1900 + broken_time.tm_year;
1307  _months= 1 + broken_time.tm_mon; /* Month is NOT ordinal for struct tm! */
1308  _days= broken_time.tm_mday; /* Day IS ordinal for struct tm */
1309  _hours= broken_time.tm_hour;
1310  _minutes= broken_time.tm_min;
1311  _seconds= broken_time.tm_sec;
1312  _epoch_seconds= from;
1313  /* Set hires precision to zero */
1314  _useconds= 0;
1315  _nseconds= 0;
1316  return is_valid();
1317  }
1318  else
1319  {
1320  return false;
1321  }
1322 }
1323 
1324 void Date::to_time_t(time_t &to) const
1325 {
1326  if (in_unix_epoch())
1327  {
1328  to= _epoch_seconds;
1329  }
1330  else
1331  {
1332  to= 0;
1333  }
1334 }
1335 
1336 void Timestamp::to_time_t(time_t &to) const
1337 {
1338  to= _epoch_seconds;
1339 }
1340 
1341 void MicroTimestamp::to_timeval(struct timeval &to) const
1342 {
1343  to.tv_sec= _epoch_seconds;
1344  to.tv_usec= _useconds;
1345 }
1346 
1347 void NanoTimestamp::to_timespec(struct timespec *to) const
1348 {
1349  to->tv_sec= _epoch_seconds;
1350  to->tv_nsec= _nseconds;
1351 }
1352 
1353 bool Date::is_valid() const
1354 {
1355  return (_years >= DRIZZLE_MIN_YEARS_SQL && _years <= DRIZZLE_MAX_YEARS_SQL)
1356  && (_months >= 1 && _months <= DRIZZLE_MAX_MONTHS)
1357  && (_days >= 1 && _days <= days_in_gregorian_year_month(_years, _months));
1358 }
1359 
1360 bool Time::is_valid() const
1361 {
1362  return (_years == 0)
1363  && (_months == 0)
1364  && (_days == 0)
1365  && (_hours <= DRIZZLE_MAX_HOURS)
1366  && (_minutes <= DRIZZLE_MAX_MINUTES)
1367  && (_seconds <= DRIZZLE_MAX_SECONDS); /* No Leap second... TIME is for elapsed time... */
1368 }
1369 
1370 bool Time::is_fuzzy_valid() const
1371 {
1372  if (is_valid())
1373  return true;
1374 
1375  return (_years >= DRIZZLE_MIN_YEARS_SQL && _years <= DRIZZLE_MAX_YEARS_SQL)
1376  && (_months >= 1 && _months <= DRIZZLE_MAX_MONTHS)
1377  && (_days >= 1 && _days <= days_in_gregorian_year_month(_years, _months))
1378  && (_hours <= DRIZZLE_MAX_HOURS)
1379  && (_minutes <= DRIZZLE_MAX_MINUTES)
1380  && (_seconds <= DRIZZLE_MAX_SECONDS); /* No Leap second... TIME is for elapsed time... */
1381 }
1382 
1384 {
1385  return (_years >= DRIZZLE_MIN_YEARS_SQL && _years <= DRIZZLE_MAX_YEARS_SQL)
1386  && (_months >= 1 && _months <= DRIZZLE_MAX_MONTHS)
1387  && (_days >= 1 && _days <= days_in_gregorian_year_month(_years, _months))
1388  && (_hours <= DRIZZLE_MAX_HOURS)
1389  && (_minutes <= DRIZZLE_MAX_MINUTES)
1390  && (_seconds <= DRIZZLE_MAX_SECONDS_WITH_LEAP); /* Leap second... */
1391 }
1392 
1394 {
1395  return DateTime::is_valid()
1396  && in_unix_epoch_range(_years, _months, _days, _hours, _minutes, _seconds)
1397  && (_seconds <= DRIZZLE_MAX_SECONDS);
1398 }
1399 
1401 {
1402  return Timestamp::is_valid()
1403  && (_useconds <= UINT32_C(999999));
1404 }
1405 
1407 {
1408  return Timestamp::is_valid()
1409  && (_useconds <= UINT32_C(999999))
1410  && (_nseconds <= UINT32_C(999999999));
1411 }
1412 
1413 } /* namespace drizzled */