13
13
along with this program; if not, write to the Free Software
14
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
#include "mysys_priv.h"
17
20
#include <mystrings/m_string.h>
18
21
#include <mystrings/m_ctype.h>
22
#include <drizzled/util/test.h>
19
25
/* Windows version of localtime_r() is declared in my_ptrhead.h */
21
27
uint64_t log_10_int[20]=
31
37
/* Position for YYYY-DD-MM HH-MM-DD.FFFFFF AM in default format */
33
static uchar internal_format_positions[]=
34
{0, 1, 2, 3, 4, 5, 6, (uchar) 255};
39
static unsigned char internal_format_positions[]=
40
{0, 1, 2, 3, 4, 5, 6, (unsigned char) 255};
36
42
static char time_separator=':';
38
44
static uint32_t const days_at_timestart=719528; /* daynr at 1970.01.01 */
39
uchar days_in_month[]= {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0};
45
unsigned char days_in_month[]= {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0};
42
Offset of system time zone from UTC in seconds used to speed up
48
Offset of system time zone from UTC in seconds used to speed up
43
49
work of my_system_gmt_sec() function.
45
51
static long my_time_zone=0;
156
162
#define MAX_DATE_PARTS 8
158
164
enum enum_drizzle_timestamp_type
159
str_to_datetime(const char *str, uint length, DRIZZLE_TIME *l_time,
160
uint flags, int *was_cut)
165
str_to_datetime(const char *str, uint32_t length, DRIZZLE_TIME *l_time,
166
uint32_t flags, int *was_cut)
162
uint field_length, year_length=4, digits, i, number_of_fields;
163
uint date[MAX_DATE_PARTS], date_len[MAX_DATE_PARTS];
164
uint add_hours= 0, start_loop;
168
uint32_t field_length, year_length=4, digits, i, number_of_fields;
169
uint32_t date[MAX_DATE_PARTS], date_len[MAX_DATE_PARTS];
170
uint32_t add_hours= 0, start_loop;
165
171
uint32_t not_zero_date, allow_space;
166
172
bool is_internal_format;
167
173
const char *pos, *last_field_pos=NULL;
168
174
const char *end=str+length;
169
const uchar *format_position;
175
const unsigned char *format_position;
170
176
bool found_delimitier= 0, found_space= 0;
171
uint frac_pos, frac_len;
177
uint32_t frac_pos, frac_len;
175
181
/* Skip space at start */
176
for (; str != end && my_isspace(&my_charset_latin1, *str) ; str++)
182
for (; str != end && my_isspace(&my_charset_utf8_general_ci, *str) ; str++)
178
if (str == end || ! my_isdigit(&my_charset_latin1, *str))
184
if (str == end || ! my_isdigit(&my_charset_utf8_general_ci, *str))
181
187
return(DRIZZLE_TIMESTAMP_NONE);
191
197
(YYYY-MM-DD, YYYYMMDD, YYYYYMMDDHHMMSS)
194
pos != end && (my_isdigit(&my_charset_latin1,*pos) || *pos == 'T');
200
pos != end && (my_isdigit(&my_charset_utf8_general_ci,*pos) || *pos == 'T');
216
222
We do this by checking if there is two numbers separated by
217
223
space in the input.
219
while (pos < end && !my_isspace(&my_charset_latin1, *pos))
225
while (pos < end && !my_isspace(&my_charset_utf8_general_ci, *pos))
221
while (pos < end && !my_isdigit(&my_charset_latin1, *pos))
227
while (pos < end && !my_isdigit(&my_charset_utf8_general_ci, *pos))
244
250
2003-03-03 20:00:20 AM
245
251
20:00:20.000000 AM 03-03-2000
247
i= max((uint) format_position[0], (uint) format_position[1]);
253
i= cmax((uint) format_position[0], (uint) format_position[1]);
248
254
set_if_bigger(i, (uint) format_position[2]);
249
255
allow_space= ((1 << i) | (1 << format_position[6]));
250
256
allow_space&= (1 | 2 | 4 | 8);
252
258
not_zero_date= 0;
253
259
for (i = start_loop;
254
260
i < MAX_DATE_PARTS-1 && str != end &&
255
my_isdigit(&my_charset_latin1,*str);
261
my_isdigit(&my_charset_utf8_general_ci,*str);
258
264
const char *start= str;
259
uint32_t tmp_value= (uint) (uchar) (*str++ - '0');
260
while (str != end && my_isdigit(&my_charset_latin1,str[0]) &&
265
uint32_t tmp_value= (uint) (unsigned char) (*str++ - '0');
266
while (str != end && my_isdigit(&my_charset_utf8_general_ci,str[0]) &&
261
267
(!is_internal_format || --field_length))
263
tmp_value=tmp_value*10 + (uint32_t) (uchar) (*str - '0');
269
tmp_value=tmp_value*10 + (uint32_t) (unsigned char) (*str - '0');
266
272
date_len[i]= (uint) (str - start);
298
304
while (str != end &&
299
(my_ispunct(&my_charset_latin1,*str) ||
300
my_isspace(&my_charset_latin1,*str)))
305
(my_ispunct(&my_charset_utf8_general_ci,*str) ||
306
my_isspace(&my_charset_utf8_general_ci,*str)))
302
if (my_isspace(&my_charset_latin1,*str))
308
if (my_isspace(&my_charset_utf8_general_ci,*str))
304
310
if (!(allow_space & (1 << i)))
325
331
continue; /* Not AM/PM */
326
332
str+= 2; /* Skip AM/PM */
327
333
/* Skip space after AM/PM */
328
while (str != end && my_isspace(&my_charset_latin1,*str))
334
while (str != end && my_isspace(&my_charset_utf8_general_ci,*str))
407
413
for (; str != end ; str++)
409
if (!my_isspace(&my_charset_latin1, *str))
415
if (!my_isspace(&my_charset_utf8_general_ci, *str))
411
417
not_zero_date= 1; /* Give warning */
470
bool str_to_time(const char *str, uint length, DRIZZLE_TIME *l_time,
476
bool str_to_time(const char *str, uint32_t length, DRIZZLE_TIME *l_time,
473
479
uint32_t date[5];
475
481
const char *end=str+length, *end_of_days;
476
482
bool found_days,found_hours;
481
for (; str != end && my_isspace(&my_charset_latin1,*str) ; str++)
487
for (; str != end && my_isspace(&my_charset_utf8_general_ci,*str) ; str++)
483
489
if (str != end && *str == '-')
507
513
/* Not a timestamp. Try to get this as a DAYS_TO_SECOND string */
508
for (value=0; str != end && my_isdigit(&my_charset_latin1,*str) ; str++)
514
for (value=0; str != end && my_isdigit(&my_charset_utf8_general_ci,*str) ; str++)
509
515
value=value*10L + (long) (*str - '0');
511
517
/* Skip all space after 'days' */
512
518
end_of_days= str;
513
for (; str != end && my_isspace(&my_charset_latin1, str[0]) ; str++)
519
for (; str != end && my_isspace(&my_charset_utf8_general_ci, str[0]) ; str++)
516
522
found_days=found_hours=0;
517
523
if ((uint) (end-str) > 1 && str != end_of_days &&
518
my_isdigit(&my_charset_latin1, *str))
524
my_isdigit(&my_charset_utf8_general_ci, *str))
519
525
{ /* Found days part */
520
526
date[0]= (uint32_t) value;
521
527
state= 1; /* Assume next is hours */
524
530
else if ((end-str) > 1 && *str == time_separator &&
525
my_isdigit(&my_charset_latin1, str[1]))
531
my_isdigit(&my_charset_utf8_general_ci, str[1]))
527
533
date[0]= 0; /* Assume we found hours */
528
534
date[1]= (uint32_t) value;
544
550
/* Read hours, minutes and seconds */
547
for (value=0; str != end && my_isdigit(&my_charset_latin1,*str) ; str++)
553
for (value=0; str != end && my_isdigit(&my_charset_utf8_general_ci,*str) ; str++)
548
554
value=value*10L + (long) (*str - '0');
549
555
date[state++]= (uint32_t) value;
550
556
if (state == 4 || (end-str) < 2 || *str != time_separator ||
551
!my_isdigit(&my_charset_latin1,str[1]))
557
!my_isdigit(&my_charset_utf8_general_ci,str[1]))
553
559
str++; /* Skip time_separator (':') */
558
564
/* Fix the date to assume that seconds was given */
559
565
if (!found_hours && !found_days)
561
bmove_upp((uchar*) (date+4), (uchar*) (date+state),
567
bmove_upp((unsigned char*) (date+4), (unsigned char*) (date+state),
562
568
sizeof(long)*(state-1));
563
569
memset(date, 0, sizeof(long)*(4-state));
570
576
/* Get fractional second part */
571
if ((end-str) >= 2 && *str == '.' && my_isdigit(&my_charset_latin1,str[1]))
577
if ((end-str) >= 2 && *str == '.' && my_isdigit(&my_charset_utf8_general_ci,str[1]))
573
579
int field_length= 5;
574
str++; value=(uint) (uchar) (*str - '0');
575
while (++str != end && my_isdigit(&my_charset_latin1, *str))
580
str++; value=(uint) (unsigned char) (*str - '0');
581
while (++str != end && my_isdigit(&my_charset_utf8_general_ci, *str))
577
583
if (field_length-- > 0)
578
value= value*10 + (uint) (uchar) (*str - '0');
584
value= value*10 + (uint) (unsigned char) (*str - '0');
580
586
if (field_length > 0)
581
587
value*= (long) log_10_int[field_length];
589
595
/* Check for exponent part: E<gigit> | E<sign><digit> */
590
596
/* (may occur as result of %g formatting of time value) */
591
597
if ((end - str) > 1 &&
592
598
(*str == 'e' || *str == 'E') &&
593
(my_isdigit(&my_charset_latin1, str[1]) ||
599
(my_isdigit(&my_charset_utf8_general_ci, str[1]) ||
594
600
((str[1] == '-' || str[1] == '+') &&
595
601
(end - str) > 2 &&
596
my_isdigit(&my_charset_latin1, str[2]))))
602
my_isdigit(&my_charset_utf8_general_ci, str[2]))))
599
605
if (internal_format_positions[7] != 255)
601
607
/* Read a possible AM/PM */
602
while (str != end && my_isspace(&my_charset_latin1, *str))
608
while (str != end && my_isspace(&my_charset_utf8_general_ci, *str))
604
610
if (str+2 <= end && (str[1] == 'M' || str[1] == 'm'))
631
637
/* Check if the value is valid and fits into DRIZZLE_TIME range */
632
638
if (check_time_range(l_time, warning))
635
641
/* Check if there is garbage at end of the DRIZZLE_TIME specification */
640
if (!my_isspace(&my_charset_latin1,*str))
646
if (!my_isspace(&my_charset_utf8_general_ci,*str))
642
648
*warning|= DRIZZLE_TIME_WARN_TRUNCATED;
779
785
in_dst_time_gap - set to true if time falls into spring time-gap
782
The idea is to cache the time zone offset from UTC (including daylight
783
saving time) for the next call to make things faster. But currently we
784
just calculate this offset during startup (by calling init_time()
788
The idea is to cache the time zone offset from UTC (including daylight
789
saving time) for the next call to make things faster. But currently we
790
just calculate this offset during startup (by calling init_time()
785
791
function) and use it all the time.
786
792
Time value provided should be legal time value (e.g. '2003-01-01 25:00:00'
1004
1010
int my_time_to_str(const DRIZZLE_TIME *l_time, char *to)
1006
uint extra_hours= 0;
1012
uint32_t extra_hours= 0;
1007
1013
return sprintf(to, "%s%02u:%02u:%02u",
1008
1014
(l_time->neg ? "-" : ""),
1009
1015
extra_hours+ l_time->hour,
1091
1097
int64_t number_to_datetime(int64_t nr, DRIZZLE_TIME *time_res,
1092
uint flags, int *was_cut)
1098
uint32_t flags, int *was_cut)
1094
1100
long part1,part2;