~drizzle-trunk/drizzle/development

813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
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
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
25
/**
26
 * @file 
27
 *
28
 * Implementation of the server's temporal class API
29
 *
30
 * @todo
31
 *
32
 * Move to completed ValueObject API, which would remove the from_xxx() methods
33
 * and replace them with constructors which take other ValueObject instances as
34
 * their single parameter.
35
 */
36
813.1.12 by Jay Pipes
Fixes for SECOND() function to use new Temporal system. Because
37
#include "drizzled/global.h"
38
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
39
#include "mystrings/m_ctype.h"
40
#include "drizzled/my_decimal.h"
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
41
#include "drizzled/calendar.h"
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
42
#include "drizzled/temporal.h"
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
43
#ifdef NOTYETIMPLEMENTED
44
#include "drizzled/temporal_interval.h"
45
#endif
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
46
#include "drizzled/temporal_format.h"
992.1.1 by Monty Taylor
Merged solaris gcc build fixes.
47
#include "time.h"
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
48
907.1.7 by Jay Pipes
Merged in remove-timezone work
49
#include <ostream>
50
#include <iomanip>
779.4.3 by Monty Taylor
Fixed include order compile thing.
51
#include <vector>
52
#include <string.h>
53
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
54
extern std::vector<drizzled::TemporalFormat *> known_datetime_formats;
55
extern std::vector<drizzled::TemporalFormat *> known_date_formats;
56
extern std::vector<drizzled::TemporalFormat *> known_time_formats;
57
58
namespace drizzled 
59
{
60
61
Temporal::Temporal()
62
:
63
  _calendar(GREGORIAN)
64
, _years(0)
65
, _months(0)
66
, _days(0)
67
, _hours(0)
68
, _minutes(0)
69
, _seconds(0)
70
, _epoch_seconds(0)
71
, _useconds(0)
72
, _nseconds(0)
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
73
, _overflow(false)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
74
{}
75
76
uint64_t Temporal::_cumulative_seconds_in_time() const
77
{
78
  return (uint64_t) ((_hours * INT64_C(3600)) 
79
      + (_minutes * INT64_C(60)) 
80
      + _seconds);
81
}
82
83
void Temporal::set_epoch_seconds()
84
{
85
  /* 
86
   * If the temporal is in the range of a timestamp, set 
87
   * the epoch_seconds member variable
88
   */
89
  if (in_unix_epoch_range(_years, _months, _days, _hours, _minutes, _seconds))
90
  {
91
    time_t result_time;
92
    struct tm broken_time;
93
94
    broken_time.tm_sec= _seconds;
95
    broken_time.tm_min= _minutes;
96
    broken_time.tm_hour= _hours;
97
    broken_time.tm_mday= _days; /* Drizzle format uses ordinal, standard tm does too! */
98
    broken_time.tm_mon= _months - 1; /* Drizzle format uses ordinal, standard tm does NOT! */
99
    broken_time.tm_year= _years - 1900; /* tm_year expects range of 70 - 38 */
100
101
    result_time= timegm(&broken_time);
102
103
    _epoch_seconds= result_time;
104
  }
105
}
106
107
bool Date::from_string(const char *from, size_t from_len)
108
{
109
  /* 
110
   * Loop through the known date formats and see if 
111
   * there is a match.
112
   */
113
  bool matched= false;
114
  TemporalFormat *current_format;
115
  std::vector<TemporalFormat *>::iterator current= known_date_formats.begin();
116
117
  while (current != known_date_formats.end())
118
  {
119
    current_format= *current;
120
    if (current_format->matches(from, from_len, this))
121
    {
122
      matched= true;
123
      break;
124
    }
125
    current++;
126
  }
127
128
  if (! matched)
129
    return false;
130
131
  set_epoch_seconds();
132
  return is_valid();
133
}
134
135
bool DateTime::from_string(const char *from, size_t from_len)
136
{
137
  /* 
138
   * Loop through the known datetime formats and see if 
139
   * there is a match.
140
   */
141
  bool matched= false;
142
  TemporalFormat *current_format;
143
  std::vector<TemporalFormat *>::iterator current= known_datetime_formats.begin();
144
145
  while (current != known_datetime_formats.end())
146
  {
147
    current_format= *current;
148
    if (current_format->matches(from, from_len, this))
149
    {
150
      matched= true;
151
      break;
152
    }
153
    current++;
154
  }
155
156
  if (! matched)
157
    return false;
158
159
  set_epoch_seconds();
160
  return is_valid();
161
}
162
163
/*
164
 * Comparison operators for Time against another Time
165
 * are easy.  We simply compare the cumulative time
166
 * value of each.
167
 */
168
bool Time::operator==(const Time& rhs)
169
{
170
  return (
171
          _hours == rhs._hours
172
       && _minutes == rhs._minutes
173
       && _seconds == rhs._seconds
174
       && _useconds == rhs._useconds
175
       && _nseconds == rhs._nseconds
176
      );
177
}
178
bool Time::operator!=(const Time& rhs)
179
{
180
  return ! (*this == rhs);
181
}
182
bool Time::operator<(const Time& rhs)
183
{
184
  return (_cumulative_seconds_in_time() < rhs._cumulative_seconds_in_time());
185
}
186
bool Time::operator<=(const Time& rhs)
187
{
188
  return (_cumulative_seconds_in_time() <= rhs._cumulative_seconds_in_time());
189
}
190
bool Time::operator>(const Time& rhs)
191
{
192
  return (_cumulative_seconds_in_time() > rhs._cumulative_seconds_in_time());
193
}
194
bool Time::operator>=(const Time& rhs)
195
{
196
  return (_cumulative_seconds_in_time() >= rhs._cumulative_seconds_in_time());
197
}
198
199
/** 
200
 * Subtracting one Time value from another can yield
201
 * a new Time instance.
202
 *
203
 * This operator is called in the following situation:
204
 *
205
 * @code
206
 * drizzled::Time lhs;
207
 * lhs.from_string("20:00:00");
208
 * drizzled::Time rhs;
209
 * rhs.from_string("19:00:00");
210
 *
211
 * drizzled::Time result= lhs - rhs;
212
 * @endcode
213
 *
214
 * @note
215
 *
216
 * Subtracting a larger time value from a smaller one
217
 * should throw an exception at some point.  The result
218
 * of such an operator should be a TemporalInterval, not
219
 * a Time instance, since a negative time is not possible.
220
 */
221
const Time Time::operator-(const Time& rhs)
222
{
223
  Time result;
224
225
  int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
226
  result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
227
  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
228
  result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
229
  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
230
  result._seconds= (uint32_t) second_diff;
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
231
  
232
  return result;
233
}
234
const Time Time::operator+(const Time& rhs)
235
{
236
  Time result;
237
  int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
238
  result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
239
  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
240
  result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
241
  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
242
  result._seconds= (uint32_t) second_diff;
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
243
  /** 
244
   * @TODO Once exceptions are supported, we should raise an error here if
245
   *       the result Time is not valid?
246
   */
247
  return result;
248
}
249
250
/*
251
 * Variation of + and - operator which returns a reference to the left-hand
252
 * side Time object and adds the right-hand side to itself.
253
 */
254
Time& Time::operator+=(const Time& rhs)
255
{
256
  int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
257
  _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
258
  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
259
  _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
260
  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
261
  _seconds= (uint32_t) second_diff;
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
262
  /** 
263
   * @TODO Once exceptions are supported, we should raise an error here if
264
   *       the result Time is not valid?
265
   */
266
  return *this;
267
}
268
Time& Time::operator-=(const Time& rhs)
269
{
270
  int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
271
  _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
272
  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
273
  _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
274
  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
275
  _seconds= (uint32_t) second_diff;
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
276
  /** 
277
   * @TODO Once exceptions are supported, we should raise an error here if
278
   *       the result Time is not valid?
279
   */
280
  return *this;
281
}
282
283
/*
284
 * Comparison operators for Date against another Date
285
 * are easy.  We simply compare the cumulative
286
 * value of each.
287
 */
288
bool Date::operator==(const Date& rhs)
289
{
290
  return (
291
          _years == rhs._years
292
       && _months == rhs._months
293
       && _days == rhs._days
294
      );
295
}
296
bool Date::operator!=(const Date& rhs)
297
{
298
  return ! (*this == rhs);
299
}
300
bool Date::operator<(const Date& rhs)
301
{
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
302
  int64_t days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
303
  int64_t days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
304
  return (days_left < days_right);
305
}
306
bool Date::operator<=(const Date& rhs)
307
{
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
308
  int64_t days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
309
  int64_t days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
310
  return (days_left <= days_right);
311
}
312
bool Date::operator>(const Date& rhs)
313
{
314
  return ! (*this <= rhs);
315
}
316
bool Date::operator>=(const Date& rhs)
317
{
318
  return ! (*this < rhs);
319
}
320
321
/*
322
 * Comparison operators for DateTime against another DateTime
323
 * are easy.  We simply compare the cumulative time
324
 * value of each.
325
 */
892.2.9 by Monty Taylor
Raped Jay's code.
326
bool Date::operator==(const DateTime& rhs)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
327
{
328
  return (
329
          _years == rhs._years
330
       && _months == rhs._months
331
       && _days == rhs._days
332
       && _hours == rhs._hours
333
       && _minutes == rhs._minutes
334
       && _seconds == rhs._seconds
335
       && _useconds == rhs._useconds
336
       && _nseconds == rhs._nseconds
337
      );
338
}
892.2.9 by Monty Taylor
Raped Jay's code.
339
bool Date::operator!=(const DateTime& rhs)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
340
{
341
  return ! (*this == rhs);
342
}
892.2.9 by Monty Taylor
Raped Jay's code.
343
bool Date::operator<(const DateTime& rhs)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
344
{
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
345
  int64_t days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
346
  int64_t days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
347
  if (days_left < days_right)
348
    return true;
349
  else if (days_left > days_right)
350
    return false;
351
  /* Here if both dates are the same, so compare times */
352
  return (_cumulative_seconds_in_time() < rhs._cumulative_seconds_in_time());
353
}
892.2.9 by Monty Taylor
Raped Jay's code.
354
bool Date::operator<=(const DateTime& rhs)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
355
{
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
356
  int64_t days_left= julian_day_number_from_gregorian_date(_years, _months, _days);
357
  int64_t days_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
358
  if (days_left < days_right)
359
    return true;
360
  else if (days_left > days_right)
361
    return false;
362
  /* Here if both dates are the same, so compare times */
363
  return (_cumulative_seconds_in_time() <= rhs._cumulative_seconds_in_time());
364
}
892.2.9 by Monty Taylor
Raped Jay's code.
365
bool Date::operator>(const DateTime& rhs)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
366
{
367
  return ! (*this <= rhs);
368
}
892.2.9 by Monty Taylor
Raped Jay's code.
369
bool Date::operator>=(const DateTime& rhs)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
370
{
371
  return ! (*this < rhs);
372
}
373
374
/** 
375
 * We can add or subtract a Time value to/from a DateTime value 
376
 * as well...it always produces a DateTime.
377
 */
892.2.10 by Monty Taylor
More raping of Jay's code.
378
const Date Date::operator-(const Time& rhs)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
379
{
380
  DateTime result;
381
382
  /* 
383
   * First, we set the resulting DATE pieces equal to our 
384
   * left-hand side DateTime's DATE components. Then, deal with 
385
   * the time components.
386
   */
387
  result._years= _years;
388
  result._months= _months;
389
  result._days= _days;
390
391
  int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
392
393
  /* 
394
   * The resulting diff might be negative.  If it is, that means that 
395
   * we have subtracting a larger time piece from the datetime, like so:
396
   *
397
   * x = DateTime("2007-06-09 09:30:00") - Time("16:30:00");
398
   *
399
   * In these cases, we need to subtract a day from the resulting
400
   * DateTime.
401
   */
402
  if (second_diff < 0)
403
    result._days--;
404
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
405
  result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
406
  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
407
  result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
408
  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
409
  result._seconds= (uint32_t) second_diff;
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
410
411
  /* Handle the microsecond precision */
412
  int64_t microsecond_diff= _useconds - rhs._useconds;
413
  if (microsecond_diff < 0)
414
  {
415
    microsecond_diff= (-1 * microsecond_diff);
416
    result._seconds--;
417
  }
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
418
  result._useconds= (uint32_t) microsecond_diff;
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
419
420
  return result;
421
}
892.2.10 by Monty Taylor
More raping of Jay's code.
422
const Date Date::operator+(const Time& rhs)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
423
{
424
  DateTime result;
425
426
  /* 
427
   * First, we set the resulting DATE pieces equal to our 
428
   * left-hand side DateTime's DATE components. Then, deal with 
429
   * the time components.
430
   */
431
  result._years= _years;
432
  result._months= _months;
433
  result._days= _days;
434
435
  int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
436
437
  /* 
438
   * The resulting seconds might be more than a day.  If do, 
439
   * adjust our resulting days up 1.
440
   */
441
  if (second_diff >= DRIZZLE_SECONDS_IN_DAY)
442
  {
443
    result._days++;
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
444
    second_diff%= DRIZZLE_SECONDS_IN_DAY;
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
445
  }
446
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
447
  result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
448
  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
449
  result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
450
  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
451
  result._seconds= (uint32_t) second_diff;
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
452
453
  /* Handle the microsecond precision */
454
  int64_t microsecond_diff= _useconds - rhs._useconds;
455
  if (microsecond_diff < 0)
456
  {
457
    microsecond_diff= (-1 * microsecond_diff);
458
    result._seconds--;
459
  }
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
460
  result._useconds= (uint32_t) microsecond_diff;
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
461
462
  return result;
463
}
464
465
/*
466
 * Variation of + and - operator which returns a reference to the left-hand
467
 * side DateTime object and adds the right-hand side Time to itself.
468
 */
892.2.10 by Monty Taylor
More raping of Jay's code.
469
Date& Date::operator+=(const Time& rhs)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
470
{
471
  int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
472
  /* 
473
   * The resulting seconds might be more than a day.  If do, 
474
   * adjust our resulting days up 1.
475
   */
476
  if (second_diff >= DRIZZLE_SECONDS_IN_DAY)
477
  {
478
    _days++;
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
479
    second_diff%= DRIZZLE_SECONDS_IN_DAY;
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
480
  }
481
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
482
  _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
483
  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
484
  _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
485
  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
486
  _seconds= (uint32_t) second_diff;
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
487
488
  /* Handle the microsecond precision */
489
  int64_t microsecond_diff= _useconds - rhs._useconds;
490
  if (microsecond_diff < 0)
491
  {
492
    microsecond_diff= (-1 * microsecond_diff);
493
    _seconds--;
494
  }
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
495
  _useconds= (uint32_t) microsecond_diff;
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
496
  /** 
497
   * @TODO Once exceptions are supported, we should raise an error here if
498
   *       the result Time is not valid?
499
   */
500
  return *this;
501
}
892.2.10 by Monty Taylor
More raping of Jay's code.
502
Date& Date::operator-=(const Time& rhs)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
503
{
504
  int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
505
506
  /* 
507
   * The resulting diff might be negative.  If it is, that means that 
508
   * we have subtracting a larger time piece from the datetime, like so:
509
   *
510
   * x = DateTime("2007-06-09 09:30:00");
511
   * x-= Time("16:30:00");
512
   *
513
   * In these cases, we need to subtract a day from the resulting
514
   * DateTime.
515
   */
516
  if (second_diff < 0)
517
    _days--;
518
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
519
  _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
520
  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
521
  _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
522
  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
523
  _seconds= (uint32_t) second_diff;
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
524
525
  /* Handle the microsecond precision */
526
  int64_t microsecond_diff= _useconds - rhs._useconds;
527
  if (microsecond_diff < 0)
528
  {
529
    microsecond_diff= (-1 * microsecond_diff);
530
    _seconds--;
531
  }
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
532
  _useconds= (uint32_t) microsecond_diff;
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
533
  /** 
534
   * @TODO Once exceptions are supported, we should raise an error here if
535
   *       the result Time is not valid?
536
   */
537
  return *this;
538
}
539
540
/**
541
 * We can add/subtract two Dates to/from each other.  The result
542
 * is always another Date instance.
543
 */
544
const Date Date::operator-(const Date &rhs)
545
{
546
  /* Figure out the difference in days between the two dates */
547
  int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
548
  int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
549
  int64_t day_diff= day_left - day_right;
550
551
  Date result;
552
  /* Now re-compose the Date's structure from the resulting Julian Day Number */
553
  gregorian_date_from_julian_day_number(day_diff, &result._years, &result._months, &result._days);
554
  return result;
555
}
556
const Date Date::operator+(const Date &rhs)
557
{
558
  /* 
559
   * Figure out the new Julian Day Number by adding the JDNs of both
560
   * dates together.
561
   */
562
  int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
563
  int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
564
  int64_t day_diff= day_left + day_right;
565
566
  /** @TODO Need an exception check here for bounds of JDN... */
567
568
  Date result;
569
  /* Now re-compose the Date's structure from the resulting Julian Day Number */
570
  gregorian_date_from_julian_day_number(day_diff, &result._years, &result._months, &result._days);
571
  return result;
572
}
573
/* Similar to the above, but we add/subtract the right side to this object itself */
574
Date& Date::operator-=(const Date &rhs)
575
{
576
  int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
577
  int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
578
  int64_t day_diff= day_left - day_right;
579
580
  /* Now re-compose the Date's structure from the resulting Julian Day Number */
581
  gregorian_date_from_julian_day_number(day_diff, &_years, &_months, &_days);
582
  return *this;
583
}
584
Date& Date::operator+=(const Date &rhs)
585
{
586
  /* 
587
   * Figure out the new Julian Day Number by adding the JDNs of both
588
   * dates together.
589
   */
590
  int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
591
  int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
592
  int64_t day_diff= day_left + day_right;
593
594
  /** @TODO Need an exception check here for bounds of JDN... */
595
596
  /* Now re-compose the Date's structure from the resulting Julian Day Number */
597
  gregorian_date_from_julian_day_number(day_diff, &_years, &_months, &_days);
598
  return *this;
599
}
600
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
601
Date& Date::operator=(const DateTime &rhs)
602
{
603
  /* Only copy the Date components of the assigned DateTime... */
604
  _years= rhs._years;
605
  _months= rhs._months;
606
  _days= rhs._days;
607
  /* Zero-out everything else.. */
608
  _hours= _minutes= _seconds= _useconds= _nseconds= 0;
609
  return *this;
610
}
611
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
612
/**
613
 * We can add/subtract two DateTimes to/from each other.  The result
614
 * is always another DateTime instance.
615
 */
892.2.9 by Monty Taylor
Raped Jay's code.
616
const Date Date::operator-(const DateTime &rhs)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
617
{
618
  /* Figure out the difference in days between the two dates. */
619
  int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
620
  int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
621
  int64_t day_diff= day_left - day_right;
622
623
  DateTime result;
624
  /* Now re-compose the Date's structure from the resulting Julian Day Number */
625
  gregorian_date_from_julian_day_number(day_diff, &result._years, &result._months, &result._days);
626
627
  /* And now handle the time components */
628
  int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
629
630
  /* 
631
   * The resulting diff might be negative.  If it is, that means that 
632
   * we have subtracting a larger time piece from the datetime, like so:
633
   *
634
   * x = DateTime("2007-06-09 09:30:00");
635
   * x-= Time("16:30:00");
636
   *
637
   * In these cases, we need to subtract a day from the resulting
638
   * DateTime.
639
   */
640
  if (second_diff < 0)
641
    _days--;
642
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
643
  result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
644
  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
645
  result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
646
  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
647
  result._seconds= (uint32_t) second_diff;
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
648
649
  /* Handle the microsecond precision */
650
  int64_t microsecond_diff= _useconds - rhs._useconds;
651
  if (microsecond_diff < 0)
652
  {
653
    microsecond_diff= (-1 * microsecond_diff);
654
    result._seconds--;
655
  }
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
656
  result._useconds= (uint32_t) microsecond_diff;
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
657
658
  return result;
659
}
892.2.9 by Monty Taylor
Raped Jay's code.
660
const Date Date::operator+(const DateTime &rhs)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
661
{
892.2.9 by Monty Taylor
Raped Jay's code.
662
  /*
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
663
   * Figure out the new Julian Day Number by adding the JDNs of both
664
   * dates together.
665
   */
666
  int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
667
  int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
668
  int64_t day_diff= day_left + day_right;
669
670
  /** @TODO Need an exception check here for bounds of JDN... */
671
672
  DateTime result;
673
  /* Now re-compose the Date's structure from the resulting Julian Day Number */
674
  gregorian_date_from_julian_day_number(day_diff, &result._years, &result._months, &result._days);
675
676
  /* And now handle the time components */
677
  int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
678
679
  /* 
680
   * The resulting seconds might be more than a day.  If do, 
681
   * adjust our resulting days up 1.
682
   */
683
  if (second_diff >= DRIZZLE_SECONDS_IN_DAY)
684
  {
685
    result._days++;
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
686
    second_diff%= DRIZZLE_SECONDS_IN_DAY;
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
687
  }
688
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
689
  result._hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
690
  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
691
  result._minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
692
  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
693
  result._seconds= (uint32_t) second_diff;
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
694
695
  /* Handle the microsecond precision */
696
  int64_t microsecond_diff= _useconds - rhs._useconds;
697
  if (microsecond_diff < 0)
698
  {
699
    microsecond_diff= (-1 * microsecond_diff);
700
    result._seconds--;
701
  }
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
702
  result._useconds= (uint32_t) microsecond_diff;
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
703
704
  return result;
705
}
706
/* Similar to the above, but we add/subtract the right side to this object itself */
892.2.9 by Monty Taylor
Raped Jay's code.
707
Date& Date::operator-=(const DateTime &rhs)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
708
{
709
  /* Figure out the difference in days between the two dates.  */
710
  int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
711
  int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
712
  int64_t day_diff= day_left - day_right;
713
714
  /* Now re-compose the Date's structure from the ng Julian Day Number */
715
  gregorian_date_from_julian_day_number(day_diff, &_years, &_months, &_days);
716
717
  /* And now handle the time components */
718
  int64_t second_diff= _cumulative_seconds_in_time() - rhs._cumulative_seconds_in_time();
719
720
  /* 
721
   * The resulting diff might be negative.  If it is, that means that 
722
   * we have subtracting a larger time piece from the datetime, like so:
723
   *
724
   * x = DateTime("2007-06-09 09:30:00");
725
   * x-= Time("16:30:00");
726
   *
727
   * In these cases, we need to subtract a day from the ng
728
   * DateTime.
729
   */
730
  if (second_diff < 0)
731
    _days--;
732
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
733
  _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
734
  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
735
  _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
736
  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
737
  _seconds= (uint32_t) second_diff;
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
738
739
  /* Handle the microsecond precision */
740
  int64_t microsecond_diff= _useconds - rhs._useconds;
741
  if (microsecond_diff < 0)
742
  {
743
    microsecond_diff= (-1 * microsecond_diff);
744
    _seconds--;
745
  }
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
746
  _useconds= (uint32_t) microsecond_diff;
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
747
748
  return *this;
749
}
892.2.9 by Monty Taylor
Raped Jay's code.
750
Date& Date::operator+=(const DateTime &rhs)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
751
{
752
  /* 
753
   * Figure out the new Julian Day Number by adding the JDNs of both
754
   * dates together.
755
   */
756
  int64_t day_left= julian_day_number_from_gregorian_date(_years, _months, _days);
757
  int64_t day_right= julian_day_number_from_gregorian_date(rhs._years, rhs._months, rhs._days);
758
  int64_t day_diff= day_left + day_right;
759
760
  /** @TODO Need an exception check here for bounds of JDN... */
761
762
  /* Now re-compose the Date's structure from the ng Julian Day Number */
763
  gregorian_date_from_julian_day_number(day_diff, &_years, &_months, &_days);
764
765
  /* And now handle the time components */
766
  int64_t second_diff= _cumulative_seconds_in_time() + rhs._cumulative_seconds_in_time();
767
768
  /* 
769
   * The resulting seconds might be more than a day.  If do, 
770
   * adjust our ng days up 1.
771
   */
772
  if (second_diff >= DRIZZLE_SECONDS_IN_DAY)
773
  {
774
    _days++;
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
775
    second_diff%= DRIZZLE_SECONDS_IN_DAY;
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
776
  }
777
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
778
  _hours= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_HOUR;
779
  second_diff%= DRIZZLE_SECONDS_IN_HOUR;
780
  _minutes= (uint32_t) second_diff / DRIZZLE_SECONDS_IN_MINUTE;
781
  second_diff%= DRIZZLE_SECONDS_IN_MINUTE;
782
  _seconds= (uint32_t) second_diff;
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
783
784
  /* Handle the microsecond precision */
785
  int64_t microsecond_diff= _useconds - rhs._useconds;
786
  if (microsecond_diff < 0)
787
  {
788
    microsecond_diff= (-1 * microsecond_diff);
789
    _seconds--;
790
  }
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
791
  _useconds= (uint32_t) microsecond_diff;
792
793
  return *this;
794
}
795
#ifdef NOTYETIMPLEMENTED
892.2.11 by Monty Taylor
One more temporal hack.
796
Date& Date::operator+=(const TemporalIntervalYear &rhs)
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
797
{
798
  /* Simple one...add the years and adjust for any leaps */
799
  int64_t new_years= _years;
800
  new_years+= rhs._years;
801
  if (new_years > DRIZZLE_MAX_YEARS_SQL)
802
  {
803
    /* 
804
     * Set everything to zero. We got an overflow.
805
     * @TODO Exceptions would be great here...
806
     */
807
    _reset();
808
    _overflow= true;
809
    return *this;
810
  }
811
  _years= (uint32_t) new_years;
812
  if (_months == 2 && _days == 29 && days_in_gregorian_year_month(_years, _months) != 366)
813
    _days= 28;
814
  return *this;
815
} 
816
892.2.11 by Monty Taylor
One more temporal hack.
817
Date& Date::operator-=(const TemporalIntervalYear &rhs)
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
818
{
819
  /* Simple one...subtract the years and adjust for any leaps */
820
  int64_t new_years= _years;
821
  new_years-= rhs._years;
822
  if (new_years < 0)
823
  {
824
    /* 
825
     * Set everything to zero. We got an overflow.
826
     * @TODO Exceptions would be great here...
827
     */
828
    _reset();
829
    _overflow= true;
830
    return *this;
831
  }
832
  _years= (uint32_t) new_years;
833
  if (_months == 2 && _days == 29 && days_in_gregorian_year_month(_years, _months) != 366)
834
    _days= 28;
835
  return *this;
836
} 
837
892.2.11 by Monty Taylor
One more temporal hack.
838
Date& Date::operator+=(const TemporalIntervalDayOrWeek &rhs)
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
839
{
840
  /* Simple one...add the days */
841
  int64_t julian_day= julian_day_number_from_gregorian_date(_years, _months, _days) + rhs._days;
842
  gregorian_date_from_julian_day_number(julian_day, &_years, &_months, &_days);
843
  return *this;
844
} 
845
892.2.11 by Monty Taylor
One more temporal hack.
846
Date& Date::operator-=(const TemporalIntervalDayOrWeek &rhs)
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
847
{
848
  /* Simple one...subtract the days */
849
  int64_t julian_day= julian_day_number_from_gregorian_date(_years, _months, _days) - rhs._days;
850
  gregorian_date_from_julian_day_number(julian_day, &_years, &_months, &_days);
851
  return *this;
852
} 
853
892.2.11 by Monty Taylor
One more temporal hack.
854
Date& Date::operator+=(const TemporalIntervalYearMonth &rhs)
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
855
{
856
  /* Simple one...add the months in the period adjust */
857
  int64_t period= (_years * 12) + (rhs._years * 12) + (_months - 1) + rhs._months;
858
  int64_t new_years= (period / 12);
859
  if (new_years > DRIZZLE_MAX_YEARS_SQL)
860
  {
861
    /* 
862
     * Set everything to zero. We got an overflow.
863
     * @TODO Exceptions would be great here...
864
     */
865
    _reset();
866
    _overflow= true;
867
    return *this;
868
  }
869
  _years= (uint32_t) new_years;
870
  _months= (uint32_t) (period % 12) + 1;
871
  
872
  /* Adjust day if the new month doesn't have enough days */
873
  uint32_t days_in_new_month= days_in_gregorian_year_month(_years, _months);
874
  if (_days > days_in_new_month)
875
    _days= days_in_new_month;
876
  return *this;
877
} 
878
892.2.11 by Monty Taylor
One more temporal hack.
879
Date& Date::operator-=(const TemporalIntervalYearMonth &rhs)
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
880
{
881
  /* Simple one...subtract the months in the period and adjust */
882
  int64_t period= (_years * 12) - (rhs._years * 12) + (_months - 1) - rhs._months;
883
  int64_t new_years= (period / 12);
884
  if (new_years < 0)
885
  {
886
    /* 
887
     * Set everything to zero. We got an overflow.
888
     * @TODO Exceptions would be great here...
889
     */
890
    _reset();
891
    _overflow= true;
892
    return *this;
893
  }
894
  _years= (uint32_t) (period / 12);
895
  _months= (uint32_t) (period % 12) + 1;
896
  
897
  /* Adjust day if the new month doesn't have enough days */
898
  uint32_t days_in_new_month= days_in_gregorian_year_month(_years, _months);
899
  if (_days > days_in_new_month)
900
    _days= days_in_new_month;
901
  return *this;
902
} 
903
892.2.11 by Monty Taylor
One more temporal hack.
904
Date& Date::operator+=(const TemporalIntervalDayOrLess &rhs)
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
905
{
906
  /* 
907
   * Convert the temporal and the interval into a number of 
908
   * microseconds, then add them together and convert the
909
   * resulting microseconds back into a broken-down temporal
910
   * component.
911
   */
912
  int64_t new_seconds;
913
  int64_t new_microseconds;
914
  int64_t extra_sec;
915
  int64_t new_days;
916
  new_microseconds= _useconds + rhs._useconds;
917
  extra_sec= new_microseconds / INT64_C(1000000);
918
  new_microseconds= new_microseconds % INT64_C(1000000);
919
920
  new_seconds= ((_days - 1) * 3600 * 24) + (_hours * 3600) + (_minutes * 60) + _seconds;
921
  new_seconds+= (rhs._days * 3600 * 24) + (rhs._hours * 3600) + (rhs._minutes * 60) + rhs._seconds;
922
  new_seconds+= extra_sec;
923
924
  if (new_microseconds < 0)
925
  {
926
    new_microseconds+= INT64_C(1000000);
927
    new_seconds--;
928
  }
929
  
930
  new_days= new_seconds / (3600 * 24L);
931
  new_seconds-= new_days * 3600 * 24L;
932
  if (new_seconds < 0)
933
  {
934
    new_days--;
935
    new_seconds+= 3600 * 24L;
936
  }
937
  _useconds= (uint32_t) new_microseconds;
938
  _seconds= (uint32_t) (new_seconds % 60);
939
  _minutes= (uint32_t) ((new_seconds / 60) % 60);
940
  _hours= (uint32_t) (new_seconds / 3600);
941
  int64_t julian_day= julian_day_number_from_gregorian_date(_years, _months, 1) + new_days;
942
  gregorian_date_from_julian_day_number(julian_day, &_years, &_months, &_days);
943
  return *this;
944
}
945
892.2.11 by Monty Taylor
One more temporal hack.
946
Date& Date::operator-=(const TemporalIntervalDayOrLess &rhs)
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
947
{
948
  /* 
949
   * Convert the temporal and the interval into a number of 
950
   * microseconds, then subtract them from each other and convert 
951
   * the resulting microseconds back into a broken-down temporal
952
   * component.
953
   */
954
  int64_t new_seconds;
955
  int64_t new_microseconds;
956
  int64_t extra_sec;
957
  int64_t new_days;
958
  new_microseconds= _useconds - rhs._useconds;
959
  extra_sec= new_microseconds / INT64_C(1000000);
960
  new_microseconds= new_microseconds % INT64_C(1000000);
961
962
  new_seconds= ((_days - 1) * 3600 * 24) + (_hours * 3600) + (_minutes * 60) + _seconds;
963
  new_seconds-= (rhs._days * 3600 * 24) + (rhs._hours * 3600) + (rhs._minutes * 60) + rhs._seconds;
964
  new_seconds+= extra_sec;
965
966
  if (new_microseconds < 0)
967
  {
968
    new_microseconds+= INT64_C(1000000);
969
    new_seconds--;
970
  }
971
  
972
  new_days= new_seconds / (3600 * 24L);
973
  new_seconds-= new_days * 3600 * 24L;
974
  if (new_seconds < 0)
975
  {
976
    new_days--;
977
    new_seconds+= 3600 * 24L;
978
  }
979
  _useconds= (uint32_t) new_microseconds;
980
  _seconds= (uint32_t) (new_seconds % 60);
981
  _minutes= (uint32_t) ((new_seconds / 60) % 60);
982
  _hours= (uint32_t) (new_seconds / 3600);
983
  int64_t julian_day= julian_day_number_from_gregorian_date(_years, _months, 1) + new_days;
984
  gregorian_date_from_julian_day_number(julian_day, &_years, &_months, &_days);
985
  return *this;
986
}
987
#endif /* NOTYETIMPLEMENTED */
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
988
/*
910.2.10 by Monty Taylor
Merged in jay's patch again.
989
 * Comparison operators between a Date and a Timestamp
990
 */
991
bool Date::operator==(const Timestamp& rhs)
992
{
993
  return (_years == rhs._years && _months == rhs._months && _days == rhs._days);
994
}
995
bool Date::operator!=(const Timestamp& rhs)
996
{
997
  return ! (*this == rhs);
998
}
999
bool Date::operator<(const Timestamp& rhs)
1000
{
1001
  if (_years < rhs._years)
1002
    return true;
1003
  if (_years > rhs._years)
1004
    return false;
1005
  /* In same year */
1006
  if (_months < rhs._months)
1007
    return true;
1008
  if (_months > rhs._months)
1009
    return false;
1010
  /* Same month */
1011
  return _days < rhs._days;
1012
}
1013
bool Date::operator<=(const Timestamp& rhs)
1014
{
1015
  return (*this < rhs || *this == rhs);
1016
}
1017
bool Date::operator>(const Timestamp& rhs)
1018
{
1019
  return ! (*this < rhs);
1020
}
1021
bool Date::operator>=(const Timestamp& rhs)
1022
{
1023
  return ! (*this <= rhs);
1024
}
1025
/*
1026
 * Comparison operators between a Timestamp and a Date
1027
 */
1028
bool Timestamp::operator==(const Date& rhs)
1029
{
1030
  return (_years == rhs._years && _months == rhs._months && _days == rhs._days);
1031
}
1032
bool Timestamp::operator!=(const Date& rhs)
1033
{
1034
  return ! (*this == rhs);
1035
}
1036
bool Timestamp::operator<(const Date& rhs)
1037
{
1038
  if (_years < rhs._years)
1039
    return true;
1040
  if (_years > rhs._years)
1041
    return false;
1042
  /* In same year */
1043
  if (_months < rhs._months)
1044
    return true;
1045
  if (_months > rhs._months)
1046
    return false;
1047
  /* Same month */
1048
  return _days < rhs._days;
1049
}
1050
bool Timestamp::operator<=(const Date& rhs)
1051
{
1052
  return (*this < rhs || *this == rhs);
1053
}
1054
bool Timestamp::operator>(const Date& rhs)
1055
{
1056
  return ! (*this < rhs);
1057
}
1058
bool Timestamp::operator>=(const Date& rhs)
1059
{
1060
  return ! (*this <= rhs);
1061
}
1062
/*
1063
 * Comparison operators between a Timestamp and a DateTime
1064
 */
1065
bool Timestamp::operator==(const DateTime& rhs)
1066
{
1067
  return (_years == rhs._years && _months == rhs._months && _days == rhs._days
1068
          && _hours == rhs._hours && _minutes == rhs._minutes && _seconds == rhs._seconds);
1069
}
1070
bool Timestamp::operator!=(const DateTime& rhs)
1071
{
1072
  return ! (*this == rhs);
1073
}
1074
bool Timestamp::operator<(const DateTime& rhs)
1075
{
1076
  if (_years < rhs._years)
1077
    return true;
1078
  if (_years > rhs._years)
1079
    return false;
1080
  /* In same year */
1081
  if (_months < rhs._months)
1082
    return true;
1083
  if (_months > rhs._months)
1084
    return false;
1085
  /* Same month */
1086
  if (_days < rhs._days)
1087
    return true;
1088
  if (_days > rhs._days)
1089
     return false;
1090
  /* Same day */
1091
  if (_hours < rhs._hours)
1092
    return true;
1093
  if (_hours > rhs._hours)
1094
    return false;
1095
  /* Same hour */
1096
  if (_minutes < rhs._minutes)
1097
    return true;
1098
  if (_minutes > rhs._minutes)
1099
    return false;
1100
  /* Same minute */
1101
  return _seconds < rhs._seconds;
1102
}
1103
bool Timestamp::operator<=(const DateTime& rhs)
1104
{
1105
  return (*this < rhs || *this == rhs);
1106
}
1107
bool Timestamp::operator>(const DateTime& rhs)
1108
{
1109
  return ! (*this < rhs);
1110
}
1111
bool Timestamp::operator>=(const DateTime& rhs)
1112
{
1113
  return ! (*this <= rhs);
1114
}
1115
/*
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1116
 * Comparison operators between two Timestamps
1117
 */
907.1.7 by Jay Pipes
Merged in remove-timezone work
1118
bool Timestamp::operator==(const Timestamp& rhs)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1119
{
1120
  return (_epoch_seconds == rhs._epoch_seconds);
1121
}
907.1.7 by Jay Pipes
Merged in remove-timezone work
1122
bool Timestamp::operator!=(const Timestamp& rhs)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1123
{
1124
  return ! (*this == rhs);
1125
}
907.1.7 by Jay Pipes
Merged in remove-timezone work
1126
bool Timestamp::operator<(const Timestamp& rhs)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1127
{
1128
  return (_epoch_seconds < rhs._epoch_seconds);
1129
}
907.1.7 by Jay Pipes
Merged in remove-timezone work
1130
bool Timestamp::operator<=(const Timestamp& rhs)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1131
{
1132
  return (_epoch_seconds <= rhs._epoch_seconds);
1133
}
907.1.7 by Jay Pipes
Merged in remove-timezone work
1134
bool Timestamp::operator>(const Timestamp& rhs)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1135
{
1136
  return ! (*this < rhs);
1137
}
907.1.7 by Jay Pipes
Merged in remove-timezone work
1138
bool Timestamp::operator>=(const Timestamp& rhs)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1139
{
1140
  return ! (*this <= rhs);
1141
}
1142
907.1.7 by Jay Pipes
Merged in remove-timezone work
1143
/**
1144
 * Push the contents of the timestamp into the output stream
1145
 * as a formatted Timestamp value.
1146
 *
1147
 * @TODO This unfortunately fails in a weird way...even with std::noskipws, 
1148
 * the output stream only reads up to the space in the string... :(
1149
 */
1150
std::ostream& operator<<(std::ostream& os, const Timestamp& subject)
1151
{
1152
  return os << subject.years() << '-' 
1153
            << std::setw(2) << std::setfill('0') << subject.months() << '-'
1154
            << std::setw(2) << std::setfill('0') << subject.days() << ' '
1155
            << std::setw(2) << std::setfill('0') << subject.hours() << ':'
1156
            << std::setw(2) << std::setfill('0') << subject.minutes() << ':'
1157
            << std::setw(2) << std::setfill('0') << subject.seconds();
1158
}
1159
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1160
bool Time::from_string(const char *from, size_t from_len)
1161
{
892.2.9 by Monty Taylor
Raped Jay's code.
1162
  /*
1163
   * Loop through the known time formats and see if
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1164
   * there is a match.
1165
   */
1166
  bool matched= false;
1167
  TemporalFormat *current_format;
1168
  std::vector<TemporalFormat *>::iterator current= known_time_formats.begin();
1169
1170
  while (current != known_time_formats.end())
1171
  {
1172
    current_format= *current;
1173
    if (current_format->matches(from, from_len, this))
1174
    {
1175
      matched= true;
1176
      break;
1177
    }
1178
    current++;
1179
  }
1180
1181
  if (! matched)
1182
    return false;
1183
  else
1184
    return is_valid();
1185
}
1186
1187
void Time::to_string(char *to, size_t *to_len) const
1188
{
1189
  *to_len= sprintf(to
1190
                 , "%02" PRIu32 ":%02" PRIu32 ":%02" PRIu32
1191
                 , _hours
1192
                 , _minutes
1193
                 , _seconds);
1194
}
1195
1196
void Date::to_string(char *to, size_t *to_len) const
1197
{
1198
  *to_len= sprintf(to
1199
                 , "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32
1200
                 , _years
1201
                 , _months
1202
                 , _days);
1203
}
1204
1205
void DateTime::to_string(char *to, size_t *to_len) const
1206
{
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
1207
  /* If the temporal has a microsecond component, use a slightly different output */
1208
  if (_useconds == 0)
1209
  {
1210
    *to_len= sprintf(to
1211
                  , "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32 " %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32
1212
                  , _years
1213
                  , _months
1214
                  , _days
1215
                  , _hours
1216
                  , _minutes
1217
                  , _seconds);
1218
  }
1219
  else
1220
  {
1221
    *to_len= sprintf(to
1222
                  , "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32 " %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 ".%06" PRIu32
1223
                  , _years
1224
                  , _months
1225
                  , _days
1226
                  , _hours
1227
                  , _minutes
1228
                  , _seconds
1229
                  , _useconds);
1230
  }
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1231
}
1232
1233
void MicroTimestamp::to_string(char *to, size_t *to_len) const
1234
{
1235
  *to_len= sprintf(to
1236
                 , "%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32 " %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 ".%06" PRIu32
1237
                 , _years
1238
                 , _months
1239
                 , _days
1240
                 , _hours
1241
                 , _minutes
1242
                 , _seconds
1243
                 , _useconds);
1244
}
1245
1246
void Time::to_decimal(my_decimal *to) const
1247
{
1248
  int64_t time_portion= (((_hours * 100L) + _minutes) * 100L) + _seconds;
1249
  (void) int2my_decimal(E_DEC_FATAL_ERROR, time_portion, false, to);
1250
  if (_useconds > 0)
1251
  {
1252
    to->buf[(to->intg-1) / 9 + 1]= _useconds * 1000;
1253
    to->frac= 6;
1254
  }
1255
}
1256
1257
void Date::to_decimal(my_decimal *to) const
1258
{
1259
  int64_t date_portion= (((_years * 100L) + _months) * 100L) + _days;
1260
  (void) int2my_decimal(E_DEC_FATAL_ERROR, date_portion, false, to);
1261
}
1262
1263
void DateTime::to_decimal(my_decimal *to) const
1264
{
1265
  int64_t date_portion= (((_years * 100L) + _months) * 100L) + _days;
1266
  int64_t time_portion= (((((date_portion * 100L) + _hours) * 100L) + _minutes) * 100L) + _seconds;
1267
  (void) int2my_decimal(E_DEC_FATAL_ERROR, time_portion, false, to);
1268
  if (_useconds > 0)
1269
  {
1270
    to->buf[(to->intg-1) / 9 + 1]= _useconds * 1000;
1271
    to->frac= 6;
1272
  }
1273
}
1274
1275
void Date::to_int64_t(int64_t *to) const
1276
{
1277
  *to= (_years * INT32_C(10000)) 
1278
     + (_months * INT32_C(100)) 
1279
     + _days;
1280
}
1281
1282
void Date::to_int32_t(int32_t *to) const
1283
{
1284
  *to= (_years * INT32_C(10000)) 
1285
     + (_months * INT32_C(100)) 
1286
     + _days;
1287
}
1288
1289
void Time::to_int32_t(int32_t *to) const
1290
{
1291
  *to= (_hours * INT32_C(10000)) 
1292
     + (_minutes * INT32_C(100)) 
1293
     + _seconds;
1294
}
1295
1296
void DateTime::to_int64_t(int64_t *to) const
1297
{
1298
  *to= ((
1299
       (_years * INT64_C(10000)) 
1300
     + (_months * INT64_C(100)) 
1301
     + _days
1302
       ) * INT64_C(1000000))
1303
     + (
1304
       (_hours * INT64_C(10000)) 
1305
     + (_minutes * INT64_C(100) )
1306
     + _seconds
1307
     );
1308
}
1309
1310
void Date::to_tm(struct tm *to) const
1311
{
1312
  to->tm_sec= 0;
1313
  to->tm_min= 0;
1314
  to->tm_hour= 0;
1315
  to->tm_mday= _days; /* Drizzle format uses ordinal, standard tm does too! */
1316
  to->tm_mon= _months - 1; /* Drizzle format uses ordinal, standard tm does NOT! */
1317
  to->tm_year= _years - 1900;
1318
}
1319
1320
void DateTime::to_tm(struct tm *to) const
1321
{
1322
  to->tm_sec= _seconds;
1323
  to->tm_min= _minutes;
1324
  to->tm_hour= _hours;
1325
  to->tm_mday= _days; /* Drizzle format uses ordinal, standard tm does too! */
1326
  to->tm_mon= _months - 1; /* Drizzle format uses ordinal, standard tm does NOT! */
1327
  to->tm_year= _years - 1900;
1328
}
1329
1330
bool Date::from_julian_day_number(const int64_t from)
1331
{
1332
  gregorian_date_from_julian_day_number(from, &_years, &_months, &_days);
1333
  return is_valid();
1334
}
1335
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
1336
void Date::to_julian_day_number(int64_t *to) const
1337
{
1338
  *to= julian_day_number_from_gregorian_date(_years, _months, _days);
1339
}
1340
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1341
/**
1342
 * Ignore overflow and pass-through to DateTime::from_int64_t()
1343
 */
1344
bool Date::from_int32_t(const int32_t from)
1345
{
1346
  return ((DateTime *) this)->from_int64_t((int64_t) from);
1347
}
1348
1349
/**
1350
 * Attempt to interpret the supplied 4-byte integer as
1351
 * a TIME value in the format HHmmSS
1352
 */
1353
bool Time::from_int32_t(const int32_t from)
1354
{
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
1355
  uint32_t copy_from= (uint32_t) from;
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1356
  _hours= copy_from % INT32_C(10000);
1357
  _minutes= copy_from % INT32_C(100);
1358
  _seconds= copy_from & 3; /* Masks off all but last 2 digits */
1359
  return is_valid();
1360
}
1361
1362
/**
1363
 * We try to intepret the incoming number as a datetime "string".
1364
 * This is pretty much a hack for usability, but keeps us compatible
1365
 * with MySQL.
1366
 */
1367
bool DateTime::from_int64_t(const int64_t from)
1368
{
1369
  int64_t copy_from= from;
1370
  int64_t part1;
1371
  int64_t part2;
1372
873.1.7 by Jay Pipes
Fixes Field_datetime::store(NUMBER) to throw an error when invalid
1373
  if (copy_from == 0LL)
1374
    return false;
1375
1376
  if (copy_from < 10000101000000LL)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1377
  {
1378
    if (copy_from < 101)
1379
      return false;
873.1.7 by Jay Pipes
Fixes Field_datetime::store(NUMBER) to throw an error when invalid
1380
    else if (copy_from <= (DRIZZLE_YY_PART_YEAR-1)*10000L+1231L)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1381
      copy_from= (copy_from+20000000L)*1000000L;                 /* YYMMDD, year: 2000-2069 */
873.1.7 by Jay Pipes
Fixes Field_datetime::store(NUMBER) to throw an error when invalid
1382
    else if (copy_from < (DRIZZLE_YY_PART_YEAR)*10000L+101L)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1383
      return false;
873.1.7 by Jay Pipes
Fixes Field_datetime::store(NUMBER) to throw an error when invalid
1384
    else if (copy_from <= 991231L)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1385
      copy_from= (copy_from+19000000L)*1000000L;                 /* YYMMDD, year: 1970-1999 */
873.1.7 by Jay Pipes
Fixes Field_datetime::store(NUMBER) to throw an error when invalid
1386
    else if (copy_from < 10000101L)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1387
      return false;
873.1.7 by Jay Pipes
Fixes Field_datetime::store(NUMBER) to throw an error when invalid
1388
    else if (copy_from <= 99991231L)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1389
      copy_from= copy_from*1000000L;
873.1.7 by Jay Pipes
Fixes Field_datetime::store(NUMBER) to throw an error when invalid
1390
    else if (copy_from < 101000000L)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1391
      return false;
873.1.7 by Jay Pipes
Fixes Field_datetime::store(NUMBER) to throw an error when invalid
1392
    else if (copy_from <= (DRIZZLE_YY_PART_YEAR-1) * 10000000000LL + 1231235959LL)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1393
      copy_from= copy_from + 20000000000000LL;                   /* YYMMDDHHMMSS, 2000-2069 */
873.1.7 by Jay Pipes
Fixes Field_datetime::store(NUMBER) to throw an error when invalid
1394
    else if (copy_from <  DRIZZLE_YY_PART_YEAR * 10000000000LL + 101000000LL)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1395
      return false;
873.1.7 by Jay Pipes
Fixes Field_datetime::store(NUMBER) to throw an error when invalid
1396
    else if (copy_from <= 991231235959LL)
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1397
      copy_from= copy_from + 19000000000000LL;		/* YYMMDDHHMMSS, 1970-1999 */
1398
  }
1399
1400
  part1= (int64_t) (copy_from / 1000000LL);
1401
  part2= (int64_t) (copy_from - (int64_t) part1 * 1000000LL);
1402
  _years=  (uint32_t) (part1/10000L);  
1403
  
1404
  part1%=10000L;
1405
  _months= (uint32_t) part1 / 100;
1406
  _days=   (uint32_t) part1 % 100;
1407
  _hours=  (uint32_t) (part2/10000L);  
1408
1409
  part2%=10000L;
1410
  _minutes= (uint32_t) part2 / 100;
1411
  _seconds= (uint32_t) part2 % 100;
1412
1413
  set_epoch_seconds();
1414
  return is_valid();
1415
}
1416
1417
bool Date::in_unix_epoch() const
1418
{
1419
  return in_unix_epoch_range(_years, _months, _days, 0, 0, 0);
1420
}
1421
1422
bool DateTime::in_unix_epoch() const
1423
{
1424
  return in_unix_epoch_range(_years, _months, _days, _hours, _minutes, _seconds);
1425
}
1426
1427
bool Date::from_tm(const struct tm *from)
1428
{
1429
  _years= 1900 + from->tm_year;
1430
  _months= 1 + from->tm_mon; /* Month is NOT ordinal for struct tm! */
1431
  _days= from->tm_mday; /* Day IS ordinal for struct tm */
1432
  _hours= from->tm_hour;
1433
  _minutes= from->tm_min;
1434
  _seconds= from->tm_sec;
1435
  /* Set hires precision to zero */
1436
  _useconds= 0;
1437
  _nseconds= 0;
1438
1439
  set_epoch_seconds();
1440
  return is_valid();
1441
}
1442
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
1443
/* 
1444
 * We convert as if it's a Datetime, then simply
1445
 * drop the date portions...
1446
 */
1447
bool Time::from_time_t(const time_t from)
1448
{
1449
  struct tm broken_time;
1450
  struct tm *result;
1451
1452
  result= gmtime_r(&from, &broken_time);
1453
  if (result != NULL)
1454
  {
1455
    _years= 0;
1456
    _months= 0;
1457
    _days= 0;
1458
    _hours= broken_time.tm_hour;
1459
    _minutes= broken_time.tm_min;
1460
    _seconds= broken_time.tm_sec;
1461
    _epoch_seconds= 0; /* Don't store the time_t, since we only use part of it */
1462
    /* Set hires precision to zero */
1463
    _useconds= 0;
1464
    _nseconds= 0;
1465
    return true; /* Always true... */
1466
  }
1467
  else 
1468
    return false;
1469
}
1470
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1471
bool Date::from_time_t(const time_t from)
1472
{
1473
  struct tm broken_time;
1474
  struct tm *result;
1475
1476
  result= gmtime_r(&from, &broken_time);
1477
  if (result != NULL)
1478
  {
1479
    _years= 1900 + broken_time.tm_year;
1480
    _months= 1 + broken_time.tm_mon; /* Month is NOT ordinal for struct tm! */
1481
    _days= broken_time.tm_mday; /* Day IS ordinal for struct tm */
1482
    _hours= 0;
1483
    _minutes= 0;
1484
    _seconds= 0;
873.1.4 by Jay Pipes
Solaris integer truncation fixes - Thanks to MontyT for the warning output.. :)
1485
    _epoch_seconds= 0; /* Don't store the time_t, since we only use part of it */
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1486
    /* Set hires precision to zero */
1487
    _useconds= 0;
1488
    _nseconds= 0;
1489
    return is_valid();
1490
  }
1491
  else 
1492
    return false;
1493
}
1494
1495
bool DateTime::from_time_t(const time_t from)
1496
{
1497
  struct tm broken_time;
1498
  struct tm *result;
1499
1500
  result= gmtime_r(&from, &broken_time);
1501
  if (result != NULL)
1502
  {
1503
    _years= 1900 + broken_time.tm_year;
1504
    _months= 1 + broken_time.tm_mon; /* Month is NOT ordinal for struct tm! */
1505
    _days= broken_time.tm_mday; /* Day IS ordinal for struct tm */
1506
    _hours= broken_time.tm_hour;
1507
    _minutes= broken_time.tm_min;
1508
    _seconds= broken_time.tm_sec;
1509
    _epoch_seconds= from;
1510
    /* Set hires precision to zero */
1511
    _useconds= 0;
1512
    _nseconds= 0;
1513
    return is_valid();
1514
  }
1515
  else 
1516
    return false;
1517
}
1518
1519
void Date::to_time_t(time_t *to) const
1520
{
1521
  if (in_unix_epoch())
997.6.1 by Devananda
added else in Date::to_time_t
1522
  {
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1523
    *to= _epoch_seconds;
997.6.1 by Devananda
added else in Date::to_time_t
1524
  }
1525
  else
1526
    *to= 0;
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1527
}
1528
1529
void Timestamp::to_time_t(time_t *to) const
1530
{
1531
  *to= _epoch_seconds;
1532
}
1533
1534
void MicroTimestamp::to_timeval(struct timeval *to) const
1535
{
1536
  to->tv_sec= _epoch_seconds;
1537
  to->tv_usec= _useconds;
1538
}
1539
1540
void NanoTimestamp::to_timespec(struct timespec *to) const
1541
{
1542
  to->tv_sec= _epoch_seconds;
1543
  to->tv_nsec= _nseconds;
1544
}
1545
1546
bool Date::is_valid() const
1547
{
1548
  return (_years >= DRIZZLE_MIN_YEARS_SQL && _years <= DRIZZLE_MAX_YEARS_SQL)
1549
      && (_months >= 1 && _months <= 12)
1550
      && (_days >= 1 && _days <= days_in_gregorian_year_month(_years, _months));
1551
}
1552
1553
bool Time::is_valid() const
1554
{
1555
  return (_years == 0)
1556
      && (_months == 0)
1557
      && (_days == 0)
1558
      && (_hours <= 23)
1559
      && (_minutes <= 59)
1560
      && (_seconds <= 59); /* No Leap second... TIME is for elapsed time... */
1561
}
1562
1563
bool DateTime::is_valid() const
1564
{
1565
  return (_years >= DRIZZLE_MIN_YEARS_SQL && _years <= DRIZZLE_MAX_YEARS_SQL)
1566
      && (_months >= 1 && _months <= 12)
1567
      && (_days >= 1 && _days <= days_in_gregorian_year_month(_years, _months))
1568
      && (_hours <= 23)
1569
      && (_minutes <= 59)
1570
      && (_seconds <= 61); /* Leap second... */
1571
}
1572
1573
bool Timestamp::is_valid() const
1574
{
907.1.7 by Jay Pipes
Merged in remove-timezone work
1575
  return DateTime::is_valid() 
1576
      && in_unix_epoch_range(_years, _months, _days, _hours, _minutes, _seconds);
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1577
}
1578
1579
bool MicroTimestamp::is_valid() const
1580
{
907.1.7 by Jay Pipes
Merged in remove-timezone work
1581
  return Timestamp::is_valid()
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1582
      && (_useconds <= UINT32_C(999999));
1583
}
1584
1585
bool NanoTimestamp::is_valid() const
1586
{
907.1.7 by Jay Pipes
Merged in remove-timezone work
1587
  return Timestamp::is_valid()
813.1.2 by Jay Pipes
First function cleanup for temporal handling: YEAR()
1588
      && (_useconds <= UINT32_C(999999))
1589
      && (_nseconds <= UINT32_C(999999999));
1590
}
1591
1592
} /* end namespace drizzled */