~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to libdrizzle/my_time.c

  • Committer: Jim Winstead
  • Date: 2008-07-19 02:56:45 UTC
  • mto: (202.1.8 codestyle)
  • mto: This revision was merged to the branch mainline in revision 207.
  • Revision ID: jimw@mysql.com-20080719025645-w2pwytebgzusjzjb
Various fixes to enable compilation on Mac OS X, and remove the glib dependency.
Temporarily disables tab-completion in the drizzle client until an appropriate
autoconf check can be added/enabled.

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 <mystrings/m_string.h>
18
 
#include <mystrings/m_ctype.h>
19
 
#include <drizzled/util/test.h>
 
17
#include <m_string.h>
 
18
#include <m_ctype.h>
20
19
/* 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 unsigned char internal_format_positions[]=
35
 
{0, 1, 2, 3, 4, 5, 6, (unsigned char) 255};
 
34
static uchar internal_format_positions[]=
 
35
{0, 1, 2, 3, 4, 5, 6, (uchar) 255};
36
36
 
37
37
static char time_separator=':';
38
38
 
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};
 
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};
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
 
uint32_t calc_days_in_year(uint32_t year)
 
51
uint calc_days_in_year(uint 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
 
bool check_date(const DRIZZLE_TIME *ltime, bool not_zero_date,
79
 
                   uint32_t flags, int *was_cut)
 
78
my_bool check_date(const MYSQL_TIME *ltime, my_bool not_zero_date,
 
79
                   ulong 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 DRIZZLE_TIME value.
 
107
  Convert a timestamp string to a MYSQL_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
 
    DRIZZLE_TIMESTAMP_NONE        String wasn't a timestamp, like
 
148
    MYSQL_TIMESTAMP_NONE        String wasn't a timestamp, like
149
149
                                [DD [HH:[MM:[SS]]]].fraction.
150
150
                                l_time is not changed.
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.
 
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.
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_drizzle_timestamp_type
160
 
str_to_datetime(const char *str, uint32_t length, DRIZZLE_TIME *l_time,
161
 
                uint32_t flags, int *was_cut)
 
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)
162
162
{
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;
 
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;
168
168
  const char *pos, *last_field_pos=NULL;
169
169
  const char *end=str+length;
170
 
  const unsigned char *format_position;
171
 
  bool found_delimitier= 0, found_space= 0;
172
 
  uint32_t frac_pos, frac_len;
 
170
  const uchar *format_position;
 
171
  my_bool found_delimitier= 0, found_space= 0;
 
172
  uint frac_pos, frac_len;
173
173
 
174
174
  *was_cut= 0;
175
175
 
176
176
  /* Skip space at start */
177
 
  for (; str != end && my_isspace(&my_charset_utf8_general_ci, *str) ; str++)
 
177
  for (; str != end && my_isspace(&my_charset_latin1, *str) ; str++)
178
178
    ;
179
 
  if (str == end || ! my_isdigit(&my_charset_utf8_general_ci, *str))
 
179
  if (str == end || ! my_isdigit(&my_charset_latin1, *str))
180
180
  {
181
181
    *was_cut= 1;
182
 
    return(DRIZZLE_TIMESTAMP_NONE);
 
182
    return(MYSQL_TIMESTAMP_NONE);
183
183
  }
184
184
 
185
185
  is_internal_format= 0;
192
192
    (YYYY-MM-DD,  YYYYMMDD, YYYYYMMDDHHMMSS)
193
193
  */
194
194
  for (pos=str;
195
 
       pos != end && (my_isdigit(&my_charset_utf8_general_ci,*pos) || *pos == 'T');
 
195
       pos != end && (my_isdigit(&my_charset_latin1,*pos) || *pos == 'T');
196
196
       pos++)
197
197
    ;
198
198
 
217
217
        We do this by checking if there is two numbers separated by
218
218
        space in the input.
219
219
      */
220
 
      while (pos < end && !my_isspace(&my_charset_utf8_general_ci, *pos))
 
220
      while (pos < end && !my_isspace(&my_charset_latin1, *pos))
221
221
        pos++;
222
 
      while (pos < end && !my_isdigit(&my_charset_utf8_general_ci, *pos))
 
222
      while (pos < end && !my_isdigit(&my_charset_latin1, *pos))
223
223
        pos++;
224
224
      if (pos == end)
225
225
      {
226
226
        if (flags & TIME_DATETIME_ONLY)
227
227
        {
228
228
          *was_cut= 1;
229
 
          return(DRIZZLE_TIMESTAMP_NONE);   /* Can't be a full datetime */
 
229
          return(MYSQL_TIMESTAMP_NONE);   /* Can't be a full datetime */
230
230
        }
231
231
        /* Date field.  Set hour, minutes and seconds to 0 */
232
232
        date[0]= date[1]= date[2]= date[3]= date[4]= 0;
245
245
    2003-03-03 20:00:20 AM
246
246
    20:00:20.000000 AM 03-03-2000
247
247
  */
248
 
  i= cmax((uint) format_position[0], (uint) format_position[1]);
 
248
  i= max((uint) format_position[0], (uint) format_position[1]);
249
249
  set_if_bigger(i, (uint) format_position[2]);
250
250
  allow_space= ((1 << i) | (1 << format_position[6]));
251
251
  allow_space&= (1 | 2 | 4 | 8);
253
253
  not_zero_date= 0;
254
254
  for (i = start_loop;
255
255
       i < MAX_DATE_PARTS-1 && str != end &&
256
 
         my_isdigit(&my_charset_utf8_general_ci,*str);
 
256
         my_isdigit(&my_charset_latin1,*str);
257
257
       i++)
258
258
  {
259
259
    const char *start= str;
260
 
    uint32_t tmp_value= (uint) (unsigned char) (*str++ - '0');
261
 
    while (str != end && my_isdigit(&my_charset_utf8_general_ci,str[0]) &&
 
260
    ulong tmp_value= (uint) (uchar) (*str++ - '0');
 
261
    while (str != end && my_isdigit(&my_charset_latin1,str[0]) &&
262
262
           (!is_internal_format || --field_length))
263
263
    {
264
 
      tmp_value=tmp_value*10 + (uint32_t) (unsigned char) (*str - '0');
 
264
      tmp_value=tmp_value*10 + (ulong) (uchar) (*str - '0');
265
265
      str++;
266
266
    }
267
267
    date_len[i]= (uint) (str - start);
268
268
    if (tmp_value > 999999)                     /* Impossible date part */
269
269
    {
270
270
      *was_cut= 1;
271
 
      return(DRIZZLE_TIMESTAMP_NONE);
 
271
      return(MYSQL_TIMESTAMP_NONE);
272
272
    }
273
273
    date[i]=tmp_value;
274
274
    not_zero_date|= tmp_value;
297
297
      continue;
298
298
    }
299
299
    while (str != end &&
300
 
           (my_ispunct(&my_charset_utf8_general_ci,*str) ||
301
 
            my_isspace(&my_charset_utf8_general_ci,*str)))
 
300
           (my_ispunct(&my_charset_latin1,*str) ||
 
301
            my_isspace(&my_charset_latin1,*str)))
302
302
    {
303
 
      if (my_isspace(&my_charset_utf8_general_ci,*str))
 
303
      if (my_isspace(&my_charset_latin1,*str))
304
304
      {
305
305
        if (!(allow_space & (1 << i)))
306
306
        {
307
307
          *was_cut= 1;
308
 
          return(DRIZZLE_TIMESTAMP_NONE);
 
308
          return(MYSQL_TIMESTAMP_NONE);
309
309
        }
310
310
        found_space= 1;
311
311
      }
326
326
            continue;                           /* Not AM/PM */
327
327
          str+= 2;                              /* Skip AM/PM */
328
328
          /* Skip space after AM/PM */
329
 
          while (str != end && my_isspace(&my_charset_utf8_general_ci,*str))
 
329
          while (str != end && my_isspace(&my_charset_latin1,*str))
330
330
            str++;
331
331
        }
332
332
      }
336
336
  if (found_delimitier && !found_space && (flags & TIME_DATETIME_ONLY))
337
337
  {
338
338
    *was_cut= 1;
339
 
    return(DRIZZLE_TIMESTAMP_NONE);          /* Can't be a datetime */
 
339
    return(MYSQL_TIMESTAMP_NONE);          /* Can't be a datetime */
340
340
  }
341
341
 
342
342
  str= last_field_pos;
354
354
    if (!year_length)                           /* Year must be specified */
355
355
    {
356
356
      *was_cut= 1;
357
 
      return(DRIZZLE_TIMESTAMP_NONE);
 
357
      return(MYSQL_TIMESTAMP_NONE);
358
358
    }
359
359
 
360
360
    l_time->year=               date[(uint) format_position[0]];
370
370
      date[frac_pos]*= (uint) log_10_int[6 - frac_len];
371
371
    l_time->second_part= date[frac_pos];
372
372
 
373
 
    if (format_position[7] != (unsigned char) 255)
 
373
    if (format_position[7] != (uchar) 255)
374
374
    {
375
375
      if (l_time->hour > 12)
376
376
      {
407
407
    {
408
408
      for (; str != end ; str++)
409
409
      {
410
 
        if (!my_isspace(&my_charset_utf8_general_ci, *str))
 
410
        if (!my_isspace(&my_charset_latin1, *str))
411
411
        {
412
412
          not_zero_date= 1;                     /* Give warning */
413
413
          break;
422
422
    goto err;
423
423
 
424
424
  l_time->time_type= (number_of_fields <= 3 ?
425
 
                      DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME);
 
425
                      MYSQL_TIMESTAMP_DATE : MYSQL_TIMESTAMP_DATETIME);
426
426
 
427
427
  for (; str != end ; str++)
428
428
  {
429
 
    if (!my_isspace(&my_charset_utf8_general_ci,*str))
 
429
    if (!my_isspace(&my_charset_latin1,*str))
430
430
    {
431
431
      *was_cut= 1;
432
432
      break;
434
434
  }
435
435
 
436
436
  return(l_time->time_type=
437
 
              (number_of_fields <= 3 ? DRIZZLE_TIMESTAMP_DATE :
438
 
                                       DRIZZLE_TIMESTAMP_DATETIME));
 
437
              (number_of_fields <= 3 ? MYSQL_TIMESTAMP_DATE :
 
438
                                       MYSQL_TIMESTAMP_DATETIME));
439
439
 
440
440
err:
441
 
  memset(l_time, 0, sizeof(*l_time));
442
 
  return(DRIZZLE_TIMESTAMP_ERROR);
 
441
  bzero((char*) l_time, sizeof(*l_time));
 
442
  return(MYSQL_TIMESTAMP_ERROR);
443
443
}
444
444
 
445
445
 
446
446
/*
447
 
 Convert a time string to a DRIZZLE_TIME struct.
 
447
 Convert a time string to a MYSQL_TIME struct.
448
448
 
449
449
  SYNOPSIS
450
450
   str_to_time()
454
454
                        There may be an optional [.second_part] after seconds
455
455
   length               Length of str
456
456
   l_time               Store result here
457
 
   warning              Set DRIZZLE_TIME_WARN_TRUNCATED flag if the input string
 
457
   warning              Set MYSQL_TIME_WARN_TRUNCATED flag if the input string
458
458
                        was cut during conversion, and/or
459
 
                        DRIZZLE_TIME_WARN_OUT_OF_RANGE flag, if the value is
 
459
                        MYSQL_TIME_WARN_OUT_OF_RANGE flag, if the value is
460
460
                        out of range.
461
461
 
462
462
   NOTES
468
468
     1  error
469
469
*/
470
470
 
471
 
bool str_to_time(const char *str, uint32_t length, DRIZZLE_TIME *l_time,
 
471
my_bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
472
472
                    int *warning)
473
473
{
474
 
  uint32_t date[5];
 
474
  ulong date[5];
475
475
  uint64_t value;
476
476
  const char *end=str+length, *end_of_days;
477
 
  bool found_days,found_hours;
478
 
  uint32_t state;
 
477
  my_bool found_days,found_hours;
 
478
  uint state;
479
479
 
480
480
  l_time->neg=0;
481
481
  *warning= 0;
482
 
  for (; str != end && my_isspace(&my_charset_utf8_general_ci,*str) ; str++)
 
482
  for (; str != end && my_isspace(&my_charset_latin1,*str) ; str++)
483
483
    length--;
484
484
  if (str != end && *str == '-')
485
485
  {
494
494
  if (length >= 12)
495
495
  {                                             /* Probably full timestamp */
496
496
    int was_cut;
497
 
    enum enum_drizzle_timestamp_type
 
497
    enum enum_mysql_timestamp_type
498
498
      res= str_to_datetime(str, length, l_time,
499
499
                           (TIME_FUZZY_DATE | TIME_DATETIME_ONLY), &was_cut);
500
 
    if ((int) res >= (int) DRIZZLE_TIMESTAMP_ERROR)
 
500
    if ((int) res >= (int) MYSQL_TIMESTAMP_ERROR)
501
501
    {
502
502
      if (was_cut)
503
 
        *warning|= DRIZZLE_TIME_WARN_TRUNCATED;
504
 
      return res == DRIZZLE_TIMESTAMP_ERROR;
 
503
        *warning|= MYSQL_TIME_WARN_TRUNCATED;
 
504
      return res == MYSQL_TIMESTAMP_ERROR;
505
505
    }
506
506
  }
507
507
 
508
508
  /* Not a timestamp. Try to get this as a DAYS_TO_SECOND string */
509
 
  for (value=0; str != end && my_isdigit(&my_charset_utf8_general_ci,*str) ; str++)
 
509
  for (value=0; str != end && my_isdigit(&my_charset_latin1,*str) ; str++)
510
510
    value=value*10L + (long) (*str - '0');
511
511
 
512
512
  /* Skip all space after 'days' */
513
513
  end_of_days= str;
514
 
  for (; str != end && my_isspace(&my_charset_utf8_general_ci, str[0]) ; str++)
 
514
  for (; str != end && my_isspace(&my_charset_latin1, str[0]) ; str++)
515
515
    ;
516
516
 
517
517
  found_days=found_hours=0;
518
518
  if ((uint) (end-str) > 1 && str != end_of_days &&
519
 
      my_isdigit(&my_charset_utf8_general_ci, *str))
 
519
      my_isdigit(&my_charset_latin1, *str))
520
520
  {                                             /* Found days part */
521
 
    date[0]= (uint32_t) value;
 
521
    date[0]= (ulong) value;
522
522
    state= 1;                                   /* Assume next is hours */
523
523
    found_days= 1;
524
524
  }
525
525
  else if ((end-str) > 1 &&  *str == time_separator &&
526
 
           my_isdigit(&my_charset_utf8_general_ci, str[1]))
 
526
           my_isdigit(&my_charset_latin1, str[1]))
527
527
  {
528
528
    date[0]= 0;                                 /* Assume we found hours */
529
 
    date[1]= (uint32_t) value;
 
529
    date[1]= (ulong) value;
530
530
    state=2;
531
531
    found_hours=1;
532
532
    str++;                                      /* skip ':' */
535
535
  {
536
536
    /* String given as one number; assume HHMMSS format */
537
537
    date[0]= 0;
538
 
    date[1]= (uint32_t) (value/10000);
539
 
    date[2]= (uint32_t) (value/100 % 100);
540
 
    date[3]= (uint32_t) (value % 100);
 
538
    date[1]= (ulong) (value/10000);
 
539
    date[2]= (ulong) (value/100 % 100);
 
540
    date[3]= (ulong) (value % 100);
541
541
    state=4;
542
542
    goto fractional;
543
543
  }
545
545
  /* Read hours, minutes and seconds */
546
546
  for (;;)
547
547
  {
548
 
    for (value=0; str != end && my_isdigit(&my_charset_utf8_general_ci,*str) ; str++)
 
548
    for (value=0; str != end && my_isdigit(&my_charset_latin1,*str) ; str++)
549
549
      value=value*10L + (long) (*str - '0');
550
 
    date[state++]= (uint32_t) value;
 
550
    date[state++]= (ulong) value;
551
551
    if (state == 4 || (end-str) < 2 || *str != time_separator ||
552
 
        !my_isdigit(&my_charset_utf8_general_ci,str[1]))
 
552
        !my_isdigit(&my_charset_latin1,str[1]))
553
553
      break;
554
554
    str++;                                      /* Skip time_separator (':') */
555
555
  }
559
559
    /* Fix the date to assume that seconds was given */
560
560
    if (!found_hours && !found_days)
561
561
    {
562
 
      bmove_upp((unsigned char*) (date+4), (unsigned char*) (date+state),
 
562
      bmove_upp((uchar*) (date+4), (uchar*) (date+state),
563
563
                sizeof(long)*(state-1));
564
 
      memset(date, 0, sizeof(long)*(4-state));
 
564
      bzero((uchar*) date, sizeof(long)*(4-state));
565
565
    }
566
566
    else
567
 
      memset(date+state, 0, sizeof(long)*(4-state));
 
567
      bzero((uchar*) (date+state), sizeof(long)*(4-state));
568
568
  }
569
569
 
570
570
fractional:
571
571
  /* Get fractional second part */
572
 
  if ((end-str) >= 2 && *str == '.' && my_isdigit(&my_charset_utf8_general_ci,str[1]))
 
572
  if ((end-str) >= 2 && *str == '.' && my_isdigit(&my_charset_latin1,str[1]))
573
573
  {
574
574
    int field_length= 5;
575
 
    str++; value=(uint) (unsigned char) (*str - '0');
576
 
    while (++str != end && my_isdigit(&my_charset_utf8_general_ci, *str))
 
575
    str++; value=(uint) (uchar) (*str - '0');
 
576
    while (++str != end && my_isdigit(&my_charset_latin1, *str))
577
577
    {
578
578
      if (field_length-- > 0)
579
 
        value= value*10 + (uint) (unsigned char) (*str - '0');
 
579
        value= value*10 + (uint) (uchar) (*str - '0');
580
580
    }
581
581
    if (field_length > 0)
582
582
      value*= (long) log_10_int[field_length];
583
583
    else if (field_length < 0)
584
 
      *warning|= DRIZZLE_TIME_WARN_TRUNCATED;
585
 
    date[4]= (uint32_t) value;
 
584
      *warning|= MYSQL_TIME_WARN_TRUNCATED;
 
585
    date[4]= (ulong) value;
586
586
  }
587
587
  else
588
588
    date[4]=0;
591
591
  /* (may occur as result of %g formatting of time value) */
592
592
  if ((end - str) > 1 &&
593
593
      (*str == 'e' || *str == 'E') &&
594
 
      (my_isdigit(&my_charset_utf8_general_ci, str[1]) ||
 
594
      (my_isdigit(&my_charset_latin1, str[1]) ||
595
595
       ((str[1] == '-' || str[1] == '+') &&
596
596
        (end - str) > 2 &&
597
 
        my_isdigit(&my_charset_utf8_general_ci, str[2]))))
 
597
        my_isdigit(&my_charset_latin1, str[2]))))
598
598
    return 1;
599
599
 
600
600
  if (internal_format_positions[7] != 255)
601
601
  {
602
602
    /* Read a possible AM/PM */
603
 
    while (str != end && my_isspace(&my_charset_utf8_general_ci, *str))
 
603
    while (str != end && my_isspace(&my_charset_latin1, *str))
604
604
      str++;
605
605
    if (str+2 <= end && (str[1] == 'M' || str[1] == 'm'))
606
606
    {
627
627
  l_time->minute=       date[2];
628
628
  l_time->second=       date[3];
629
629
  l_time->second_part=  date[4];
630
 
  l_time->time_type= DRIZZLE_TIMESTAMP_TIME;
 
630
  l_time->time_type= MYSQL_TIMESTAMP_TIME;
631
631
 
632
 
  /* Check if the value is valid and fits into DRIZZLE_TIME range */
 
632
  /* Check if the value is valid and fits into MYSQL_TIME range */
633
633
  if (check_time_range(l_time, warning))
634
634
    return 1;
635
635
  
636
 
  /* Check if there is garbage at end of the DRIZZLE_TIME specification */
 
636
  /* Check if there is garbage at end of the MYSQL_TIME specification */
637
637
  if (str != end)
638
638
  {
639
639
    do
640
640
    {
641
 
      if (!my_isspace(&my_charset_utf8_general_ci,*str))
 
641
      if (!my_isspace(&my_charset_latin1,*str))
642
642
      {
643
 
        *warning|= DRIZZLE_TIME_WARN_TRUNCATED;
 
643
        *warning|= MYSQL_TIME_WARN_TRUNCATED;
644
644
        break;
645
645
      }
646
646
    } while (++str != end);
650
650
 
651
651
 
652
652
/*
653
 
  Check 'time' value to lie in the DRIZZLE_TIME range
 
653
  Check 'time' value to lie in the MYSQL_TIME range
654
654
 
655
655
  SYNOPSIS:
656
656
    check_time_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
 
657
    time     pointer to MYSQL_TIME value
 
658
    warning  set MYSQL_TIME_WARN_OUT_OF_RANGE flag if the value is out of range
659
659
 
660
660
  DESCRIPTION
661
661
  If the time value lies outside of the range [-838:59:59, 838:59:59],
662
662
  set it to the closest endpoint of the range and set
663
 
  DRIZZLE_TIME_WARN_OUT_OF_RANGE flag in the 'warning' variable.
 
663
  MYSQL_TIME_WARN_OUT_OF_RANGE flag in the 'warning' variable.
664
664
 
665
665
  RETURN
666
666
    0        time value is valid, but was possibly truncated
667
667
    1        time value is invalid
668
668
*/
669
669
 
670
 
int check_time_range(DRIZZLE_TIME *my_time, int *warning) 
 
670
int check_time_range(struct st_mysql_time *my_time, int *warning) 
671
671
{
672
672
  int64_t hour;
673
673
 
685
685
  my_time->minute= TIME_MAX_MINUTE;
686
686
  my_time->second= TIME_MAX_SECOND;
687
687
  my_time->second_part= 0;
688
 
  *warning|= DRIZZLE_TIME_WARN_OUT_OF_RANGE;
 
688
  *warning|= MYSQL_TIME_WARN_OUT_OF_RANGE;
689
689
  return 0;
690
690
}
691
691
 
700
700
{
701
701
  time_t seconds;
702
702
  struct tm *l_time,tm_tmp;
703
 
  DRIZZLE_TIME my_time;
 
703
  MYSQL_TIME my_time;
704
704
  bool not_used;
705
705
 
706
706
  seconds= (time_t) time((time_t*) 0);
728
728
    Year between 1970-2069
729
729
*/
730
730
 
731
 
uint32_t year_2000_handling(uint32_t year)
 
731
uint year_2000_handling(uint year)
732
732
{
733
733
  if ((year=year+1900) < 1900+YY_PART_YEAR)
734
734
    year+=100;
751
751
    Days since 0000-00-00
752
752
*/
753
753
 
754
 
long calc_daynr(uint32_t year,uint32_t month,uint32_t day)
 
754
long calc_daynr(uint year,uint month,uint day)
755
755
{
756
756
  long delsum;
757
757
  int temp;
769
769
 
770
770
 
771
771
/*
772
 
  Convert time in DRIZZLE_TIME representation in system time zone to its
 
772
  Convert time in MYSQL_TIME representation in system time zone to its
773
773
  my_time_t form (number of seconds in UTC since begginning of Unix Epoch).
774
774
 
775
775
  SYNOPSIS
791
791
    Time in UTC seconds since Unix Epoch representation.
792
792
*/
793
793
my_time_t
794
 
my_system_gmt_sec(const DRIZZLE_TIME *t_src, long *my_timezone,
 
794
my_system_gmt_sec(const MYSQL_TIME *t_src, long *my_timezone,
795
795
                  bool *in_dst_time_gap)
796
796
{
797
 
  uint32_t loop;
 
797
  uint loop;
798
798
  time_t tmp= 0;
799
799
  int shift= 0;
800
 
  DRIZZLE_TIME tmp_time;
801
 
  DRIZZLE_TIME *t= &tmp_time;
 
800
  MYSQL_TIME tmp_time;
 
801
  MYSQL_TIME *t= &tmp_time;
802
802
  struct tm *l_time,tm_tmp;
803
803
  long diff, current_timezone;
804
804
 
806
806
    Use temp variable to avoid trashing input data, which could happen in
807
807
    case of shift required for boundary dates processing.
808
808
  */
809
 
  memcpy(&tmp_time, t_src, sizeof(DRIZZLE_TIME));
 
809
  memcpy(&tmp_time, t_src, sizeof(MYSQL_TIME));
810
810
 
811
811
  if (!validate_timestamp_range(t))
812
812
    return 0;
980
980
} /* my_system_gmt_sec */
981
981
 
982
982
 
983
 
/* Set DRIZZLE_TIME structure to 0000-00-00 00:00:00.000000 */
 
983
/* Set MYSQL_TIME structure to 0000-00-00 00:00:00.000000 */
984
984
 
985
 
void set_zero_time(DRIZZLE_TIME *tm, enum enum_drizzle_timestamp_type time_type)
 
985
void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type)
986
986
{
987
 
  memset(tm, 0, sizeof(*tm));
 
987
  bzero((void*) tm, sizeof(*tm));
988
988
  tm->time_type= time_type;
989
989
}
990
990
 
992
992
/*
993
993
  Functions to convert time/date/datetime value to a string,
994
994
  using default format.
995
 
  This functions don't check that given DRIZZLE_TIME structure members are
 
995
  This functions don't check that given MYSQL_TIME structure members are
996
996
  in valid range. If they are not, return value won't reflect any
997
997
  valid date either. Additionally, make_time doesn't take into
998
998
  account time->day member: it's assumed that days have been converted
1002
1002
    number of characters written to 'to'
1003
1003
*/
1004
1004
 
1005
 
int my_time_to_str(const DRIZZLE_TIME *l_time, char *to)
 
1005
int my_time_to_str(const MYSQL_TIME *l_time, char *to)
1006
1006
{
1007
 
  uint32_t extra_hours= 0;
 
1007
  uint extra_hours= 0;
1008
1008
  return sprintf(to, "%s%02u:%02u:%02u",
1009
1009
                         (l_time->neg ? "-" : ""),
1010
1010
                         extra_hours+ l_time->hour,
1012
1012
                         l_time->second);
1013
1013
}
1014
1014
 
1015
 
int my_date_to_str(const DRIZZLE_TIME *l_time, char *to)
 
1015
int my_date_to_str(const MYSQL_TIME *l_time, char *to)
1016
1016
{
1017
1017
  return sprintf(to, "%04u-%02u-%02u",
1018
1018
                         l_time->year,
1020
1020
                         l_time->day);
1021
1021
}
1022
1022
 
1023
 
int my_datetime_to_str(const DRIZZLE_TIME *l_time, char *to)
 
1023
int my_datetime_to_str(const MYSQL_TIME *l_time, char *to)
1024
1024
{
1025
1025
  return sprintf(to, "%04u-%02u-%02u %02u:%02u:%02u",
1026
1026
                         l_time->year,
1043
1043
    The string must have at least MAX_DATE_STRING_REP_LENGTH bytes reserved.
1044
1044
*/
1045
1045
 
1046
 
int my_TIME_to_str(const DRIZZLE_TIME *l_time, char *to)
 
1046
int my_TIME_to_str(const MYSQL_TIME *l_time, char *to)
1047
1047
{
1048
1048
  switch (l_time->time_type) {
1049
 
  case DRIZZLE_TIMESTAMP_DATETIME:
 
1049
  case MYSQL_TIMESTAMP_DATETIME:
1050
1050
    return my_datetime_to_str(l_time, to);
1051
 
  case DRIZZLE_TIMESTAMP_DATE:
 
1051
  case MYSQL_TIMESTAMP_DATE:
1052
1052
    return my_date_to_str(l_time, to);
1053
 
  case DRIZZLE_TIMESTAMP_TIME:
 
1053
  case MYSQL_TIMESTAMP_TIME:
1054
1054
    return my_time_to_str(l_time, to);
1055
 
  case DRIZZLE_TIMESTAMP_NONE:
1056
 
  case DRIZZLE_TIMESTAMP_ERROR:
 
1055
  case MYSQL_TIMESTAMP_NONE:
 
1056
  case MYSQL_TIMESTAMP_ERROR:
1057
1057
    to[0]='\0';
1058
1058
    return 0;
1059
1059
  default:
1078
1078
 
1079
1079
  DESCRIPTION
1080
1080
    Convert a datetime value of formats YYMMDD, YYYYMMDD, YYMMDDHHMSS,
1081
 
    YYYYMMDDHHMMSS to broken-down DRIZZLE_TIME representation. Return value in
 
1081
    YYYYMMDDHHMMSS to broken-down MYSQL_TIME representation. Return value in
1082
1082
    YYYYMMDDHHMMSS format as side-effect.
1083
1083
 
1084
1084
    This function also checks if datetime value fits in DATETIME range.
1089
1089
    Datetime value in YYYYMMDDHHMMSS format.
1090
1090
*/
1091
1091
 
1092
 
int64_t number_to_datetime(int64_t nr, DRIZZLE_TIME *time_res,
1093
 
                            uint32_t flags, int *was_cut)
 
1092
int64_t number_to_datetime(int64_t nr, MYSQL_TIME *time_res,
 
1093
                            uint flags, int *was_cut)
1094
1094
{
1095
1095
  long part1,part2;
1096
1096
 
1097
1097
  *was_cut= 0;
1098
 
  memset(time_res, 0, sizeof(*time_res));
1099
 
  time_res->time_type=DRIZZLE_TIMESTAMP_DATE;
 
1098
  bzero((char*) time_res, sizeof(*time_res));
 
1099
  time_res->time_type=MYSQL_TIMESTAMP_DATE;
1100
1100
 
1101
1101
  if (nr == 0LL || nr >= 10000101000000LL)
1102
1102
  {
1103
 
    time_res->time_type=DRIZZLE_TIMESTAMP_DATETIME;
 
1103
    time_res->time_type=MYSQL_TIMESTAMP_DATETIME;
1104
1104
    goto ok;
1105
1105
  }
1106
1106
  if (nr < 101)
1127
1127
  if (nr < 101000000L)
1128
1128
    goto err;
1129
1129
 
1130
 
  time_res->time_type=DRIZZLE_TIMESTAMP_DATETIME;
 
1130
  time_res->time_type=MYSQL_TIMESTAMP_DATETIME;
1131
1131
 
1132
1132
  if (nr <= (YY_PART_YEAR-1) * 10000000000LL + 1231235959LL)
1133
1133
  {
1167
1167
 
1168
1168
/* Convert time value to integer in YYYYMMDDHHMMSS format */
1169
1169
 
1170
 
uint64_t TIME_to_uint64_t_datetime(const DRIZZLE_TIME *my_time)
 
1170
uint64_t TIME_to_uint64_t_datetime(const MYSQL_TIME *my_time)
1171
1171
{
1172
1172
  return ((uint64_t) (my_time->year * 10000UL +
1173
1173
                       my_time->month * 100UL +
1178
1178
}
1179
1179
 
1180
1180
 
1181
 
/* Convert DRIZZLE_TIME value to integer in YYYYMMDD format */
 
1181
/* Convert MYSQL_TIME value to integer in YYYYMMDD format */
1182
1182
 
1183
 
uint64_t TIME_to_uint64_t_date(const DRIZZLE_TIME *my_time)
 
1183
uint64_t TIME_to_uint64_t_date(const MYSQL_TIME *my_time)
1184
1184
{
1185
1185
  return (uint64_t) (my_time->year * 10000UL + my_time->month * 100UL +
1186
1186
                      my_time->day);
1188
1188
 
1189
1189
 
1190
1190
/*
1191
 
  Convert DRIZZLE_TIME value to integer in HHMMSS format.
 
1191
  Convert MYSQL_TIME value to integer in HHMMSS format.
1192
1192
  This function doesn't take into account time->day member:
1193
1193
  it's assumed that days have been converted to hours already.
1194
1194
*/
1195
1195
 
1196
 
uint64_t TIME_to_uint64_t_time(const DRIZZLE_TIME *my_time)
 
1196
uint64_t TIME_to_uint64_t_time(const MYSQL_TIME *my_time)
1197
1197
{
1198
1198
  return (uint64_t) (my_time->hour * 10000UL +
1199
1199
                      my_time->minute * 100UL +
1202
1202
 
1203
1203
 
1204
1204
/*
1205
 
  Convert struct DRIZZLE_TIME (date and time split into year/month/day/hour/...
 
1205
  Convert struct MYSQL_TIME (date and time split into year/month/day/hour/...
1206
1206
  to a number in format YYYYMMDDHHMMSS (DATETIME),
1207
1207
  YYYYMMDD (DATE)  or HHMMSS (TIME).
1208
1208
 
1216
1216
    SELECT ?+1;
1217
1217
 
1218
1218
  NOTE
1219
 
    This function doesn't check that given DRIZZLE_TIME structure members are
 
1219
    This function doesn't check that given MYSQL_TIME structure members are
1220
1220
    in valid range. If they are not, return value won't reflect any
1221
1221
    valid date either.
1222
1222
*/
1223
1223
 
1224
 
uint64_t TIME_to_uint64_t(const DRIZZLE_TIME *my_time)
 
1224
uint64_t TIME_to_uint64_t(const MYSQL_TIME *my_time)
1225
1225
{
1226
1226
  switch (my_time->time_type) {
1227
 
  case DRIZZLE_TIMESTAMP_DATETIME:
 
1227
  case MYSQL_TIMESTAMP_DATETIME:
1228
1228
    return TIME_to_uint64_t_datetime(my_time);
1229
 
  case DRIZZLE_TIMESTAMP_DATE:
 
1229
  case MYSQL_TIMESTAMP_DATE:
1230
1230
    return TIME_to_uint64_t_date(my_time);
1231
 
  case DRIZZLE_TIMESTAMP_TIME:
 
1231
  case MYSQL_TIMESTAMP_TIME:
1232
1232
    return TIME_to_uint64_t_time(my_time);
1233
 
  case DRIZZLE_TIMESTAMP_NONE:
1234
 
  case DRIZZLE_TIMESTAMP_ERROR:
 
1233
  case MYSQL_TIMESTAMP_NONE:
 
1234
  case MYSQL_TIMESTAMP_ERROR:
1235
1235
    return 0ULL;
1236
1236
  default:
1237
1237
    assert(0);