~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/my_time.c

  • Committer: Monty Taylor
  • Date: 2008-10-16 06:32:30 UTC
  • mto: (511.1.5 codestyle)
  • mto: This revision was merged to the branch mainline in revision 521.
  • Revision ID: monty@inaugust.com-20081016063230-4brxsra0qsmsg84q
Added -Wunused-macros.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
#include <my_time.h>
17
 
#include <m_string.h>
18
 
#include <m_ctype.h>
 
17
#include <mystrings/m_string.h>
 
18
#include <mystrings/m_ctype.h>
 
19
#include <drizzled/util/test.h>
19
20
/* Windows version of localtime_r() is declared in my_ptrhead.h */
20
 
#include <my_pthread.h>
21
21
 
22
22
uint64_t log_10_int[20]=
23
23
{
31
31
 
32
32
/* Position for YYYY-DD-MM HH-MM-DD.FFFFFF AM in default format */
33
33
 
34
 
static uchar internal_format_positions[]=
35
 
{0, 1, 2, 3, 4, 5, 6, (uchar) 255};
 
34
static unsigned char internal_format_positions[]=
 
35
{0, 1, 2, 3, 4, 5, 6, (unsigned char) 255};
36
36
 
37
37
static char time_separator=':';
38
38
 
39
 
static ulong const days_at_timestart=719528;    /* daynr at 1970.01.01 */
40
 
uchar days_in_month[]= {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0};
 
39
static uint32_t const days_at_timestart=719528; /* daynr at 1970.01.01 */
 
40
unsigned char days_in_month[]= {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0};
41
41
 
42
42
/*
43
43
  Offset of system time zone from UTC in seconds used to speed up 
48
48
 
49
49
/* Calc days in one year. works with 0 <= year <= 99 */
50
50
 
51
 
uint calc_days_in_year(uint year)
 
51
uint32_t calc_days_in_year(uint32_t year)
52
52
{
53
53
  return ((year & 3) == 0 && (year%100 || (year%400 == 0 && year)) ?
54
54
          366 : 365);
75
75
    1  error
76
76
*/
77
77
 
78
 
my_bool check_date(const MYSQL_TIME *ltime, my_bool not_zero_date,
79
 
                   ulong flags, int *was_cut)
 
78
bool check_date(const DRIZZLE_TIME *ltime, bool not_zero_date,
 
79
                   uint32_t flags, int *was_cut)
80
80
{
81
81
  if (not_zero_date)
82
82
  {
104
104
 
105
105
 
106
106
/*
107
 
  Convert a timestamp string to a MYSQL_TIME value.
 
107
  Convert a timestamp string to a DRIZZLE_TIME value.
108
108
 
109
109
  SYNOPSIS
110
110
    str_to_datetime()
145
145
   - The hour part must be specified in hour-minute-second order.
146
146
 
147
147
  RETURN VALUES
148
 
    MYSQL_TIMESTAMP_NONE        String wasn't a timestamp, like
 
148
    DRIZZLE_TIMESTAMP_NONE        String wasn't a timestamp, like
149
149
                                [DD [HH:[MM:[SS]]]].fraction.
150
150
                                l_time is not changed.
151
 
    MYSQL_TIMESTAMP_DATE        DATE string (YY MM and DD parts ok)
152
 
    MYSQL_TIMESTAMP_DATETIME    Full timestamp
153
 
    MYSQL_TIMESTAMP_ERROR       Timestamp with wrong values.
 
151
    DRIZZLE_TIMESTAMP_DATE        DATE string (YY MM and DD parts ok)
 
152
    DRIZZLE_TIMESTAMP_DATETIME    Full timestamp
 
153
    DRIZZLE_TIMESTAMP_ERROR       Timestamp with wrong values.
154
154
                                All elements in l_time is set to 0
155
155
*/
156
156
 
157
157
#define MAX_DATE_PARTS 8
158
158
 
159
 
enum enum_mysql_timestamp_type
160
 
str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
161
 
                uint flags, int *was_cut)
 
159
enum enum_drizzle_timestamp_type
 
160
str_to_datetime(const char *str, uint32_t length, DRIZZLE_TIME *l_time,
 
161
                uint32_t flags, int *was_cut)
162
162
{
163
 
  uint field_length, year_length=4, digits, i, number_of_fields;
164
 
  uint date[MAX_DATE_PARTS], date_len[MAX_DATE_PARTS];
165
 
  uint add_hours= 0, start_loop;
166
 
  ulong not_zero_date, allow_space;
167
 
  my_bool is_internal_format;
 
163
  uint32_t field_length, year_length=4, digits, i, number_of_fields;
 
164
  uint32_t date[MAX_DATE_PARTS], date_len[MAX_DATE_PARTS];
 
165
  uint32_t add_hours= 0, start_loop;
 
166
  uint32_t not_zero_date, allow_space;
 
167
  bool is_internal_format;
168
168
  const char *pos, *last_field_pos=NULL;
169
169
  const char *end=str+length;
170
 
  const uchar *format_position;
171
 
  my_bool found_delimitier= 0, found_space= 0;
172
 
  uint frac_pos, frac_len;
173
 
  DBUG_ENTER("str_to_datetime");
174
 
  DBUG_PRINT("ENTER",("str: %.*s",length,str));
 
170
  const unsigned char *format_position;
 
171
  bool found_delimitier= 0, found_space= 0;
 
172
  uint32_t frac_pos, frac_len;
175
173
 
176
174
  *was_cut= 0;
177
175
 
178
176
  /* Skip space at start */
179
 
  for (; str != end && my_isspace(&my_charset_latin1, *str) ; str++)
 
177
  for (; str != end && my_isspace(&my_charset_utf8_general_ci, *str) ; str++)
180
178
    ;
181
 
  if (str == end || ! my_isdigit(&my_charset_latin1, *str))
 
179
  if (str == end || ! my_isdigit(&my_charset_utf8_general_ci, *str))
182
180
  {
183
181
    *was_cut= 1;
184
 
    DBUG_RETURN(MYSQL_TIMESTAMP_NONE);
 
182
    return(DRIZZLE_TIMESTAMP_NONE);
185
183
  }
186
184
 
187
185
  is_internal_format= 0;
194
192
    (YYYY-MM-DD,  YYYYMMDD, YYYYYMMDDHHMMSS)
195
193
  */
196
194
  for (pos=str;
197
 
       pos != end && (my_isdigit(&my_charset_latin1,*pos) || *pos == 'T');
 
195
       pos != end && (my_isdigit(&my_charset_utf8_general_ci,*pos) || *pos == 'T');
198
196
       pos++)
199
197
    ;
200
198
 
219
217
        We do this by checking if there is two numbers separated by
220
218
        space in the input.
221
219
      */
222
 
      while (pos < end && !my_isspace(&my_charset_latin1, *pos))
 
220
      while (pos < end && !my_isspace(&my_charset_utf8_general_ci, *pos))
223
221
        pos++;
224
 
      while (pos < end && !my_isdigit(&my_charset_latin1, *pos))
 
222
      while (pos < end && !my_isdigit(&my_charset_utf8_general_ci, *pos))
225
223
        pos++;
226
224
      if (pos == end)
227
225
      {
228
226
        if (flags & TIME_DATETIME_ONLY)
229
227
        {
230
228
          *was_cut= 1;
231
 
          DBUG_RETURN(MYSQL_TIMESTAMP_NONE);   /* Can't be a full datetime */
 
229
          return(DRIZZLE_TIMESTAMP_NONE);   /* Can't be a full datetime */
232
230
        }
233
231
        /* Date field.  Set hour, minutes and seconds to 0 */
234
232
        date[0]= date[1]= date[2]= date[3]= date[4]= 0;
247
245
    2003-03-03 20:00:20 AM
248
246
    20:00:20.000000 AM 03-03-2000
249
247
  */
250
 
  i= max((uint) format_position[0], (uint) format_position[1]);
 
248
  i= cmax((uint) format_position[0], (uint) format_position[1]);
251
249
  set_if_bigger(i, (uint) format_position[2]);
252
250
  allow_space= ((1 << i) | (1 << format_position[6]));
253
251
  allow_space&= (1 | 2 | 4 | 8);
255
253
  not_zero_date= 0;
256
254
  for (i = start_loop;
257
255
       i < MAX_DATE_PARTS-1 && str != end &&
258
 
         my_isdigit(&my_charset_latin1,*str);
 
256
         my_isdigit(&my_charset_utf8_general_ci,*str);
259
257
       i++)
260
258
  {
261
259
    const char *start= str;
262
 
    ulong tmp_value= (uint) (uchar) (*str++ - '0');
263
 
    while (str != end && my_isdigit(&my_charset_latin1,str[0]) &&
 
260
    uint32_t tmp_value= (uint) (unsigned char) (*str++ - '0');
 
261
    while (str != end && my_isdigit(&my_charset_utf8_general_ci,str[0]) &&
264
262
           (!is_internal_format || --field_length))
265
263
    {
266
 
      tmp_value=tmp_value*10 + (ulong) (uchar) (*str - '0');
 
264
      tmp_value=tmp_value*10 + (uint32_t) (unsigned char) (*str - '0');
267
265
      str++;
268
266
    }
269
267
    date_len[i]= (uint) (str - start);
270
268
    if (tmp_value > 999999)                     /* Impossible date part */
271
269
    {
272
270
      *was_cut= 1;
273
 
      DBUG_RETURN(MYSQL_TIMESTAMP_NONE);
 
271
      return(DRIZZLE_TIMESTAMP_NONE);
274
272
    }
275
273
    date[i]=tmp_value;
276
274
    not_zero_date|= tmp_value;
299
297
      continue;
300
298
    }
301
299
    while (str != end &&
302
 
           (my_ispunct(&my_charset_latin1,*str) ||
303
 
            my_isspace(&my_charset_latin1,*str)))
 
300
           (my_ispunct(&my_charset_utf8_general_ci,*str) ||
 
301
            my_isspace(&my_charset_utf8_general_ci,*str)))
304
302
    {
305
 
      if (my_isspace(&my_charset_latin1,*str))
 
303
      if (my_isspace(&my_charset_utf8_general_ci,*str))
306
304
      {
307
305
        if (!(allow_space & (1 << i)))
308
306
        {
309
307
          *was_cut= 1;
310
 
          DBUG_RETURN(MYSQL_TIMESTAMP_NONE);
 
308
          return(DRIZZLE_TIMESTAMP_NONE);
311
309
        }
312
310
        found_space= 1;
313
311
      }
328
326
            continue;                           /* Not AM/PM */
329
327
          str+= 2;                              /* Skip AM/PM */
330
328
          /* Skip space after AM/PM */
331
 
          while (str != end && my_isspace(&my_charset_latin1,*str))
 
329
          while (str != end && my_isspace(&my_charset_utf8_general_ci,*str))
332
330
            str++;
333
331
        }
334
332
      }
338
336
  if (found_delimitier && !found_space && (flags & TIME_DATETIME_ONLY))
339
337
  {
340
338
    *was_cut= 1;
341
 
    DBUG_RETURN(MYSQL_TIMESTAMP_NONE);          /* Can't be a datetime */
 
339
    return(DRIZZLE_TIMESTAMP_NONE);          /* Can't be a datetime */
342
340
  }
343
341
 
344
342
  str= last_field_pos;
356
354
    if (!year_length)                           /* Year must be specified */
357
355
    {
358
356
      *was_cut= 1;
359
 
      DBUG_RETURN(MYSQL_TIMESTAMP_NONE);
 
357
      return(DRIZZLE_TIMESTAMP_NONE);
360
358
    }
361
359
 
362
360
    l_time->year=               date[(uint) format_position[0]];
372
370
      date[frac_pos]*= (uint) log_10_int[6 - frac_len];
373
371
    l_time->second_part= date[frac_pos];
374
372
 
375
 
    if (format_position[7] != (uchar) 255)
 
373
    if (format_position[7] != (unsigned char) 255)
376
374
    {
377
375
      if (l_time->hour > 12)
378
376
      {
409
407
    {
410
408
      for (; str != end ; str++)
411
409
      {
412
 
        if (!my_isspace(&my_charset_latin1, *str))
 
410
        if (!my_isspace(&my_charset_utf8_general_ci, *str))
413
411
        {
414
412
          not_zero_date= 1;                     /* Give warning */
415
413
          break;
424
422
    goto err;
425
423
 
426
424
  l_time->time_type= (number_of_fields <= 3 ?
427
 
                      MYSQL_TIMESTAMP_DATE : MYSQL_TIMESTAMP_DATETIME);
 
425
                      DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME);
428
426
 
429
427
  for (; str != end ; str++)
430
428
  {
431
 
    if (!my_isspace(&my_charset_latin1,*str))
 
429
    if (!my_isspace(&my_charset_utf8_general_ci,*str))
432
430
    {
433
431
      *was_cut= 1;
434
432
      break;
435
433
    }
436
434
  }
437
435
 
438
 
  DBUG_RETURN(l_time->time_type=
439
 
              (number_of_fields <= 3 ? MYSQL_TIMESTAMP_DATE :
440
 
                                       MYSQL_TIMESTAMP_DATETIME));
 
436
  return(l_time->time_type=
 
437
              (number_of_fields <= 3 ? DRIZZLE_TIMESTAMP_DATE :
 
438
                                       DRIZZLE_TIMESTAMP_DATETIME));
441
439
 
442
440
err:
443
 
  bzero((char*) l_time, sizeof(*l_time));
444
 
  DBUG_RETURN(MYSQL_TIMESTAMP_ERROR);
 
441
  memset(l_time, 0, sizeof(*l_time));
 
442
  return(DRIZZLE_TIMESTAMP_ERROR);
445
443
}
446
444
 
447
445
 
448
446
/*
449
 
 Convert a time string to a MYSQL_TIME struct.
 
447
 Convert a time string to a DRIZZLE_TIME struct.
450
448
 
451
449
  SYNOPSIS
452
450
   str_to_time()
456
454
                        There may be an optional [.second_part] after seconds
457
455
   length               Length of str
458
456
   l_time               Store result here
459
 
   warning              Set MYSQL_TIME_WARN_TRUNCATED flag if the input string
 
457
   warning              Set DRIZZLE_TIME_WARN_TRUNCATED flag if the input string
460
458
                        was cut during conversion, and/or
461
 
                        MYSQL_TIME_WARN_OUT_OF_RANGE flag, if the value is
 
459
                        DRIZZLE_TIME_WARN_OUT_OF_RANGE flag, if the value is
462
460
                        out of range.
463
461
 
464
462
   NOTES
470
468
     1  error
471
469
*/
472
470
 
473
 
my_bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
 
471
bool str_to_time(const char *str, uint32_t length, DRIZZLE_TIME *l_time,
474
472
                    int *warning)
475
473
{
476
 
  ulong date[5];
 
474
  uint32_t date[5];
477
475
  uint64_t value;
478
476
  const char *end=str+length, *end_of_days;
479
 
  my_bool found_days,found_hours;
480
 
  uint state;
 
477
  bool found_days,found_hours;
 
478
  uint32_t state;
481
479
 
482
480
  l_time->neg=0;
483
481
  *warning= 0;
484
 
  for (; str != end && my_isspace(&my_charset_latin1,*str) ; str++)
 
482
  for (; str != end && my_isspace(&my_charset_utf8_general_ci,*str) ; str++)
485
483
    length--;
486
484
  if (str != end && *str == '-')
487
485
  {
496
494
  if (length >= 12)
497
495
  {                                             /* Probably full timestamp */
498
496
    int was_cut;
499
 
    enum enum_mysql_timestamp_type
 
497
    enum enum_drizzle_timestamp_type
500
498
      res= str_to_datetime(str, length, l_time,
501
499
                           (TIME_FUZZY_DATE | TIME_DATETIME_ONLY), &was_cut);
502
 
    if ((int) res >= (int) MYSQL_TIMESTAMP_ERROR)
 
500
    if ((int) res >= (int) DRIZZLE_TIMESTAMP_ERROR)
503
501
    {
504
502
      if (was_cut)
505
 
        *warning|= MYSQL_TIME_WARN_TRUNCATED;
506
 
      return res == MYSQL_TIMESTAMP_ERROR;
 
503
        *warning|= DRIZZLE_TIME_WARN_TRUNCATED;
 
504
      return res == DRIZZLE_TIMESTAMP_ERROR;
507
505
    }
508
506
  }
509
507
 
510
508
  /* Not a timestamp. Try to get this as a DAYS_TO_SECOND string */
511
 
  for (value=0; str != end && my_isdigit(&my_charset_latin1,*str) ; str++)
 
509
  for (value=0; str != end && my_isdigit(&my_charset_utf8_general_ci,*str) ; str++)
512
510
    value=value*10L + (long) (*str - '0');
513
511
 
514
512
  /* Skip all space after 'days' */
515
513
  end_of_days= str;
516
 
  for (; str != end && my_isspace(&my_charset_latin1, str[0]) ; str++)
 
514
  for (; str != end && my_isspace(&my_charset_utf8_general_ci, str[0]) ; str++)
517
515
    ;
518
516
 
519
517
  found_days=found_hours=0;
520
518
  if ((uint) (end-str) > 1 && str != end_of_days &&
521
 
      my_isdigit(&my_charset_latin1, *str))
 
519
      my_isdigit(&my_charset_utf8_general_ci, *str))
522
520
  {                                             /* Found days part */
523
 
    date[0]= (ulong) value;
 
521
    date[0]= (uint32_t) value;
524
522
    state= 1;                                   /* Assume next is hours */
525
523
    found_days= 1;
526
524
  }
527
525
  else if ((end-str) > 1 &&  *str == time_separator &&
528
 
           my_isdigit(&my_charset_latin1, str[1]))
 
526
           my_isdigit(&my_charset_utf8_general_ci, str[1]))
529
527
  {
530
528
    date[0]= 0;                                 /* Assume we found hours */
531
 
    date[1]= (ulong) value;
 
529
    date[1]= (uint32_t) value;
532
530
    state=2;
533
531
    found_hours=1;
534
532
    str++;                                      /* skip ':' */
537
535
  {
538
536
    /* String given as one number; assume HHMMSS format */
539
537
    date[0]= 0;
540
 
    date[1]= (ulong) (value/10000);
541
 
    date[2]= (ulong) (value/100 % 100);
542
 
    date[3]= (ulong) (value % 100);
 
538
    date[1]= (uint32_t) (value/10000);
 
539
    date[2]= (uint32_t) (value/100 % 100);
 
540
    date[3]= (uint32_t) (value % 100);
543
541
    state=4;
544
542
    goto fractional;
545
543
  }
547
545
  /* Read hours, minutes and seconds */
548
546
  for (;;)
549
547
  {
550
 
    for (value=0; str != end && my_isdigit(&my_charset_latin1,*str) ; str++)
 
548
    for (value=0; str != end && my_isdigit(&my_charset_utf8_general_ci,*str) ; str++)
551
549
      value=value*10L + (long) (*str - '0');
552
 
    date[state++]= (ulong) value;
 
550
    date[state++]= (uint32_t) value;
553
551
    if (state == 4 || (end-str) < 2 || *str != time_separator ||
554
 
        !my_isdigit(&my_charset_latin1,str[1]))
 
552
        !my_isdigit(&my_charset_utf8_general_ci,str[1]))
555
553
      break;
556
554
    str++;                                      /* Skip time_separator (':') */
557
555
  }
561
559
    /* Fix the date to assume that seconds was given */
562
560
    if (!found_hours && !found_days)
563
561
    {
564
 
      bmove_upp((uchar*) (date+4), (uchar*) (date+state),
 
562
      bmove_upp((unsigned char*) (date+4), (unsigned char*) (date+state),
565
563
                sizeof(long)*(state-1));
566
 
      bzero((uchar*) date, sizeof(long)*(4-state));
 
564
      memset(date, 0, sizeof(long)*(4-state));
567
565
    }
568
566
    else
569
 
      bzero((uchar*) (date+state), sizeof(long)*(4-state));
 
567
      memset(date+state, 0, sizeof(long)*(4-state));
570
568
  }
571
569
 
572
570
fractional:
573
571
  /* Get fractional second part */
574
 
  if ((end-str) >= 2 && *str == '.' && my_isdigit(&my_charset_latin1,str[1]))
 
572
  if ((end-str) >= 2 && *str == '.' && my_isdigit(&my_charset_utf8_general_ci,str[1]))
575
573
  {
576
574
    int field_length= 5;
577
 
    str++; value=(uint) (uchar) (*str - '0');
578
 
    while (++str != end && my_isdigit(&my_charset_latin1, *str))
 
575
    str++; value=(uint) (unsigned char) (*str - '0');
 
576
    while (++str != end && my_isdigit(&my_charset_utf8_general_ci, *str))
579
577
    {
580
578
      if (field_length-- > 0)
581
 
        value= value*10 + (uint) (uchar) (*str - '0');
 
579
        value= value*10 + (uint) (unsigned char) (*str - '0');
582
580
    }
583
581
    if (field_length > 0)
584
582
      value*= (long) log_10_int[field_length];
585
583
    else if (field_length < 0)
586
 
      *warning|= MYSQL_TIME_WARN_TRUNCATED;
587
 
    date[4]= (ulong) value;
 
584
      *warning|= DRIZZLE_TIME_WARN_TRUNCATED;
 
585
    date[4]= (uint32_t) value;
588
586
  }
589
587
  else
590
588
    date[4]=0;
593
591
  /* (may occur as result of %g formatting of time value) */
594
592
  if ((end - str) > 1 &&
595
593
      (*str == 'e' || *str == 'E') &&
596
 
      (my_isdigit(&my_charset_latin1, str[1]) ||
 
594
      (my_isdigit(&my_charset_utf8_general_ci, str[1]) ||
597
595
       ((str[1] == '-' || str[1] == '+') &&
598
596
        (end - str) > 2 &&
599
 
        my_isdigit(&my_charset_latin1, str[2]))))
 
597
        my_isdigit(&my_charset_utf8_general_ci, str[2]))))
600
598
    return 1;
601
599
 
602
600
  if (internal_format_positions[7] != 255)
603
601
  {
604
602
    /* Read a possible AM/PM */
605
 
    while (str != end && my_isspace(&my_charset_latin1, *str))
 
603
    while (str != end && my_isspace(&my_charset_utf8_general_ci, *str))
606
604
      str++;
607
605
    if (str+2 <= end && (str[1] == 'M' || str[1] == 'm'))
608
606
    {
629
627
  l_time->minute=       date[2];
630
628
  l_time->second=       date[3];
631
629
  l_time->second_part=  date[4];
632
 
  l_time->time_type= MYSQL_TIMESTAMP_TIME;
 
630
  l_time->time_type= DRIZZLE_TIMESTAMP_TIME;
633
631
 
634
 
  /* Check if the value is valid and fits into MYSQL_TIME range */
 
632
  /* Check if the value is valid and fits into DRIZZLE_TIME range */
635
633
  if (check_time_range(l_time, warning))
636
634
    return 1;
637
635
  
638
 
  /* Check if there is garbage at end of the MYSQL_TIME specification */
 
636
  /* Check if there is garbage at end of the DRIZZLE_TIME specification */
639
637
  if (str != end)
640
638
  {
641
639
    do
642
640
    {
643
 
      if (!my_isspace(&my_charset_latin1,*str))
 
641
      if (!my_isspace(&my_charset_utf8_general_ci,*str))
644
642
      {
645
 
        *warning|= MYSQL_TIME_WARN_TRUNCATED;
 
643
        *warning|= DRIZZLE_TIME_WARN_TRUNCATED;
646
644
        break;
647
645
      }
648
646
    } while (++str != end);
652
650
 
653
651
 
654
652
/*
655
 
  Check 'time' value to lie in the MYSQL_TIME range
 
653
  Check 'time' value to lie in the DRIZZLE_TIME range
656
654
 
657
655
  SYNOPSIS:
658
656
    check_time_range()
659
 
    time     pointer to MYSQL_TIME value
660
 
    warning  set MYSQL_TIME_WARN_OUT_OF_RANGE flag if the value is out of range
 
657
    time     pointer to DRIZZLE_TIME value
 
658
    warning  set DRIZZLE_TIME_WARN_OUT_OF_RANGE flag if the value is out of range
661
659
 
662
660
  DESCRIPTION
663
661
  If the time value lies outside of the range [-838:59:59, 838:59:59],
664
662
  set it to the closest endpoint of the range and set
665
 
  MYSQL_TIME_WARN_OUT_OF_RANGE flag in the 'warning' variable.
 
663
  DRIZZLE_TIME_WARN_OUT_OF_RANGE flag in the 'warning' variable.
666
664
 
667
665
  RETURN
668
666
    0        time value is valid, but was possibly truncated
669
667
    1        time value is invalid
670
668
*/
671
669
 
672
 
int check_time_range(struct st_mysql_time *my_time, int *warning) 
 
670
int check_time_range(DRIZZLE_TIME *my_time, int *warning) 
673
671
{
674
672
  int64_t hour;
675
673
 
687
685
  my_time->minute= TIME_MAX_MINUTE;
688
686
  my_time->second= TIME_MAX_SECOND;
689
687
  my_time->second_part= 0;
690
 
  *warning|= MYSQL_TIME_WARN_OUT_OF_RANGE;
 
688
  *warning|= DRIZZLE_TIME_WARN_OUT_OF_RANGE;
691
689
  return 0;
692
690
}
693
691
 
702
700
{
703
701
  time_t seconds;
704
702
  struct tm *l_time,tm_tmp;
705
 
  MYSQL_TIME my_time;
 
703
  DRIZZLE_TIME my_time;
706
704
  bool not_used;
707
705
 
708
706
  seconds= (time_t) time((time_t*) 0);
730
728
    Year between 1970-2069
731
729
*/
732
730
 
733
 
uint year_2000_handling(uint year)
 
731
uint32_t year_2000_handling(uint32_t year)
734
732
{
735
733
  if ((year=year+1900) < 1900+YY_PART_YEAR)
736
734
    year+=100;
753
751
    Days since 0000-00-00
754
752
*/
755
753
 
756
 
long calc_daynr(uint year,uint month,uint day)
 
754
long calc_daynr(uint32_t year,uint32_t month,uint32_t day)
757
755
{
758
756
  long delsum;
759
757
  int temp;
760
 
  DBUG_ENTER("calc_daynr");
761
758
 
762
759
  if (year == 0 && month == 0 && day == 0)
763
 
    DBUG_RETURN(0);                             /* Skip errors */
 
760
    return(0);                          /* Skip errors */
764
761
  delsum= (long) (365L * year+ 31*(month-1) +day);
765
762
  if (month <= 2)
766
763
      year--;
767
764
  else
768
765
    delsum-= (long) (month*4+23)/10;
769
766
  temp=(int) ((year/100+1)*3)/4;
770
 
  DBUG_PRINT("exit",("year: %d  month: %d  day: %d -> daynr: %ld",
771
 
                     year+(month <= 2),month,day,delsum+year/4-temp));
772
 
  DBUG_RETURN(delsum+(int) year/4-temp);
 
767
  return(delsum+(int) year/4-temp);
773
768
} /* calc_daynr */
774
769
 
775
770
 
776
771
/*
777
 
  Convert time in MYSQL_TIME representation in system time zone to its
 
772
  Convert time in DRIZZLE_TIME representation in system time zone to its
778
773
  my_time_t form (number of seconds in UTC since begginning of Unix Epoch).
779
774
 
780
775
  SYNOPSIS
796
791
    Time in UTC seconds since Unix Epoch representation.
797
792
*/
798
793
my_time_t
799
 
my_system_gmt_sec(const MYSQL_TIME *t_src, long *my_timezone,
 
794
my_system_gmt_sec(const DRIZZLE_TIME *t_src, long *my_timezone,
800
795
                  bool *in_dst_time_gap)
801
796
{
802
 
  uint loop;
 
797
  uint32_t loop;
803
798
  time_t tmp= 0;
804
799
  int shift= 0;
805
 
  MYSQL_TIME tmp_time;
806
 
  MYSQL_TIME *t= &tmp_time;
 
800
  DRIZZLE_TIME tmp_time;
 
801
  DRIZZLE_TIME *t= &tmp_time;
807
802
  struct tm *l_time,tm_tmp;
808
803
  long diff, current_timezone;
809
804
 
811
806
    Use temp variable to avoid trashing input data, which could happen in
812
807
    case of shift required for boundary dates processing.
813
808
  */
814
 
  memcpy(&tmp_time, t_src, sizeof(MYSQL_TIME));
 
809
  memcpy(&tmp_time, t_src, sizeof(DRIZZLE_TIME));
815
810
 
816
811
  if (!validate_timestamp_range(t))
817
812
    return 0;
985
980
} /* my_system_gmt_sec */
986
981
 
987
982
 
988
 
/* Set MYSQL_TIME structure to 0000-00-00 00:00:00.000000 */
 
983
/* Set DRIZZLE_TIME structure to 0000-00-00 00:00:00.000000 */
989
984
 
990
 
void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type)
 
985
void set_zero_time(DRIZZLE_TIME *tm, enum enum_drizzle_timestamp_type time_type)
991
986
{
992
 
  bzero((void*) tm, sizeof(*tm));
 
987
  memset(tm, 0, sizeof(*tm));
993
988
  tm->time_type= time_type;
994
989
}
995
990
 
997
992
/*
998
993
  Functions to convert time/date/datetime value to a string,
999
994
  using default format.
1000
 
  This functions don't check that given MYSQL_TIME structure members are
 
995
  This functions don't check that given DRIZZLE_TIME structure members are
1001
996
  in valid range. If they are not, return value won't reflect any
1002
997
  valid date either. Additionally, make_time doesn't take into
1003
998
  account time->day member: it's assumed that days have been converted
1007
1002
    number of characters written to 'to'
1008
1003
*/
1009
1004
 
1010
 
int my_time_to_str(const MYSQL_TIME *l_time, char *to)
 
1005
int my_time_to_str(const DRIZZLE_TIME *l_time, char *to)
1011
1006
{
1012
 
  uint extra_hours= 0;
1013
 
  return my_sprintf(to, (to, "%s%02u:%02u:%02u",
 
1007
  uint32_t extra_hours= 0;
 
1008
  return sprintf(to, "%s%02u:%02u:%02u",
1014
1009
                         (l_time->neg ? "-" : ""),
1015
1010
                         extra_hours+ l_time->hour,
1016
1011
                         l_time->minute,
1017
 
                         l_time->second));
 
1012
                         l_time->second);
1018
1013
}
1019
1014
 
1020
 
int my_date_to_str(const MYSQL_TIME *l_time, char *to)
 
1015
int my_date_to_str(const DRIZZLE_TIME *l_time, char *to)
1021
1016
{
1022
 
  return my_sprintf(to, (to, "%04u-%02u-%02u",
 
1017
  return sprintf(to, "%04u-%02u-%02u",
1023
1018
                         l_time->year,
1024
1019
                         l_time->month,
1025
 
                         l_time->day));
 
1020
                         l_time->day);
1026
1021
}
1027
1022
 
1028
 
int my_datetime_to_str(const MYSQL_TIME *l_time, char *to)
 
1023
int my_datetime_to_str(const DRIZZLE_TIME *l_time, char *to)
1029
1024
{
1030
 
  return my_sprintf(to, (to, "%04u-%02u-%02u %02u:%02u:%02u",
 
1025
  return sprintf(to, "%04u-%02u-%02u %02u:%02u:%02u",
1031
1026
                         l_time->year,
1032
1027
                         l_time->month,
1033
1028
                         l_time->day,
1034
1029
                         l_time->hour,
1035
1030
                         l_time->minute,
1036
 
                         l_time->second));
 
1031
                         l_time->second);
1037
1032
}
1038
1033
 
1039
1034
 
1048
1043
    The string must have at least MAX_DATE_STRING_REP_LENGTH bytes reserved.
1049
1044
*/
1050
1045
 
1051
 
int my_TIME_to_str(const MYSQL_TIME *l_time, char *to)
 
1046
int my_TIME_to_str(const DRIZZLE_TIME *l_time, char *to)
1052
1047
{
1053
1048
  switch (l_time->time_type) {
1054
 
  case MYSQL_TIMESTAMP_DATETIME:
 
1049
  case DRIZZLE_TIMESTAMP_DATETIME:
1055
1050
    return my_datetime_to_str(l_time, to);
1056
 
  case MYSQL_TIMESTAMP_DATE:
 
1051
  case DRIZZLE_TIMESTAMP_DATE:
1057
1052
    return my_date_to_str(l_time, to);
1058
 
  case MYSQL_TIMESTAMP_TIME:
 
1053
  case DRIZZLE_TIMESTAMP_TIME:
1059
1054
    return my_time_to_str(l_time, to);
1060
 
  case MYSQL_TIMESTAMP_NONE:
1061
 
  case MYSQL_TIMESTAMP_ERROR:
 
1055
  case DRIZZLE_TIMESTAMP_NONE:
 
1056
  case DRIZZLE_TIMESTAMP_ERROR:
1062
1057
    to[0]='\0';
1063
1058
    return 0;
1064
1059
  default:
1065
 
    DBUG_ASSERT(0);
 
1060
    assert(0);
1066
1061
    return 0;
1067
1062
  }
1068
1063
}
1083
1078
 
1084
1079
  DESCRIPTION
1085
1080
    Convert a datetime value of formats YYMMDD, YYYYMMDD, YYMMDDHHMSS,
1086
 
    YYYYMMDDHHMMSS to broken-down MYSQL_TIME representation. Return value in
 
1081
    YYYYMMDDHHMMSS to broken-down DRIZZLE_TIME representation. Return value in
1087
1082
    YYYYMMDDHHMMSS format as side-effect.
1088
1083
 
1089
1084
    This function also checks if datetime value fits in DATETIME range.
1094
1089
    Datetime value in YYYYMMDDHHMMSS format.
1095
1090
*/
1096
1091
 
1097
 
int64_t number_to_datetime(int64_t nr, MYSQL_TIME *time_res,
1098
 
                            uint flags, int *was_cut)
 
1092
int64_t number_to_datetime(int64_t nr, DRIZZLE_TIME *time_res,
 
1093
                            uint32_t flags, int *was_cut)
1099
1094
{
1100
1095
  long part1,part2;
1101
1096
 
1102
1097
  *was_cut= 0;
1103
 
  bzero((char*) time_res, sizeof(*time_res));
1104
 
  time_res->time_type=MYSQL_TIMESTAMP_DATE;
 
1098
  memset(time_res, 0, sizeof(*time_res));
 
1099
  time_res->time_type=DRIZZLE_TIMESTAMP_DATE;
1105
1100
 
1106
1101
  if (nr == 0LL || nr >= 10000101000000LL)
1107
1102
  {
1108
 
    time_res->time_type=MYSQL_TIMESTAMP_DATETIME;
 
1103
    time_res->time_type=DRIZZLE_TIMESTAMP_DATETIME;
1109
1104
    goto ok;
1110
1105
  }
1111
1106
  if (nr < 101)
1132
1127
  if (nr < 101000000L)
1133
1128
    goto err;
1134
1129
 
1135
 
  time_res->time_type=MYSQL_TIMESTAMP_DATETIME;
 
1130
  time_res->time_type=DRIZZLE_TIMESTAMP_DATETIME;
1136
1131
 
1137
1132
  if (nr <= (YY_PART_YEAR-1) * 10000000000LL + 1231235959LL)
1138
1133
  {
1172
1167
 
1173
1168
/* Convert time value to integer in YYYYMMDDHHMMSS format */
1174
1169
 
1175
 
uint64_t TIME_to_uint64_t_datetime(const MYSQL_TIME *my_time)
 
1170
uint64_t TIME_to_uint64_t_datetime(const DRIZZLE_TIME *my_time)
1176
1171
{
1177
1172
  return ((uint64_t) (my_time->year * 10000UL +
1178
1173
                       my_time->month * 100UL +
1183
1178
}
1184
1179
 
1185
1180
 
1186
 
/* Convert MYSQL_TIME value to integer in YYYYMMDD format */
 
1181
/* Convert DRIZZLE_TIME value to integer in YYYYMMDD format */
1187
1182
 
1188
 
uint64_t TIME_to_uint64_t_date(const MYSQL_TIME *my_time)
 
1183
uint64_t TIME_to_uint64_t_date(const DRIZZLE_TIME *my_time)
1189
1184
{
1190
1185
  return (uint64_t) (my_time->year * 10000UL + my_time->month * 100UL +
1191
1186
                      my_time->day);
1193
1188
 
1194
1189
 
1195
1190
/*
1196
 
  Convert MYSQL_TIME value to integer in HHMMSS format.
 
1191
  Convert DRIZZLE_TIME value to integer in HHMMSS format.
1197
1192
  This function doesn't take into account time->day member:
1198
1193
  it's assumed that days have been converted to hours already.
1199
1194
*/
1200
1195
 
1201
 
uint64_t TIME_to_uint64_t_time(const MYSQL_TIME *my_time)
 
1196
uint64_t TIME_to_uint64_t_time(const DRIZZLE_TIME *my_time)
1202
1197
{
1203
1198
  return (uint64_t) (my_time->hour * 10000UL +
1204
1199
                      my_time->minute * 100UL +
1207
1202
 
1208
1203
 
1209
1204
/*
1210
 
  Convert struct MYSQL_TIME (date and time split into year/month/day/hour/...
 
1205
  Convert struct DRIZZLE_TIME (date and time split into year/month/day/hour/...
1211
1206
  to a number in format YYYYMMDDHHMMSS (DATETIME),
1212
1207
  YYYYMMDD (DATE)  or HHMMSS (TIME).
1213
1208
 
1221
1216
    SELECT ?+1;
1222
1217
 
1223
1218
  NOTE
1224
 
    This function doesn't check that given MYSQL_TIME structure members are
 
1219
    This function doesn't check that given DRIZZLE_TIME structure members are
1225
1220
    in valid range. If they are not, return value won't reflect any
1226
1221
    valid date either.
1227
1222
*/
1228
1223
 
1229
 
uint64_t TIME_to_uint64_t(const MYSQL_TIME *my_time)
 
1224
uint64_t TIME_to_uint64_t(const DRIZZLE_TIME *my_time)
1230
1225
{
1231
1226
  switch (my_time->time_type) {
1232
 
  case MYSQL_TIMESTAMP_DATETIME:
 
1227
  case DRIZZLE_TIMESTAMP_DATETIME:
1233
1228
    return TIME_to_uint64_t_datetime(my_time);
1234
 
  case MYSQL_TIMESTAMP_DATE:
 
1229
  case DRIZZLE_TIMESTAMP_DATE:
1235
1230
    return TIME_to_uint64_t_date(my_time);
1236
 
  case MYSQL_TIMESTAMP_TIME:
 
1231
  case DRIZZLE_TIMESTAMP_TIME:
1237
1232
    return TIME_to_uint64_t_time(my_time);
1238
 
  case MYSQL_TIMESTAMP_NONE:
1239
 
  case MYSQL_TIMESTAMP_ERROR:
 
1233
  case DRIZZLE_TIMESTAMP_NONE:
 
1234
  case DRIZZLE_TIMESTAMP_ERROR:
1240
1235
    return 0ULL;
1241
1236
  default:
1242
 
    DBUG_ASSERT(0);
 
1237
    assert(0);
1243
1238
  }
1244
1239
  return 0;
1245
1240
}