32
32
/* Position for YYYY-DD-MM HH-MM-DD.FFFFFF AM in default format */
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};
37
37
static char time_separator=':';
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};
43
43
Offset of system time zone from UTC in seconds used to speed up
145
145
- The hour part must be specified in hour-minute-second order.
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
157
157
#define MAX_DATE_PARTS 8
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)
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;
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++)
181
if (str == end || ! my_isdigit(&my_charset_latin1, *str))
179
if (str == end || ! my_isdigit(&my_charset_utf8_general_ci, *str))
184
DBUG_RETURN(MYSQL_TIMESTAMP_NONE);
182
return(DRIZZLE_TIMESTAMP_NONE);
187
185
is_internal_format= 0;
219
217
We do this by checking if there is two numbers separated by
220
218
space in the input.
222
while (pos < end && !my_isspace(&my_charset_latin1, *pos))
220
while (pos < end && !my_isspace(&my_charset_utf8_general_ci, *pos))
224
while (pos < end && !my_isdigit(&my_charset_latin1, *pos))
222
while (pos < end && !my_isdigit(&my_charset_utf8_general_ci, *pos))
228
226
if (flags & TIME_DATETIME_ONLY)
231
DBUG_RETURN(MYSQL_TIMESTAMP_NONE); /* Can't be a full datetime */
229
return(DRIZZLE_TIMESTAMP_NONE); /* Can't be a full datetime */
233
231
/* Date field. Set hour, minutes and seconds to 0 */
234
232
date[0]= date[1]= date[2]= date[3]= date[4]= 0;
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);
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))
266
tmp_value=tmp_value*10 + (ulong) (uchar) (*str - '0');
264
tmp_value=tmp_value*10 + (uint32_t) (unsigned char) (*str - '0');
269
267
date_len[i]= (uint) (str - start);
270
268
if (tmp_value > 999999) /* Impossible date part */
273
DBUG_RETURN(MYSQL_TIMESTAMP_NONE);
271
return(DRIZZLE_TIMESTAMP_NONE);
275
273
date[i]=tmp_value;
276
274
not_zero_date|= tmp_value;
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)))
305
if (my_isspace(&my_charset_latin1,*str))
303
if (my_isspace(&my_charset_utf8_general_ci,*str))
307
305
if (!(allow_space & (1 << i)))
310
DBUG_RETURN(MYSQL_TIMESTAMP_NONE);
308
return(DRIZZLE_TIMESTAMP_NONE);
426
424
l_time->time_type= (number_of_fields <= 3 ?
427
MYSQL_TIMESTAMP_DATE : MYSQL_TIMESTAMP_DATETIME);
425
DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME);
429
427
for (; str != end ; str++)
431
if (!my_isspace(&my_charset_latin1,*str))
429
if (!my_isspace(&my_charset_utf8_general_ci,*str))
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));
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);
449
Convert a time string to a MYSQL_TIME struct.
447
Convert a time string to a DRIZZLE_TIME struct.
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,
478
476
const char *end=str+length, *end_of_days;
479
my_bool found_days,found_hours;
477
bool found_days,found_hours;
484
for (; str != end && my_isspace(&my_charset_latin1,*str) ; str++)
482
for (; str != end && my_isspace(&my_charset_utf8_general_ci,*str) ; str++)
486
484
if (str != end && *str == '-')
496
494
if (length >= 12)
497
495
{ /* Probably full timestamp */
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)
505
*warning|= MYSQL_TIME_WARN_TRUNCATED;
506
return res == MYSQL_TIMESTAMP_ERROR;
503
*warning|= DRIZZLE_TIME_WARN_TRUNCATED;
504
return res == DRIZZLE_TIMESTAMP_ERROR;
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');
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++)
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 */
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]))
530
528
date[0]= 0; /* Assume we found hours */
531
date[1]= (ulong) value;
529
date[1]= (uint32_t) value;
534
532
str++; /* skip ':' */
547
545
/* Read hours, minutes and seconds */
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]))
556
554
str++; /* Skip time_separator (':') */
561
559
/* Fix the date to assume that seconds was given */
562
560
if (!found_hours && !found_days)
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));
569
bzero((uchar*) (date+state), sizeof(long)*(4-state));
567
memset(date+state, 0, sizeof(long)*(4-state));
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]))
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))
580
578
if (field_length-- > 0)
581
value= value*10 + (uint) (uchar) (*str - '0');
579
value= value*10 + (uint) (unsigned char) (*str - '0');
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;
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]))))
602
600
if (internal_format_positions[7] != 255)
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))
607
605
if (str+2 <= end && (str[1] == 'M' || str[1] == 'm'))
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;
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))
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 */
643
if (!my_isspace(&my_charset_latin1,*str))
641
if (!my_isspace(&my_charset_utf8_general_ci,*str))
645
*warning|= MYSQL_TIME_WARN_TRUNCATED;
643
*warning|= DRIZZLE_TIME_WARN_TRUNCATED;
648
646
} while (++str != end);
655
Check 'time' value to lie in the MYSQL_TIME range
653
Check 'time' value to lie in the DRIZZLE_TIME range
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
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.
668
666
0 time value is valid, but was possibly truncated
669
667
1 time value is invalid
672
int check_time_range(struct st_mysql_time *my_time, int *warning)
670
int check_time_range(DRIZZLE_TIME *my_time, int *warning)
753
751
Days since 0000-00-00
756
long calc_daynr(uint year,uint month,uint day)
754
long calc_daynr(uint32_t year,uint32_t month,uint32_t day)
760
DBUG_ENTER("calc_daynr");
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);
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 */
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).
796
791
Time in UTC seconds since Unix Epoch representation.
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)
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;
985
980
} /* my_system_gmt_sec */
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 */
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)
992
bzero((void*) tm, sizeof(*tm));
987
memset(tm, 0, sizeof(*tm));
993
988
tm->time_type= time_type;
1007
1002
number of characters written to 'to'
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)
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,
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)
1022
return my_sprintf(to, (to, "%04u-%02u-%02u",
1017
return sprintf(to, "%04u-%02u-%02u",
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)
1030
return my_sprintf(to, (to, "%04u-%02u-%02u %02u:%02u:%02u",
1025
return sprintf(to, "%04u-%02u-%02u %02u:%02u:%02u",
1035
1030
l_time->minute,
1048
1043
The string must have at least MAX_DATE_STRING_REP_LENGTH bytes reserved.
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)
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:
1094
1089
Datetime value in YYYYMMDDHHMMSS format.
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)
1100
1095
long part1,part2;
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;
1106
1101
if (nr == 0LL || nr >= 10000101000000LL)
1108
time_res->time_type=MYSQL_TIMESTAMP_DATETIME;
1103
time_res->time_type=DRIZZLE_TIMESTAMP_DATETIME;
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.
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)
1203
1198
return (uint64_t) (my_time->hour * 10000UL +
1204
1199
my_time->minute * 100UL +
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.
1229
uint64_t TIME_to_uint64_t(const MYSQL_TIME *my_time)
1224
uint64_t TIME_to_uint64_t(const DRIZZLE_TIME *my_time)
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: