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