~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/temporal.cc

  • Committer: Stewart Smith
  • Date: 2009-02-16 04:19:00 UTC
  • mfrom: (869.2.6 dollhouse)
  • mto: This revision was merged to the branch mainline in revision 887.
  • Revision ID: stewart@flamingspork.com-20090216041900-idx8llj31btz5as3
merge unireg_type removal, mainline

Show diffs side-by-side

added added

removed removed

Lines of Context:
38
38
 
39
39
#include "mystrings/m_ctype.h"
40
40
#include "drizzled/my_decimal.h"
 
41
#include "drizzled/calendar.h"
41
42
#include "drizzled/temporal.h"
 
43
#ifdef NOTYETIMPLEMENTED
 
44
#include "drizzled/temporal_interval.h"
 
45
#endif
42
46
#include "drizzled/temporal_format.h"
43
47
 
44
48
#include <vector>
45
49
#include <string.h>
46
50
 
 
51
/* time.h may already have been included in global.h, but we
 
52
   need to pick up the extra defs as well, after the global time.h */
 
53
#ifndef HAVE_DECL_TIMEGM
 
54
# include <gnulib/time.h>
 
55
#endif
 
56
 
47
57
extern std::vector<drizzled::TemporalFormat *> known_datetime_formats;
48
58
extern std::vector<drizzled::TemporalFormat *> known_date_formats;
49
59
extern std::vector<drizzled::TemporalFormat *> known_time_formats;
63
73
, _epoch_seconds(0)
64
74
, _useconds(0)
65
75
, _nseconds(0)
 
76
, _overflow(false)
66
77
{}
67
78
 
68
79
uint64_t Temporal::_cumulative_seconds_in_time() const
215
226
  Time result;
216
227
 
217
228
  int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
218
 
  result._hours= second_diff % DRIZZLE_SECONDS_IN_HOUR;
219
 
  second_diff-= (result._hours * DRIZZLE_SECONDS_IN_HOUR);
220
 
  result._minutes= second_diff % DRIZZLE_SECONDS_IN_MINUTE;
221
 
  second_diff-= (result._minutes * DRIZZLE_SECONDS_IN_MINUTE);
222
 
  result._seconds= second_diff;
 
229
  result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
 
230
  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
 
231
  result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
 
232
  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
 
233
  result._seconds= (uint32_t) second_diff;
223
234
  
224
235
  return result;
225
236
}
227
238
{
228
239
  Time result;
229
240
  int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
230
 
  result._hours= second_diff % DRIZZLE_SECONDS_IN_HOUR;
231
 
  second_diff-= (result._hours * DRIZZLE_SECONDS_IN_HOUR);
232
 
  result._minutes= second_diff % DRIZZLE_SECONDS_IN_MINUTE;
233
 
  second_diff-= (result._minutes * DRIZZLE_SECONDS_IN_MINUTE);
234
 
  result._seconds= second_diff;
 
241
  result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
 
242
  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
 
243
  result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
 
244
  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
 
245
  result._seconds= (uint32_t) second_diff;
235
246
  /** 
236
247
   * @TODO Once exceptions are supported, we should raise an error here if
237
248
   *       the result Time is not valid?
246
257
Time& Time::operator+=(const Time& rhs)
247
258
{
248
259
  int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
249
 
  _hours= second_diff % DRIZZLE_SECONDS_IN_HOUR;
250
 
  second_diff-= (_hours * DRIZZLE_SECONDS_IN_HOUR);
251
 
  _minutes= second_diff % DRIZZLE_SECONDS_IN_MINUTE;
252
 
  second_diff-= (_minutes * DRIZZLE_SECONDS_IN_MINUTE);
253
 
  _seconds= second_diff;
 
260
  _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
 
261
  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
 
262
  _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
 
263
  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
 
264
  _seconds= (uint32_t) second_diff;
254
265
  /** 
255
266
   * @TODO Once exceptions are supported, we should raise an error here if
256
267
   *       the result Time is not valid?
260
271
Time& Time::operator-=(const Time& rhs)
261
272
{
262
273
  int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
263
 
  _hours= second_diff % DRIZZLE_SECONDS_IN_HOUR;
264
 
  second_diff-= (_hours * DRIZZLE_SECONDS_IN_HOUR);
265
 
  _minutes= second_diff % DRIZZLE_SECONDS_IN_MINUTE;
266
 
  second_diff-= (_minutes * DRIZZLE_SECONDS_IN_MINUTE);
267
 
  _seconds= second_diff;
 
274
  _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
 
275
  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
 
276
  _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
 
277
  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
 
278
  _seconds= (uint32_t) second_diff;
268
279
  /** 
269
280
   * @TODO Once exceptions are supported, we should raise an error here if
270
281
   *       the result Time is not valid?
291
302
}
292
303
bool Date::operator<(const Date& rhs)
293
304
{
294
 
  int days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
295
 
  int days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
 
305
  int64_t days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
 
306
  int64_t days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
296
307
  return (days_left < days_right);
297
308
}
298
309
bool Date::operator<=(const Date& rhs)
299
310
{
300
 
  int days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
301
 
  int days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
 
311
  int64_t days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
 
312
  int64_t days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
302
313
  return (days_left <= days_right);
303
314
}
304
315
bool Date::operator>(const Date& rhs)
334
345
}
335
346
bool DateTime::operator<(const DateTime& rhs)
336
347
{
337
 
  int days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
338
 
  int days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
 
348
  int64_t days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
 
349
  int64_t days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
339
350
  if (days_left < days_right)
340
351
    return true;
341
352
  else if (days_left > days_right)
345
356
}
346
357
bool DateTime::operator<=(const DateTime& rhs)
347
358
{
348
 
  int days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
349
 
  int days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
 
359
  int64_t days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
 
360
  int64_t days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
350
361
  if (days_left < days_right)
351
362
    return true;
352
363
  else if (days_left > days_right)
394
405
  if (second_diff < 0)
395
406
    result._days--;
396
407
 
397
 
  result._hours= second_diff % DRIZZLE_SECONDS_IN_HOUR;
398
 
  second_diff-= (result._hours * DRIZZLE_SECONDS_IN_HOUR);
399
 
  result._minutes= second_diff % DRIZZLE_SECONDS_IN_MINUTE;
400
 
  second_diff-= (result._minutes * DRIZZLE_SECONDS_IN_MINUTE);
401
 
  result._seconds= second_diff;
 
408
  result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
 
409
  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
 
410
  result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
 
411
  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
 
412
  result._seconds= (uint32_t) second_diff;
402
413
 
403
414
  /* Handle the microsecond precision */
404
415
  int64_t microsecond_diff= _useconds - rhs._useconds;
407
418
    microsecond_diff= (-1 * microsecond_diff);
408
419
    result._seconds--;
409
420
  }
410
 
  result._useconds= microsecond_diff;
 
421
  result._useconds= (uint32_t) microsecond_diff;
411
422
 
412
423
  return result;
413
424
}
433
444
  if (second_diff >= DRIZZLE_SECONDS_IN_DAY)
434
445
  {
435
446
    result._days++;
436
 
    second_diff-= (result._days * DRIZZLE_SECONDS_IN_DAY);
 
447
    second_diff%= DRIZZLE_SECONDS_IN_DAY;
437
448
  }
438
449
 
439
 
  result._hours= second_diff % DRIZZLE_SECONDS_IN_HOUR;
440
 
  second_diff-= (result._hours * DRIZZLE_SECONDS_IN_HOUR);
441
 
  result._minutes= second_diff % DRIZZLE_SECONDS_IN_MINUTE;
442
 
  second_diff-= (result._minutes * DRIZZLE_SECONDS_IN_MINUTE);
443
 
  result._seconds= second_diff;
 
450
  result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
 
451
  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
 
452
  result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
 
453
  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
 
454
  result._seconds= (uint32_t) second_diff;
444
455
 
445
456
  /* Handle the microsecond precision */
446
457
  int64_t microsecond_diff= _useconds - rhs._useconds;
449
460
    microsecond_diff= (-1 * microsecond_diff);
450
461
    result._seconds--;
451
462
  }
452
 
  result._useconds= microsecond_diff;
 
463
  result._useconds= (uint32_t) microsecond_diff;
453
464
 
454
465
  return result;
455
466
}
468
479
  if (second_diff >= DRIZZLE_SECONDS_IN_DAY)
469
480
  {
470
481
    _days++;
471
 
    second_diff-= (_days * DRIZZLE_SECONDS_IN_DAY);
 
482
    second_diff%= DRIZZLE_SECONDS_IN_DAY;
472
483
  }
473
484
 
474
 
  _hours= second_diff % DRIZZLE_SECONDS_IN_HOUR;
475
 
  second_diff-= (_hours * DRIZZLE_SECONDS_IN_HOUR);
476
 
  _minutes= second_diff % DRIZZLE_SECONDS_IN_MINUTE;
477
 
  second_diff-= (_minutes * DRIZZLE_SECONDS_IN_MINUTE);
478
 
  _seconds= second_diff;
 
485
  _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
 
486
  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
 
487
  _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
 
488
  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
 
489
  _seconds= (uint32_t) second_diff;
479
490
 
480
491
  /* Handle the microsecond precision */
481
492
  int64_t microsecond_diff= _useconds - rhs._useconds;
484
495
    microsecond_diff= (-1 * microsecond_diff);
485
496
    _seconds--;
486
497
  }
487
 
  _useconds= microsecond_diff;
 
498
  _useconds= (uint32_t) microsecond_diff;
488
499
  /** 
489
500
   * @TODO Once exceptions are supported, we should raise an error here if
490
501
   *       the result Time is not valid?
508
519
  if (second_diff < 0)
509
520
    _days--;
510
521
 
511
 
  _hours= second_diff % DRIZZLE_SECONDS_IN_HOUR;
512
 
  second_diff-= (_hours * DRIZZLE_SECONDS_IN_HOUR);
513
 
  _minutes= second_diff % DRIZZLE_SECONDS_IN_MINUTE;
514
 
  second_diff-= (_minutes * DRIZZLE_SECONDS_IN_MINUTE);
515
 
  _seconds= second_diff;
 
522
  _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
 
523
  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
 
524
  _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
 
525
  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
 
526
  _seconds= (uint32_t) second_diff;
516
527
 
517
528
  /* Handle the microsecond precision */
518
529
  int64_t microsecond_diff= _useconds - rhs._useconds;
521
532
    microsecond_diff= (-1 * microsecond_diff);
522
533
    _seconds--;
523
534
  }
524
 
  _useconds= microsecond_diff;
 
535
  _useconds= (uint32_t) microsecond_diff;
525
536
  /** 
526
537
   * @TODO Once exceptions are supported, we should raise an error here if
527
538
   *       the result Time is not valid?
590
601
  return *this;
591
602
}
592
603
 
 
604
Date& Date::operator=(const DateTime &rhs)
 
605
{
 
606
  /* Only copy the Date components of the assigned DateTime... */
 
607
  _years= rhs._years;
 
608
  _months= rhs._months;
 
609
  _days= rhs._days;
 
610
  /* Zero-out everything else.. */
 
611
  _hours= _minutes= _seconds= _useconds= _nseconds= 0;
 
612
  return *this;
 
613
}
 
614
 
593
615
/**
594
616
 * We can add/subtract two DateTimes to/from each other.  The result
595
617
 * is always another DateTime instance.
621
643
  if (second_diff < 0)
622
644
    _days--;
623
645
 
624
 
  result._hours= second_diff % DRIZZLE_SECONDS_IN_HOUR;
625
 
  second_diff-= (result._hours * DRIZZLE_SECONDS_IN_HOUR);
626
 
  result._minutes= second_diff % DRIZZLE_SECONDS_IN_MINUTE;
627
 
  second_diff-= (result._minutes * DRIZZLE_SECONDS_IN_MINUTE);
628
 
  result._seconds= second_diff;
 
646
  result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
 
647
  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
 
648
  result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
 
649
  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
 
650
  result._seconds= (uint32_t) second_diff;
629
651
 
630
652
  /* Handle the microsecond precision */
631
653
  int64_t microsecond_diff= _useconds - rhs._useconds;
634
656
    microsecond_diff= (-1 * microsecond_diff);
635
657
    result._seconds--;
636
658
  }
637
 
  result._useconds= microsecond_diff;
 
659
  result._useconds= (uint32_t) microsecond_diff;
638
660
 
639
661
  return result;
640
662
}
664
686
  if (second_diff >= DRIZZLE_SECONDS_IN_DAY)
665
687
  {
666
688
    result._days++;
667
 
    second_diff-= (result._days * DRIZZLE_SECONDS_IN_DAY);
 
689
    second_diff%= DRIZZLE_SECONDS_IN_DAY;
668
690
  }
669
691
 
670
 
  result._hours= second_diff % DRIZZLE_SECONDS_IN_HOUR;
671
 
  second_diff-= (result._hours * DRIZZLE_SECONDS_IN_HOUR);
672
 
  result._minutes= second_diff % DRIZZLE_SECONDS_IN_MINUTE;
673
 
  second_diff-= (result._minutes * DRIZZLE_SECONDS_IN_MINUTE);
674
 
  result._seconds= second_diff;
 
692
  result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
 
693
  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
 
694
  result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
 
695
  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
 
696
  result._seconds= (uint32_t) second_diff;
675
697
 
676
698
  /* Handle the microsecond precision */
677
699
  int64_t microsecond_diff= _useconds - rhs._useconds;
680
702
    microsecond_diff= (-1 * microsecond_diff);
681
703
    result._seconds--;
682
704
  }
683
 
  result._useconds= microsecond_diff;
 
705
  result._useconds= (uint32_t) microsecond_diff;
684
706
 
685
707
  return result;
686
708
}
711
733
  if (second_diff < 0)
712
734
    _days--;
713
735
 
714
 
  _hours= second_diff % DRIZZLE_SECONDS_IN_HOUR;
715
 
  second_diff-= (_hours * DRIZZLE_SECONDS_IN_HOUR);
716
 
  _minutes= second_diff % DRIZZLE_SECONDS_IN_MINUTE;
717
 
  second_diff-= (_minutes * DRIZZLE_SECONDS_IN_MINUTE);
718
 
  _seconds= second_diff;
 
736
  _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
 
737
  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
 
738
  _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
 
739
  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
 
740
  _seconds= (uint32_t) second_diff;
719
741
 
720
742
  /* Handle the microsecond precision */
721
743
  int64_t microsecond_diff= _useconds - rhs._useconds;
724
746
    microsecond_diff= (-1 * microsecond_diff);
725
747
    _seconds--;
726
748
  }
727
 
  _useconds= microsecond_diff;
 
749
  _useconds= (uint32_t) microsecond_diff;
728
750
 
729
751
  return *this;
730
752
}
753
775
  if (second_diff >= DRIZZLE_SECONDS_IN_DAY)
754
776
  {
755
777
    _days++;
756
 
    second_diff-= (_days * DRIZZLE_SECONDS_IN_DAY);
 
778
    second_diff%= DRIZZLE_SECONDS_IN_DAY;
757
779
  }
758
780
 
759
 
  _hours= second_diff % DRIZZLE_SECONDS_IN_HOUR;
760
 
  second_diff-= (_hours * DRIZZLE_SECONDS_IN_HOUR);
761
 
  _minutes= second_diff % DRIZZLE_SECONDS_IN_MINUTE;
762
 
  second_diff-= (_minutes * DRIZZLE_SECONDS_IN_MINUTE);
763
 
  _seconds= second_diff;
 
781
  _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
 
782
  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
 
783
  _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
 
784
  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
 
785
  _seconds= (uint32_t) second_diff;
764
786
 
765
787
  /* Handle the microsecond precision */
766
788
  int64_t microsecond_diff= _useconds - rhs._useconds;
769
791
    microsecond_diff= (-1 * microsecond_diff);
770
792
    _seconds--;
771
793
  }
772
 
  _useconds= microsecond_diff;
773
 
 
774
 
  return *this;
775
 
}
776
 
 
 
794
  _useconds= (uint32_t) microsecond_diff;
 
795
 
 
796
  return *this;
 
797
}
 
798
#ifdef NOTYETIMPLEMENTED
 
799
DateTime& DateTime::operator+=(const TemporalIntervalYear &rhs)
 
800
{
 
801
  /* Simple one...add the years and adjust for any leaps */
 
802
  int64_t new_years= _years;
 
803
  new_years+= rhs._years;
 
804
  if (new_years > DRIZZLE_MAX_YEARS_SQL)
 
805
  {
 
806
    /* 
 
807
     * Set everything to zero. We got an overflow.
 
808
     * @TODO Exceptions would be great here...
 
809
     */
 
810
    _reset();
 
811
    _overflow= true;
 
812
    return *this;
 
813
  }
 
814
  _years= (uint32_t) new_years;
 
815
  if (_months == 2 && _days == 29 && days_in_gregorian_year_month(_years, _months) != 366)
 
816
    _days= 28;
 
817
  return *this;
 
818
 
819
 
 
820
DateTime& DateTime::operator-=(const TemporalIntervalYear &rhs)
 
821
{
 
822
  /* Simple one...subtract the years and adjust for any leaps */
 
823
  int64_t new_years= _years;
 
824
  new_years-= rhs._years;
 
825
  if (new_years < 0)
 
826
  {
 
827
    /* 
 
828
     * Set everything to zero. We got an overflow.
 
829
     * @TODO Exceptions would be great here...
 
830
     */
 
831
    _reset();
 
832
    _overflow= true;
 
833
    return *this;
 
834
  }
 
835
  _years= (uint32_t) new_years;
 
836
  if (_months == 2 && _days == 29 && days_in_gregorian_year_month(_years, _months) != 366)
 
837
    _days= 28;
 
838
  return *this;
 
839
 
840
 
 
841
DateTime& DateTime::operator+=(const TemporalIntervalDayOrWeek &rhs)
 
842
{
 
843
  /* Simple one...add the days */
 
844
  int64_t julian_day= julian_day_number_from_gregorian_date(_years, _months, _days) + rhs._days;
 
845
  gregorian_date_from_julian_day_number(julian_day, &_years, &_months, &_days);
 
846
  return *this;
 
847
 
848
 
 
849
DateTime& DateTime::operator-=(const TemporalIntervalDayOrWeek &rhs)
 
850
{
 
851
  /* Simple one...subtract the days */
 
852
  int64_t julian_day= julian_day_number_from_gregorian_date(_years, _months, _days) - rhs._days;
 
853
  gregorian_date_from_julian_day_number(julian_day, &_years, &_months, &_days);
 
854
  return *this;
 
855
 
856
 
 
857
DateTime& DateTime::operator+=(const TemporalIntervalYearMonth &rhs)
 
858
{
 
859
  /* Simple one...add the months in the period adjust */
 
860
  int64_t period= (_years * 12) + (rhs._years * 12) + (_months - 1) + rhs._months;
 
861
  int64_t new_years= (period / 12);
 
862
  if (new_years > DRIZZLE_MAX_YEARS_SQL)
 
863
  {
 
864
    /* 
 
865
     * Set everything to zero. We got an overflow.
 
866
     * @TODO Exceptions would be great here...
 
867
     */
 
868
    _reset();
 
869
    _overflow= true;
 
870
    return *this;
 
871
  }
 
872
  _years= (uint32_t) new_years;
 
873
  _months= (uint32_t) (period % 12) + 1;
 
874
  
 
875
  /* Adjust day if the new month doesn't have enough days */
 
876
  uint32_t days_in_new_month= days_in_gregorian_year_month(_years, _months);
 
877
  if (_days > days_in_new_month)
 
878
    _days= days_in_new_month;
 
879
  return *this;
 
880
 
881
 
 
882
DateTime& DateTime::operator-=(const TemporalIntervalYearMonth &rhs)
 
883
{
 
884
  /* Simple one...subtract the months in the period and adjust */
 
885
  int64_t period= (_years * 12) - (rhs._years * 12) + (_months - 1) - rhs._months;
 
886
  int64_t new_years= (period / 12);
 
887
  if (new_years < 0)
 
888
  {
 
889
    /* 
 
890
     * Set everything to zero. We got an overflow.
 
891
     * @TODO Exceptions would be great here...
 
892
     */
 
893
    _reset();
 
894
    _overflow= true;
 
895
    return *this;
 
896
  }
 
897
  _years= (uint32_t) (period / 12);
 
898
  _months= (uint32_t) (period % 12) + 1;
 
899
  
 
900
  /* Adjust day if the new month doesn't have enough days */
 
901
  uint32_t days_in_new_month= days_in_gregorian_year_month(_years, _months);
 
902
  if (_days > days_in_new_month)
 
903
    _days= days_in_new_month;
 
904
  return *this;
 
905
 
906
 
 
907
DateTime& DateTime::operator+=(const TemporalIntervalDayOrLess &rhs)
 
908
{
 
909
  /* 
 
910
   * Convert the temporal and the interval into a number of 
 
911
   * microseconds, then add them together and convert the
 
912
   * resulting microseconds back into a broken-down temporal
 
913
   * component.
 
914
   */
 
915
  int64_t new_seconds;
 
916
  int64_t new_microseconds;
 
917
  int64_t extra_sec;
 
918
  int64_t new_days;
 
919
  new_microseconds= _useconds + rhs._useconds;
 
920
  extra_sec= new_microseconds / INT64_C(1000000);
 
921
  new_microseconds= new_microseconds % INT64_C(1000000);
 
922
 
 
923
  new_seconds= ((_days - 1) * 3600 * 24) + (_hours * 3600) + (_minutes * 60) + _seconds;
 
924
  new_seconds+= (rhs._days * 3600 * 24) + (rhs._hours * 3600) + (rhs._minutes * 60) + rhs._seconds;
 
925
  new_seconds+= extra_sec;
 
926
 
 
927
  if (new_microseconds < 0)
 
928
  {
 
929
    new_microseconds+= INT64_C(1000000);
 
930
    new_seconds--;
 
931
  }
 
932
  
 
933
  new_days= new_seconds / (3600 * 24L);
 
934
  new_seconds-= new_days * 3600 * 24L;
 
935
  if (new_seconds < 0)
 
936
  {
 
937
    new_days--;
 
938
    new_seconds+= 3600 * 24L;
 
939
  }
 
940
  _useconds= (uint32_t) new_microseconds;
 
941
  _seconds= (uint32_t) (new_seconds % 60);
 
942
  _minutes= (uint32_t) ((new_seconds / 60) % 60);
 
943
  _hours= (uint32_t) (new_seconds / 3600);
 
944
  int64_t julian_day= julian_day_number_from_gregorian_date(_years, _months, 1) + new_days;
 
945
  gregorian_date_from_julian_day_number(julian_day, &_years, &_months, &_days);
 
946
  return *this;
 
947
}
 
948
 
 
949
DateTime& DateTime::operator-=(const TemporalIntervalDayOrLess &rhs)
 
950
{
 
951
  /* 
 
952
   * Convert the temporal and the interval into a number of 
 
953
   * microseconds, then subtract them from each other and convert 
 
954
   * the resulting microseconds back into a broken-down temporal
 
955
   * component.
 
956
   */
 
957
  int64_t new_seconds;
 
958
  int64_t new_microseconds;
 
959
  int64_t extra_sec;
 
960
  int64_t new_days;
 
961
  new_microseconds= _useconds - rhs._useconds;
 
962
  extra_sec= new_microseconds / INT64_C(1000000);
 
963
  new_microseconds= new_microseconds % INT64_C(1000000);
 
964
 
 
965
  new_seconds= ((_days - 1) * 3600 * 24) + (_hours * 3600) + (_minutes * 60) + _seconds;
 
966
  new_seconds-= (rhs._days * 3600 * 24) + (rhs._hours * 3600) + (rhs._minutes * 60) + rhs._seconds;
 
967
  new_seconds+= extra_sec;
 
968
 
 
969
  if (new_microseconds < 0)
 
970
  {
 
971
    new_microseconds+= INT64_C(1000000);
 
972
    new_seconds--;
 
973
  }
 
974
  
 
975
  new_days= new_seconds / (3600 * 24L);
 
976
  new_seconds-= new_days * 3600 * 24L;
 
977
  if (new_seconds < 0)
 
978
  {
 
979
    new_days--;
 
980
    new_seconds+= 3600 * 24L;
 
981
  }
 
982
  _useconds= (uint32_t) new_microseconds;
 
983
  _seconds= (uint32_t) (new_seconds % 60);
 
984
  _minutes= (uint32_t) ((new_seconds / 60) % 60);
 
985
  _hours= (uint32_t) (new_seconds / 3600);
 
986
  int64_t julian_day= julian_day_number_from_gregorian_date(_years, _months, 1) + new_days;
 
987
  gregorian_date_from_julian_day_number(julian_day, &_years, &_months, &_days);
 
988
  return *this;
 
989
}
 
990
#endif /* NOTYETIMPLEMENTED */
777
991
/*
778
992
 * Comparison operators between two Timestamps
779
993
 */
802
1016
  return ! (*this <= rhs);
803
1017
}
804
1018
 
805
 
 
806
1019
bool Time::from_string(const char *from, size_t from_len)
807
1020
{
808
1021
  /* 
850
1063
 
851
1064
void DateTime::to_string(char *to, size_t *to_len) const
852
1065
{
853
 
  *to_len= sprintf(to
854
 
                 , "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32 " %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32
855
 
                 , _years
856
 
                 , _months
857
 
                 , _days
858
 
                 , _hours
859
 
                 , _minutes
860
 
                 , _seconds);
 
1066
  /* If the temporal has a microsecond component, use a slightly different output */
 
1067
  if (_useconds == 0)
 
1068
  {
 
1069
    *to_len= sprintf(to
 
1070
                  , "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32 " %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32
 
1071
                  , _years
 
1072
                  , _months
 
1073
                  , _days
 
1074
                  , _hours
 
1075
                  , _minutes
 
1076
                  , _seconds);
 
1077
  }
 
1078
  else
 
1079
  {
 
1080
    *to_len= sprintf(to
 
1081
                  , "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32 " %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 ".%06" PRIu32
 
1082
                  , _years
 
1083
                  , _months
 
1084
                  , _days
 
1085
                  , _hours
 
1086
                  , _minutes
 
1087
                  , _seconds
 
1088
                  , _useconds);
 
1089
  }
861
1090
}
862
1091
 
863
1092
void MicroTimestamp::to_string(char *to, size_t *to_len) const
957
1186
  to->tm_year= _years - 1900;
958
1187
}
959
1188
 
960
 
/**
961
 
 * We assume that the supplied integer is an
962
 
 * absolute day number (for instance, from the FROM_DAYS()
963
 
 * SQL function.
964
 
 */
965
1189
bool Date::from_julian_day_number(const int64_t from)
966
1190
{
967
 
  /* 
968
 
   * First convert the absolute day number into a Julian
969
 
   * Day Number and then run a standard conversion on the
970
 
   * JDN.
971
 
   */
972
1191
  gregorian_date_from_julian_day_number(from, &_years, &_months, &_days);
973
1192
  return is_valid();
974
1193
}
975
1194
 
 
1195
void Date::to_julian_day_number(int64_t *to) const
 
1196
{
 
1197
  *to= julian_day_number_from_gregorian_date(_years, _months, _days);
 
1198
}
 
1199
 
976
1200
/**
977
1201
 * Ignore overflow and pass-through to DateTime::from_int64_t()
978
1202
 */
987
1211
 */
988
1212
bool Time::from_int32_t(const int32_t from)
989
1213
{
990
 
  int32_t copy_from= from;
 
1214
  uint32_t copy_from= (uint32_t) from;
991
1215
  _hours= copy_from % INT32_C(10000);
992
1216
  _minutes= copy_from % INT32_C(100);
993
1217
  _seconds= copy_from & 3; /* Masks off all but last 2 digits */
1005
1229
  int64_t part1;
1006
1230
  int64_t part2;
1007
1231
 
1008
 
  if (! (copy_from == 0LL || copy_from >= 10000101000000LL))
 
1232
  if (copy_from == 0LL)
 
1233
    return false;
 
1234
 
 
1235
  if (copy_from < 10000101000000LL)
1009
1236
  {
1010
1237
    if (copy_from < 101)
1011
1238
      return false;
1012
 
    if (copy_from <= (DRIZZLE_YY_PART_YEAR-1)*10000L+1231L)
 
1239
    else if (copy_from <= (DRIZZLE_YY_PART_YEAR-1)*10000L+1231L)
1013
1240
      copy_from= (copy_from+20000000L)*1000000L;                 /* YYMMDD, year: 2000-2069 */
1014
 
    if (copy_from < (DRIZZLE_YY_PART_YEAR)*10000L+101L)
 
1241
    else if (copy_from < (DRIZZLE_YY_PART_YEAR)*10000L+101L)
1015
1242
      return false;
1016
 
    if (copy_from <= 991231L)
 
1243
    else if (copy_from <= 991231L)
1017
1244
      copy_from= (copy_from+19000000L)*1000000L;                 /* YYMMDD, year: 1970-1999 */
1018
 
    if (copy_from < 10000101L)
 
1245
    else if (copy_from < 10000101L)
1019
1246
      return false;
1020
 
    if (copy_from <= 99991231L)
 
1247
    else if (copy_from <= 99991231L)
1021
1248
      copy_from= copy_from*1000000L;
1022
 
    if (copy_from < 101000000L)
 
1249
    else if (copy_from < 101000000L)
1023
1250
      return false;
1024
 
    if (copy_from <= (DRIZZLE_YY_PART_YEAR-1) * 10000000000LL + 1231235959LL)
 
1251
    else if (copy_from <= (DRIZZLE_YY_PART_YEAR-1) * 10000000000LL + 1231235959LL)
1025
1252
      copy_from= copy_from + 20000000000000LL;                   /* YYMMDDHHMMSS, 2000-2069 */
1026
 
    if (copy_from <  DRIZZLE_YY_PART_YEAR * 10000000000LL + 101000000LL)
 
1253
    else if (copy_from <  DRIZZLE_YY_PART_YEAR * 10000000000LL + 101000000LL)
1027
1254
      return false;
1028
 
    if (copy_from <= 991231235959LL)
 
1255
    else if (copy_from <= 991231235959LL)
1029
1256
      copy_from= copy_from + 19000000000000LL;          /* YYMMDDHHMMSS, 1970-1999 */
1030
1257
  }
1031
1258
 
1072
1299
  return is_valid();
1073
1300
}
1074
1301
 
 
1302
/* 
 
1303
 * We convert as if it's a Datetime, then simply
 
1304
 * drop the date portions...
 
1305
 */
 
1306
bool Time::from_time_t(const time_t from)
 
1307
{
 
1308
  struct tm broken_time;
 
1309
  struct tm *result;
 
1310
 
 
1311
  result= gmtime_r(&from, &broken_time);
 
1312
  if (result != NULL)
 
1313
  {
 
1314
    _years= 0;
 
1315
    _months= 0;
 
1316
    _days= 0;
 
1317
    _hours= broken_time.tm_hour;
 
1318
    _minutes= broken_time.tm_min;
 
1319
    _seconds= broken_time.tm_sec;
 
1320
    _epoch_seconds= 0; /* Don't store the time_t, since we only use part of it */
 
1321
    /* Set hires precision to zero */
 
1322
    _useconds= 0;
 
1323
    _nseconds= 0;
 
1324
    return true; /* Always true... */
 
1325
  }
 
1326
  else 
 
1327
    return false;
 
1328
}
 
1329
 
1075
1330
bool Date::from_time_t(const time_t from)
1076
1331
{
1077
1332
  struct tm broken_time;
1086
1341
    _hours= 0;
1087
1342
    _minutes= 0;
1088
1343
    _seconds= 0;
1089
 
    _epoch_seconds= 0;
 
1344
    _epoch_seconds= 0; /* Don't store the time_t, since we only use part of it */
1090
1345
    /* Set hires precision to zero */
1091
1346
    _useconds= 0;
1092
1347
    _nseconds= 0;