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