19 #include <myisampack.h>
21 #include <my_pthread.h>
23 ulonglong log_10_int[20]=
25 1, 10, 100, 1000, 10000UL, 100000UL, 1000000UL, 10000000UL,
26 ULL(100000000), ULL(1000000000), ULL(10000000000), ULL(100000000000),
27 ULL(1000000000000), ULL(10000000000000), ULL(100000000000000),
28 ULL(1000000000000000), ULL(10000000000000000), ULL(100000000000000000),
29 ULL(1000000000000000000), ULL(10000000000000000000)
33 const char my_zero_datetime6[]=
"0000-00-00 00:00:00.000000";
38 static uchar internal_format_positions[]=
39 {0, 1, 2, 3, 4, 5, 6, (uchar) 255};
41 static char time_separator=
':';
43 static ulong
const days_at_timestart=719528;
44 uchar days_in_month[]= {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0};
50 static long my_time_zone=0;
55 uint calc_days_in_year(uint year)
57 return ((year & 3) == 0 && (year%100 || (year%400 == 0 && year)) ?
68 enum enum_mysql_timestamp_type time_type)
70 memset(tm, 0,
sizeof(*tm));
71 tm->time_type= time_type;
81 tm->hour= TIME_MAX_HOUR;
82 tm->minute= TIME_MAX_MINUTE;
83 tm->second= TIME_MAX_SECOND;
94 set_zero_time(tm, MYSQL_TIMESTAMP_TIME);
120 my_bool check_date(
const MYSQL_TIME *ltime, my_bool not_zero_date,
121 ulonglong
flags,
int *was_cut)
125 if (((flags & TIME_NO_ZERO_IN_DATE) || !(flags & TIME_FUZZY_DATE)) &&
126 (ltime->month == 0 || ltime->day == 0))
128 *was_cut= MYSQL_TIME_WARN_ZERO_IN_DATE;
131 else if ((!(flags & TIME_INVALID_DATES) &&
132 ltime->month && ltime->day > days_in_month[ltime->month-1] &&
133 (ltime->month != 2 || calc_days_in_year(ltime->year) != 366 ||
136 *was_cut= MYSQL_TIME_WARN_OUT_OF_RANGE;
140 else if (flags & TIME_NO_ZERO_DATE)
142 *was_cut= MYSQL_TIME_WARN_ZERO_DATE;
155 inline my_bool check_time_mmssff_range(
const MYSQL_TIME *ltime)
157 return ltime->minute >= 60 || ltime->second >= 60 ||
174 inline my_bool check_time_range_quick(
const MYSQL_TIME *ltime)
176 longlong hour= (longlong) ltime->hour + 24LL * ltime->day;
178 DBUG_ASSERT(!check_time_mmssff_range(ltime));
179 if (hour <= TIME_MAX_HOUR &&
180 (hour != TIME_MAX_HOUR || ltime->minute != TIME_MAX_MINUTE ||
181 ltime->second != TIME_MAX_SECOND || !ltime->
second_part))
194 my_bool check_datetime_range(
const MYSQL_TIME *ltime)
201 ltime->year > 9999 || ltime->month > 12 || ltime->day > 31 ||
202 ltime->minute > 59 || ltime->second > 59 || ltime->
second_part > 999999 ||
204 (ltime->time_type == MYSQL_TIMESTAMP_TIME ? TIME_MAX_HOUR : 23));
266 #define MAX_DATE_PARTS 8
269 str_to_datetime(
const char *str, uint length,
MYSQL_TIME *l_time,
272 uint field_length, UNINIT_VAR(year_length), digits,
i, number_of_fields;
273 uint date[MAX_DATE_PARTS], date_len[MAX_DATE_PARTS];
274 uint add_hours= 0, start_loop;
275 ulong not_zero_date, allow_space;
276 my_bool is_internal_format;
277 const char *pos, *UNINIT_VAR(last_field_pos);
278 const char *end=str+length;
279 const uchar *format_position;
280 my_bool found_delimitier= 0, found_space= 0;
281 uint frac_pos, frac_len;
282 DBUG_ENTER(
"str_to_datetime");
283 DBUG_PRINT(
"ENTER",(
"str: %.*s",length,str));
285 LINT_INIT(field_length);
287 my_time_status_init(status);
290 for (; str != end && my_isspace(&my_charset_latin1, *str) ; str++)
292 if (str == end || ! my_isdigit(&my_charset_latin1, *str))
294 status->warnings= MYSQL_TIME_WARN_TRUNCATED;
295 l_time->time_type= MYSQL_TIMESTAMP_NONE;
299 is_internal_format= 0;
301 format_position= internal_format_positions;
309 pos != end && (my_isdigit(&my_charset_latin1,*pos) || *pos ==
'T');
313 digits= (uint) (pos-str);
315 date_len[format_position[0]]= 0;
316 if (pos == end || *pos ==
'.')
319 year_length= (digits == 4 || digits == 8 || digits >= 14) ? 4 : 2;
320 field_length= year_length;
321 is_internal_format= 1;
322 format_position= internal_format_positions;
326 if (format_position[0] >= 3)
334 while (pos < end && !my_isspace(&my_charset_latin1, *pos))
336 while (pos < end && !my_isdigit(&my_charset_latin1, *pos))
340 if (flags & TIME_DATETIME_ONLY)
342 status->warnings= MYSQL_TIME_WARN_TRUNCATED;
343 l_time->time_type= MYSQL_TIMESTAMP_NONE;
347 date[0]= date[1]= date[2]= date[3]= date[4]= 0;
352 field_length= format_position[0] == 0 ? 4 : 2;
363 i= MY_MAX((uint) format_position[0], (uint) format_position[1]);
364 set_if_bigger(i, (uint) format_position[2]);
365 allow_space= ((1 <<
i) | (1 << format_position[6]));
366 allow_space&= (1 | 2 | 4 | 8 | 64);
370 i < MAX_DATE_PARTS-1 && str != end &&
371 my_isdigit(&my_charset_latin1,*str);
374 const char *start= str;
375 ulong tmp_value= (uint) (uchar) (*str++ -
'0');
384 my_bool scan_until_delim= !is_internal_format &&
385 ((i != format_position[6]));
387 while (str != end && my_isdigit(&my_charset_latin1,str[0]) &&
388 (scan_until_delim || --field_length))
390 tmp_value=tmp_value*10 + (ulong) (uchar) (*str -
'0');
393 date_len[
i]= (uint) (str - start);
394 if (tmp_value > 999999)
396 status->warnings= MYSQL_TIME_WARN_TRUNCATED;
397 l_time->time_type= MYSQL_TIMESTAMP_NONE;
401 not_zero_date|= tmp_value;
404 field_length= format_position[i+1] == 0 ? 4 : 2;
406 if ((last_field_pos= str) == end)
412 if (i == format_position[2] && *str ==
'T')
417 if (i == format_position[5])
432 (my_ispunct(&my_charset_latin1,*str) ||
433 my_isspace(&my_charset_latin1,*str)))
435 if (my_isspace(&my_charset_latin1,*str))
437 if (!(allow_space & (1 << i)))
439 status->warnings= MYSQL_TIME_WARN_TRUNCATED;
440 l_time->time_type= MYSQL_TIMESTAMP_NONE;
449 if (i == format_position[6])
452 if (format_position[7] != 255)
454 if (str+2 <= end && (str[1] ==
'M' || str[1] ==
'm'))
456 if (str[0] ==
'p' || str[0] ==
'P')
458 else if (str[0] !=
'a' || str[0] !=
'A')
462 while (str != end && my_isspace(&my_charset_latin1,*str))
469 if (found_delimitier && !found_space && (flags & TIME_DATETIME_ONLY))
471 status->warnings= MYSQL_TIME_WARN_TRUNCATED;
472 l_time->time_type= MYSQL_TIMESTAMP_NONE;
478 number_of_fields= i - start_loop;
479 while (i < MAX_DATE_PARTS)
485 if (!is_internal_format)
487 year_length= date_len[(uint) format_position[0]];
490 status->warnings= MYSQL_TIME_WARN_TRUNCATED;
491 l_time->time_type= MYSQL_TIMESTAMP_NONE;
495 l_time->year= date[(uint) format_position[0]];
496 l_time->month= date[(uint) format_position[1]];
497 l_time->day= date[(uint) format_position[2]];
498 l_time->hour= date[(uint) format_position[3]];
499 l_time->minute= date[(uint) format_position[4]];
500 l_time->second= date[(uint) format_position[5]];
502 frac_pos= (uint) format_position[6];
503 frac_len= date_len[frac_pos];
504 status->fractional_digits= frac_len;
506 date[frac_pos]*= (uint) log_10_int[DATETIME_MAX_DECIMALS - frac_len];
509 if (format_position[7] != (uchar) 255)
511 if (l_time->hour > 12)
513 status->warnings= MYSQL_TIME_WARN_TRUNCATED;
516 l_time->hour= l_time->hour%12 + add_hours;
521 l_time->year= date[0];
522 l_time->month= date[1];
523 l_time->day= date[2];
524 l_time->hour= date[3];
525 l_time->minute= date[4];
526 l_time->second= date[5];
528 date[6]*= (uint) log_10_int[DATETIME_MAX_DECIMALS - date_len[6]];
530 status->fractional_digits= date_len[6];
534 if (year_length == 2 && not_zero_date)
535 l_time->year+= (l_time->year < YY_PART_YEAR ? 2000 : 1900);
541 l_time->time_type= (number_of_fields <= 3 ?
542 MYSQL_TIMESTAMP_DATE : MYSQL_TIMESTAMP_DATETIME);
544 if (number_of_fields < 3 || check_datetime_range(l_time))
549 for (; str != end ; str++)
551 if (!my_isspace(&my_charset_latin1, *str))
558 status->warnings|= not_zero_date ? MYSQL_TIME_WARN_TRUNCATED :
559 MYSQL_TIME_WARN_ZERO_DATE;
563 if (check_date(l_time, not_zero_date != 0, flags, &status->warnings))
567 if (status->fractional_digits == 6 && str != end)
569 if (my_isdigit(&my_charset_latin1, *str))
575 status->nanoseconds= 100 * (int) (*str++ -
'0');
576 for (; str != end && my_isdigit(&my_charset_latin1, *str); str++)
581 for (; str != end ; str++)
583 if (!my_isspace(&my_charset_latin1,*str))
585 status->warnings= MYSQL_TIME_WARN_TRUNCATED;
593 set_zero_time(l_time, MYSQL_TIMESTAMP_ERROR);
625 my_bool str_to_time(
const char *str, uint length,
MYSQL_TIME *l_time,
630 const char *end=str+length, *end_of_days;
631 my_bool found_days,found_hours;
634 my_time_status_init(status);
636 for (; str != end && my_isspace(&my_charset_latin1,*str) ; str++)
638 if (str != end && *str ==
'-')
650 (void) str_to_datetime(str, length, l_time,
651 (TIME_FUZZY_DATE | TIME_DATETIME_ONLY), status);
652 if (l_time->time_type >= MYSQL_TIMESTAMP_ERROR)
653 return l_time->time_type == MYSQL_TIMESTAMP_ERROR;
654 my_time_status_init(status);
658 for (value=0; str != end && my_isdigit(&my_charset_latin1,*str) ; str++)
659 value=value*10L + (
long) (*str -
'0');
661 if (value > UINT_MAX)
666 for (; str != end && my_isspace(&my_charset_latin1, str[0]) ; str++)
670 found_days=found_hours=0;
671 if ((uint) (end-str) > 1 && str != end_of_days &&
672 my_isdigit(&my_charset_latin1, *str))
674 date[0]= (ulong) value;
678 else if ((end-str) > 1 && *str == time_separator &&
679 my_isdigit(&my_charset_latin1, str[1]))
682 date[1]= (ulong) value;
691 date[1]= (ulong) (value/10000);
692 date[2]= (ulong) (value/100 % 100);
693 date[3]= (ulong) (value % 100);
701 for (value=0; str != end && my_isdigit(&my_charset_latin1,*str) ; str++)
702 value=value*10L + (
long) (*str -
'0');
703 date[state++]= (ulong) value;
704 if (state == 4 || (end-str) < 2 || *str != time_separator ||
705 !my_isdigit(&my_charset_latin1,str[1]))
713 if (!found_hours && !found_days)
715 bmove_upp((uchar*) (date+4), (uchar*) (date+state),
716 sizeof(
long)*(state-1));
717 memset(date, 0,
sizeof(
long)*(4-state));
720 memset((date+state), 0,
sizeof(
long)*(4-state));
725 if ((end-str) >= 2 && *str ==
'.' && my_isdigit(&my_charset_latin1,str[1]))
728 str++; value=(uint) (uchar) (*str -
'0');
729 while (++str != end && my_isdigit(&my_charset_latin1, *str))
731 if (field_length-- > 0)
732 value= value*10 + (uint) (uchar) (*str -
'0');
734 if (field_length >= 0)
736 status->fractional_digits= DATETIME_MAX_DECIMALS - field_length;
737 if (field_length > 0)
738 value*= (long) log_10_int[field_length];
743 status->fractional_digits= 6;
744 status->nanoseconds= 100 * (int) (str[-1] -
'0');
745 for ( ; str != end && my_isdigit(&my_charset_latin1, *str); str++)
748 date[4]= (ulong) value;
750 else if ((end - str) == 1 && *str ==
'.')
760 if ((end - str) > 1 &&
761 (*str ==
'e' || *str ==
'E') &&
762 (my_isdigit(&my_charset_latin1, str[1]) ||
763 ((str[1] ==
'-' || str[1] ==
'+') &&
765 my_isdigit(&my_charset_latin1, str[2]))))
768 if (internal_format_positions[7] != 255)
771 while (str != end && my_isspace(&my_charset_latin1, *str))
773 if (str+2 <= end && (str[1] ==
'M' || str[1] ==
'm'))
775 if (str[0] ==
'p' || str[0] ==
'P')
778 date[1]= date[1]%12 + 12;
780 else if (str[0] ==
'a' || str[0] ==
'A')
786 if (date[0] > UINT_MAX || date[1] > UINT_MAX ||
787 date[2] > UINT_MAX || date[3] > UINT_MAX ||
795 l_time->hour= date[1] + date[0] * 24;
797 l_time->minute= date[2];
798 l_time->second= date[3];
800 l_time->time_type= MYSQL_TIMESTAMP_TIME;
802 if (check_time_mmssff_range(l_time))
804 status->warnings|= MYSQL_TIME_WARN_OUT_OF_RANGE;
809 adjust_time_range(l_time, &status->warnings);
816 if (!my_isspace(&my_charset_latin1,*str))
818 status->warnings|= MYSQL_TIME_WARN_TRUNCATED;
821 }
while (++str != end);
837 number_to_time(longlong nr,
MYSQL_TIME *ltime,
int *warnings)
839 if (nr > TIME_MAX_VALUE)
842 if (nr >= 10000000000LL)
844 int warnings_backup= *warnings;
845 if (number_to_datetime(nr, ltime, 0, warnings) != LL(-1))
847 *warnings= warnings_backup;
849 set_max_time(ltime, 0);
850 *warnings|= MYSQL_TIME_WARN_OUT_OF_RANGE;
853 else if (nr < -TIME_MAX_VALUE)
855 set_max_time(ltime, 1);
856 *warnings|= MYSQL_TIME_WARN_OUT_OF_RANGE;
859 if ((ltime->neg= (nr < 0)))
861 if (nr % 100 >= 60 || nr / 100 % 100 >= 60)
863 set_zero_time(ltime, MYSQL_TIMESTAMP_TIME);
864 *warnings|= MYSQL_TIME_WARN_OUT_OF_RANGE;
867 ltime->time_type= MYSQL_TIMESTAMP_TIME;
868 ltime->year= ltime->month= ltime->day= 0;
869 TIME_set_hhmmss(ltime, nr);
884 void adjust_time_range(
struct st_mysql_time *my_time,
int *warning)
886 DBUG_ASSERT(!check_time_mmssff_range(my_time));
887 if (check_time_range_quick(my_time))
890 set_max_hhmmss(my_time);
891 *warning|= MYSQL_TIME_WARN_OUT_OF_RANGE;
902 void my_init_time(
void)
905 struct tm *l_time,tm_tmp;
909 seconds= (time_t) time((time_t*) 0);
910 localtime_r(&seconds,&tm_tmp);
913 my_time.year= (uint) l_time->tm_year+1900;
914 my_time.month= (uint) l_time->tm_mon+1;
915 my_time.day= (uint) l_time->tm_mday;
916 my_time.hour= (uint) l_time->tm_hour;
917 my_time.minute= (uint) l_time->tm_min;
918 my_time.second= (uint) l_time->tm_sec;
919 my_time.time_type= MYSQL_TIMESTAMP_DATETIME;
922 my_system_gmt_sec(&my_time, &my_time_zone, ¬_used);
937 uint year_2000_handling(uint year)
939 if ((year=year+1900) < 1900+YY_PART_YEAR)
960 long calc_daynr(uint year,uint month,uint day)
965 DBUG_ENTER(
"calc_daynr");
967 if (y == 0 && month == 0)
970 delsum= (long) (365 * y + 31 *((
int) month - 1) + (int) day);
974 delsum-= (long) ((
int) month * 4 + 23) / 10;
975 temp=(int) ((y/100+1)*3)/4;
976 DBUG_PRINT(
"exit",(
"year: %d month: %d day: %d -> daynr: %ld",
977 y+(month <= 2),month,day,delsum+y/4-temp));
978 DBUG_ASSERT(delsum+(
int) y/4-temp >= 0);
979 DBUG_RETURN(delsum+(
int) y/4-temp);
1006 my_system_gmt_sec(
const MYSQL_TIME *t_src,
long *my_timezone,
1007 my_bool *in_dst_time_gap)
1014 struct tm *l_time,tm_tmp;
1015 long diff, current_timezone;
1021 memcpy(&tmp_time, t_src,
sizeof(
MYSQL_TIME));
1023 if (!validate_timestamp_range(t))
1076 if ((t->year == TIMESTAMP_MAX_YEAR) && (t->month == 1) && (t->day > 4))
1086 #ifdef TIME_T_UNSIGNED
1098 if ((t->year == TIMESTAMP_MIN_YEAR + 1) && (t->month == 1)
1105 if ((t->year == TIMESTAMP_MIN_YEAR) && (t->month == 12)
1116 tmp= (time_t) (((calc_daynr((uint) t->year, (uint) t->month, (uint) t->day) -
1117 (
long) days_at_timestart) * SECONDS_IN_24H +
1118 (
long) t->hour*3600L +
1119 (
long) (t->minute*60 + t->second)) + (time_t) my_time_zone -
1122 current_timezone= my_time_zone;
1123 localtime_r(&tmp,&tm_tmp);
1127 (t->hour != (uint) l_time->tm_hour ||
1128 t->minute != (uint) l_time->tm_min ||
1129 t->second != (uint) l_time->tm_sec);
1133 int days= t->day - l_time->tm_mday;
1138 diff=(3600L*(long) (days*24+((
int) t->hour - (
int) l_time->tm_hour)) +
1139 (
long) (60*((
int) t->minute - (
int) l_time->tm_min)) +
1140 (
long) ((
int) t->second - (
int) l_time->tm_sec));
1141 current_timezone+= diff+3600;
1142 tmp+= (time_t) diff;
1143 localtime_r(&tmp,&tm_tmp);
1156 if (loop == 2 && t->hour != (uint) l_time->tm_hour)
1158 int days= t->day - l_time->tm_mday;
1163 diff=(3600L*(long) (days*24+((
int) t->hour - (
int) l_time->tm_hour))+
1164 (
long) (60*((int) t->minute - (
int) l_time->tm_min)) +
1165 (long) ((
int) t->second - (int) l_time->tm_sec));
1167 tmp+=3600 - t->minute*60 - t->second;
1168 else if (diff == -3600)
1169 tmp-=t->minute*60 + t->second;
1171 *in_dst_time_gap= 1;
1173 *my_timezone= current_timezone;
1177 tmp+= shift * SECONDS_IN_24H;
1189 if (!IS_TIME_T_VALID_FOR_TIMESTAMP(tmp))
1192 return (my_time_t) tmp;
1204 my_useconds_to_str(
char *
to, ulong useconds, uint dec)
1206 DBUG_ASSERT(dec <= DATETIME_MAX_DECIMALS);
1207 return sprintf(to,
".%0*lu", (
int) dec,
1208 useconds / (ulong) log_10_int[DATETIME_MAX_DECIMALS - dec]);
1225 int my_time_to_str(
const MYSQL_TIME *l_time,
char *to, uint dec)
1227 uint extra_hours= 0;
1228 int len= sprintf(to,
"%s%02u:%02u:%02u", (l_time->neg ?
"-" :
""),
1229 extra_hours + l_time->hour, l_time->minute, l_time->second);
1231 len+= my_useconds_to_str(to + len, l_time->
second_part, dec);
1235 int my_date_to_str(
const MYSQL_TIME *l_time,
char *to)
1237 return sprintf(to,
"%04u-%02u-%02u",
1238 l_time->year, l_time->month, l_time->day);
1252 TIME_to_datetime_str(
char *to,
const MYSQL_TIME *ltime)
1256 temp= ltime->year / 100;
1257 *to++= (char) (
'0' + temp / 10);
1258 *to++= (char) (
'0' + temp % 10);
1259 temp= ltime->year % 100;
1260 *to++= (char) (
'0' + temp / 10);
1261 *to++= (char) (
'0' + temp % 10);
1266 temp= temp-temp2 * 10;
1267 *to++= (char) (
'0' + (
char) (temp2));
1268 *to++= (char) (
'0' + (
char) (
temp));
1273 temp= temp - temp2 * 10;
1274 *to++= (char) (
'0' + (
char) (temp2));
1275 *to++= (char) (
'0' + (
char) (
temp));
1280 temp= temp - temp2 * 10;
1281 *to++= (char) (
'0' + (
char) (temp2));
1282 *to++= (char) (
'0' + (
char) (
temp));
1285 temp= ltime->minute;
1287 temp= temp - temp2 * 10;
1288 *to++= (char) (
'0' + (
char) (temp2));
1289 *to++= (char) (
'0' + (
char) (
temp));
1292 temp= ltime->second;
1294 temp= temp - temp2 * 10;
1295 *to++= (char) (
'0' + (
char) (temp2));
1296 *to++= (char) (
'0' + (
char) (
temp));
1308 int my_datetime_to_str(
const MYSQL_TIME *l_time,
char *to, uint dec)
1310 int len= TIME_to_datetime_str(to, l_time);
1312 len+= my_useconds_to_str(to + len, l_time->
second_part, dec);
1330 int my_TIME_to_str(
const MYSQL_TIME *l_time,
char *to, uint dec)
1332 switch (l_time->time_type) {
1333 case MYSQL_TIMESTAMP_DATETIME:
1334 return my_datetime_to_str(l_time, to, dec);
1335 case MYSQL_TIMESTAMP_DATE:
1336 return my_date_to_str(l_time, to);
1337 case MYSQL_TIMESTAMP_TIME:
1338 return my_time_to_str(l_time, to, dec);
1339 case MYSQL_TIMESTAMP_NONE:
1340 case MYSQL_TIMESTAMP_ERROR:
1358 int my_timeval_to_str(
const struct timeval *tm,
char *to, uint dec)
1360 int len= sprintf(to,
"%d", (
int) tm->tv_sec);
1362 len+= my_useconds_to_str(to + len, tm->tv_usec, dec);
1399 longlong number_to_datetime(longlong nr,
MYSQL_TIME *time_res,
1400 ulonglong flags,
int *was_cut)
1405 memset(time_res, 0,
sizeof(*time_res));
1406 time_res->time_type=MYSQL_TIMESTAMP_DATE;
1408 if (nr == LL(0) || nr >= LL(10000101000000))
1410 time_res->time_type=MYSQL_TIMESTAMP_DATETIME;
1411 if (nr > 99999999999999LL)
1413 *was_cut= MYSQL_TIME_WARN_OUT_OF_RANGE;
1420 if (nr <= (YY_PART_YEAR-1)*10000L+1231L)
1422 nr= (nr+20000000L)*1000000L;
1425 if (nr < (YY_PART_YEAR)*10000L+101L)
1429 nr= (nr+19000000L)*1000000L;
1437 if (nr < 10000101L && !(flags & TIME_FUZZY_DATE))
1439 if (nr <= 99991231L)
1444 if (nr < 101000000L)
1447 time_res->time_type=MYSQL_TIMESTAMP_DATETIME;
1449 if (nr <= (YY_PART_YEAR-1)*LL(10000000000)+LL(1231235959))
1451 nr= nr+LL(20000000000000);
1454 if (nr < YY_PART_YEAR*LL(10000000000)+ LL(101000000))
1456 if (nr <= LL(991231235959))
1457 nr= nr+LL(19000000000000);
1460 part1=(long) (nr/LL(1000000));
1461 part2=(long) (nr - (longlong) part1*LL(1000000));
1462 time_res->year= (int) (part1/10000L); part1%=10000L;
1463 time_res->month= (int) part1 / 100;
1464 time_res->day= (int) part1 % 100;
1465 time_res->hour= (int) (part2/10000L); part2%=10000L;
1466 time_res->minute=(int) part2 / 100;
1467 time_res->second=(int) part2 % 100;
1469 if (!check_datetime_range(time_res) &&
1470 !check_date(time_res, (nr != 0), flags, was_cut))
1474 if (!nr && (flags & TIME_NO_ZERO_DATE))
1478 *was_cut= MYSQL_TIME_WARN_TRUNCATED;
1488 ulonglong TIME_to_ulonglong_datetime(
const MYSQL_TIME *my_time)
1490 return ((ulonglong) (my_time->year * 10000UL +
1491 my_time->month * 100UL +
1492 my_time->day) * ULL(1000000) +
1493 (ulonglong) (my_time->hour * 10000UL +
1494 my_time->minute * 100UL +
1505 ulonglong TIME_to_ulonglong_date(
const MYSQL_TIME *my_time)
1507 return (ulonglong) (my_time->year * 10000UL + my_time->month * 100UL +
1519 ulonglong TIME_to_ulonglong_time(
const MYSQL_TIME *my_time)
1521 return (ulonglong) (my_time->hour * 10000UL +
1522 my_time->minute * 100UL +
1532 void TIME_set_yymmdd(
MYSQL_TIME *ltime, uint yymmdd)
1534 ltime->day= (int) (yymmdd % 100);
1535 ltime->month= (int) (yymmdd / 100) % 100;
1536 ltime->year= (int) (yymmdd / 10000);
1545 void TIME_set_hhmmss(
MYSQL_TIME *ltime, uint hhmmss)
1547 ltime->second= (int) (hhmmss % 100);
1548 ltime->minute= (int) (hhmmss / 100) % 100;
1549 ltime->hour= (int) (hhmmss / 10000);
1573 ulonglong TIME_to_ulonglong(
const MYSQL_TIME *my_time)
1575 switch (my_time->time_type) {
1576 case MYSQL_TIMESTAMP_DATETIME:
1577 return TIME_to_ulonglong_datetime(my_time);
1578 case MYSQL_TIMESTAMP_DATE:
1579 return TIME_to_ulonglong_date(my_time);
1580 case MYSQL_TIMESTAMP_TIME:
1581 return TIME_to_ulonglong_time(my_time);
1582 case MYSQL_TIMESTAMP_NONE:
1583 case MYSQL_TIMESTAMP_ERROR:
1615 longlong TIME_to_longlong_time_packed(
const MYSQL_TIME *ltime)
1618 long hms= (((ltime->month ? 0 : ltime->day * 24) + ltime->hour) << 12) |
1619 (ltime->minute << 6) | ltime->second;
1620 longlong tmp= MY_PACKED_TIME_MAKE(hms, ltime->
second_part);
1621 return ltime->neg ? -tmp : tmp;
1631 void TIME_from_longlong_time_packed(
MYSQL_TIME *ltime, longlong tmp)
1634 if ((ltime->neg= (tmp < 0)))
1636 hms= MY_PACKED_TIME_GET_INT_PART(tmp);
1637 ltime->year= (uint) 0;
1638 ltime->month= (uint) 0;
1639 ltime->day= (uint) 0;
1640 ltime->hour= (uint) (hms >> 12) % (1 << 10);
1641 ltime->minute= (uint) (hms >> 6) % (1 << 6);
1642 ltime->second= (uint) hms % (1 << 6);
1643 ltime->
second_part= MY_PACKED_TIME_GET_FRAC_PART(tmp);
1644 ltime->time_type= MYSQL_TIMESTAMP_TIME;
1653 uint my_time_binary_length(uint dec)
1655 DBUG_ASSERT(dec <= DATETIME_MAX_DECIMALS);
1656 return 3 + (dec + 1) / 2;
1664 #define TIMEF_OFS 0x800000000000LL
1665 #define TIMEF_INT_OFS 0x800000LL
1675 void my_time_packed_to_binary(longlong nr, uchar *ptr, uint dec)
1677 DBUG_ASSERT(dec <= DATETIME_MAX_DECIMALS);
1679 DBUG_ASSERT((MY_PACKED_TIME_GET_FRAC_PART(nr) %
1680 (
int) log_10_int[DATETIME_MAX_DECIMALS - dec]) == 0);
1686 mi_int3store(ptr, TIMEF_INT_OFS + MY_PACKED_TIME_GET_INT_PART(nr));
1691 mi_int3store(ptr, TIMEF_INT_OFS + MY_PACKED_TIME_GET_INT_PART(nr));
1692 ptr[3]= (
unsigned char) (
char) (MY_PACKED_TIME_GET_FRAC_PART(nr) / 10000);
1697 mi_int3store(ptr, TIMEF_INT_OFS + MY_PACKED_TIME_GET_INT_PART(nr));
1698 mi_int2store(ptr + 3, MY_PACKED_TIME_GET_FRAC_PART(nr) / 100);
1703 mi_int6store(ptr, nr + TIMEF_OFS);
1717 longlong my_time_packed_from_binary(
const uchar *ptr, uint dec)
1719 DBUG_ASSERT(dec <= DATETIME_MAX_DECIMALS);
1726 longlong intpart= mi_uint3korr(ptr) - TIMEF_INT_OFS;
1727 return MY_PACKED_TIME_MAKE_INT(intpart);
1732 longlong intpart= mi_uint3korr(ptr) - TIMEF_INT_OFS;
1733 int frac= (uint) ptr[3];
1734 if (intpart < 0 && frac)
1756 return MY_PACKED_TIME_MAKE(intpart, frac * 10000);
1762 longlong intpart= mi_uint3korr(ptr) - TIMEF_INT_OFS;
1763 int frac= mi_uint2korr(ptr + 3);
1764 if (intpart < 0 && frac)
1773 return MY_PACKED_TIME_MAKE(intpart, frac * 100);
1778 return ((longlong) mi_uint6korr(ptr)) - TIMEF_OFS;
1804 longlong TIME_to_longlong_datetime_packed(
const MYSQL_TIME *ltime)
1806 longlong ymd= ((ltime->year * 13 + ltime->month) << 5) | ltime->day;
1807 longlong hms= (ltime->hour << 12) | (ltime->minute << 6) | ltime->second;
1808 longlong tmp= MY_PACKED_TIME_MAKE(((ymd << 17) | hms), ltime->
second_part);
1809 DBUG_ASSERT(!check_datetime_range(ltime));
1810 return ltime->neg ? -tmp : tmp;
1822 longlong TIME_to_longlong_date_packed(
const MYSQL_TIME *ltime)
1824 longlong ymd= ((ltime->year * 13 + ltime->month) << 5) | ltime->day;
1825 return MY_PACKED_TIME_MAKE_INT(ymd << 17);
1833 longlong year_to_longlong_datetime_packed(
long year)
1835 longlong ymd= ((year * 13) << 5);
1836 return MY_PACKED_TIME_MAKE_INT(ymd << 17);
1845 void TIME_from_longlong_datetime_packed(
MYSQL_TIME *ltime, longlong tmp)
1848 longlong ymdhms, ym;
1849 if ((ltime->neg= (tmp < 0)))
1852 ltime->
second_part= MY_PACKED_TIME_GET_FRAC_PART(tmp);
1853 ymdhms= MY_PACKED_TIME_GET_INT_PART(tmp);
1857 hms= ymdhms % (1 << 17);
1859 ltime->day= ymd % (1 << 5);
1860 ltime->month= ym % 13;
1861 ltime->year= ym / 13;
1863 ltime->second= hms % (1 << 6);
1864 ltime->minute= (hms >> 6) % (1 << 6);
1865 ltime->hour= (hms >> 12);
1867 ltime->time_type= MYSQL_TIMESTAMP_DATETIME;
1876 void TIME_from_longlong_date_packed(
MYSQL_TIME *ltime, longlong tmp)
1878 TIME_from_longlong_datetime_packed(ltime, tmp);
1879 ltime->time_type= MYSQL_TIMESTAMP_DATE;
1887 uint my_datetime_binary_length(uint dec)
1889 DBUG_ASSERT(dec <= DATETIME_MAX_DECIMALS);
1890 return 5 + (dec + 1) / 2;
1898 #define DATETIMEF_INT_OFS 0x8000000000LL
1909 longlong my_datetime_packed_from_binary(
const uchar *ptr, uint dec)
1911 longlong intpart= mi_uint5korr(ptr) - DATETIMEF_INT_OFS;
1913 DBUG_ASSERT(dec <= DATETIME_MAX_DECIMALS);
1918 return MY_PACKED_TIME_MAKE_INT(intpart);
1921 frac= ((int) (
signed char) ptr[5]) * 10000;
1925 frac= mi_sint2korr(ptr + 5) * 100;
1929 frac= mi_sint3korr(ptr + 5);
1932 return MY_PACKED_TIME_MAKE(intpart, frac);
1943 void my_datetime_packed_to_binary(longlong nr, uchar *ptr, uint dec)
1945 DBUG_ASSERT(dec <= DATETIME_MAX_DECIMALS);
1947 DBUG_ASSERT((MY_PACKED_TIME_GET_FRAC_PART(nr) %
1948 (
int) log_10_int[DATETIME_MAX_DECIMALS - dec]) == 0);
1950 mi_int5store(ptr, MY_PACKED_TIME_GET_INT_PART(nr) + DATETIMEF_INT_OFS);
1958 ptr[5]= (
unsigned char) (
char) (MY_PACKED_TIME_GET_FRAC_PART(nr) / 10000);
1962 mi_int2store(ptr + 5, MY_PACKED_TIME_GET_FRAC_PART(nr) / 100);
1966 mi_int3store(ptr + 5, MY_PACKED_TIME_GET_FRAC_PART(nr));
1978 uint my_timestamp_binary_length(uint dec)
1980 DBUG_ASSERT(dec <= DATETIME_MAX_DECIMALS);
1981 return 4 + (dec + 1) / 2;
1992 void my_timestamp_from_binary(
struct timeval *tm,
const uchar *ptr, uint dec)
1994 DBUG_ASSERT(dec <= DATETIME_MAX_DECIMALS);
1995 tm->tv_sec= mi_uint4korr(ptr);
2004 tm->tv_usec= ((int) ptr[4]) * 10000;
2008 tm->tv_usec= mi_sint2korr(ptr + 4) * 100;
2012 tm->tv_usec= mi_sint3korr(ptr + 4);
2024 void my_timestamp_to_binary(
const struct timeval *tm, uchar *ptr, uint dec)
2026 DBUG_ASSERT(dec <= DATETIME_MAX_DECIMALS);
2028 DBUG_ASSERT((tm->tv_usec %
2029 (
int) log_10_int[DATETIME_MAX_DECIMALS - dec]) == 0);
2030 mi_int4store(ptr, tm->tv_sec);
2038 ptr[4]= (
unsigned char) (
char) (tm->tv_usec / 10000);
2042 mi_int2store(ptr + 4, tm->tv_usec / 100);
2047 mi_int3store(ptr + 4, tm->tv_usec);
2061 longlong TIME_to_longlong_packed(
const MYSQL_TIME *ltime)
2063 switch (ltime->time_type) {
2064 case MYSQL_TIMESTAMP_DATE:
2065 return TIME_to_longlong_date_packed(ltime);
2066 case MYSQL_TIMESTAMP_DATETIME:
2067 return TIME_to_longlong_datetime_packed(ltime);
2068 case MYSQL_TIMESTAMP_TIME:
2069 return TIME_to_longlong_time_packed(ltime);
2070 case MYSQL_TIMESTAMP_NONE:
2071 case MYSQL_TIMESTAMP_ERROR: