#include <my_time.h>#include <m_string.h>#include <m_ctype.h>#include <my_pthread.h>Include dependency graph for my_time.c:

Go to the source code of this file.
| #define MAX_DATE_PARTS 8 |
Definition at line 686 of file my_time.c.
References DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, int(), YY_MAGIC_BELOW, and YY_PART_YEAR.
00687 { 00688 long delsum; 00689 int temp; 00690 DBUG_ENTER("calc_daynr"); 00691 00692 if (year == 0 && month == 0 && day == 0) 00693 DBUG_RETURN(0); /* Skip errors */ 00694 if (year < YY_MAGIC_BELOW) 00695 { 00696 if ((year=year+1900) < 1900+YY_PART_YEAR) 00697 year+=100; 00698 } 00699 delsum= (long) (365L * year+ 31*(month-1) +day); 00700 if (month <= 2) 00701 year--; 00702 else 00703 delsum-= (long) (month*4+23)/10; 00704 temp=(int) ((year/100+1)*3)/4; 00705 DBUG_PRINT("exit",("year: %d month: %d day: %d -> daynr: %ld", 00706 year+(month <= 2),month,day,delsum+year/4-temp)); 00707 DBUG_RETURN(delsum+(int) year/4-temp); 00708 } /* calc_daynr */
Here is the call graph for this function:

| static my_bool check_date | ( | const MYSQL_TIME * | ltime, | |
| my_bool | not_zero_date, | |||
| ulong | flags, | |||
| int * | was_cut | |||
| ) | [static] |
Definition at line 79 of file my_time.c.
References calc_days_in_year(), st_mysql_time::day, FALSE, st_mysql_time::month, TIME_FUZZY_DATE, TIME_INVALID_DATES, TIME_NO_ZERO_DATE, TIME_NO_ZERO_IN_DATE, TRUE, and st_mysql_time::year.
Referenced by number_to_datetime(), and str_to_datetime().
00081 { 00082 if (not_zero_date) 00083 { 00084 if ((((flags & TIME_NO_ZERO_IN_DATE) || !(flags & TIME_FUZZY_DATE)) && 00085 (ltime->month == 0 || ltime->day == 0)) || 00086 (!(flags & TIME_INVALID_DATES) && 00087 ltime->month && ltime->day > days_in_month[ltime->month-1] && 00088 (ltime->month != 2 || calc_days_in_year(ltime->year) != 366 || 00089 ltime->day != 29)) || 00090 (ltime->year == 0 && (ltime->month != 0 || ltime->day != 0))) 00091 { 00092 *was_cut= 2; 00093 return TRUE; 00094 } 00095 } 00096 else if (flags & TIME_NO_ZERO_DATE) 00097 { 00098 /* 00099 We don't set *was_cut here to signal that the problem was a zero date 00100 and not an invalid date 00101 */ 00102 return TRUE; 00103 } 00104 return FALSE; 00105 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void init_time | ( | void | ) |
Definition at line 663 of file my_time.c.
References st_mysql_time::day, st_mysql_time::hour, localtime_r(), st_mysql_time::minute, st_mysql_time::month, my_system_gmt_sec(), st_mysql_time::second, and st_mysql_time::year.
00664 { 00665 time_t seconds; 00666 struct tm *l_time,tm_tmp; 00667 MYSQL_TIME my_time; 00668 my_bool not_used; 00669 00670 seconds= (time_t) time((time_t*) 0); 00671 localtime_r(&seconds,&tm_tmp); 00672 l_time= &tm_tmp; 00673 my_time_zone= 3600; /* Comp. for -3600 in my_gmt_sec */ 00674 my_time.year= (uint) l_time->tm_year+1900; 00675 my_time.month= (uint) l_time->tm_mon+1; 00676 my_time.day= (uint) l_time->tm_mday; 00677 my_time.hour= (uint) l_time->tm_hour; 00678 my_time.minute= (uint) l_time->tm_min; 00679 my_time.second= (uint) l_time->tm_sec; 00680 my_system_gmt_sec(&my_time, &my_time_zone, ¬_used); /* Init my_time_zone */ 00681 }
Here is the call graph for this function:

| int my_date_to_str | ( | const MYSQL_TIME * | l_time, | |
| char * | to | |||
| ) |
Definition at line 850 of file my_time.c.
References st_mysql_time::day, st_mysql_time::month, my_sprintf, and st_mysql_time::year.
00851 { 00852 return my_sprintf(to, (to, "%04d-%02d-%02d", 00853 l_time->year, 00854 l_time->month, 00855 l_time->day)); 00856 }
| int my_datetime_to_str | ( | const MYSQL_TIME * | l_time, | |
| char * | to | |||
| ) |
Definition at line 858 of file my_time.c.
References st_mysql_time::day, st_mysql_time::hour, st_mysql_time::minute, st_mysql_time::month, my_sprintf, st_mysql_time::second, and st_mysql_time::year.
00859 { 00860 return my_sprintf(to, (to, "%04d-%02d-%02d %02d:%02d:%02d", 00861 l_time->year, 00862 l_time->month, 00863 l_time->day, 00864 l_time->hour, 00865 l_time->minute, 00866 l_time->second)); 00867 }
| my_time_t my_system_gmt_sec | ( | const MYSQL_TIME * | t, | |
| long * | my_timezone, | |||
| my_bool * | in_dst_time_gap | |||
| ) |
Definition at line 734 of file my_time.c.
References calc_daynr(), st_mysql_time::day, st_mysql_time::hour, localtime_r(), st_mysql_time::minute, st_mysql_time::month, st_mysql_time::second, and st_mysql_time::year.
00736 { 00737 uint loop; 00738 time_t tmp; 00739 struct tm *l_time,tm_tmp; 00740 long diff, current_timezone; 00741 00742 /* 00743 Calculate the gmt time based on current time and timezone 00744 The -1 on the end is to ensure that if have a date that exists twice 00745 (like 2002-10-27 02:00:0 MET), we will find the initial date. 00746 00747 By doing -3600 we will have to call localtime_r() several times, but 00748 I couldn't come up with a better way to get a repeatable result :( 00749 00750 We can't use mktime() as it's buggy on many platforms and not thread safe. 00751 00752 Note: this code assumes that our time_t estimation is not too far away 00753 from real value (we assume that localtime_r(tmp) will return something 00754 within 24 hrs from t) which is probably true for all current time zones. 00755 */ 00756 tmp=(time_t) (((calc_daynr((uint) t->year,(uint) t->month,(uint) t->day) - 00757 (long) days_at_timestart)*86400L + (long) t->hour*3600L + 00758 (long) (t->minute*60 + t->second)) + (time_t) my_time_zone - 00759 3600); 00760 current_timezone= my_time_zone; 00761 00762 localtime_r(&tmp,&tm_tmp); 00763 l_time=&tm_tmp; 00764 for (loop=0; 00765 loop < 2 && 00766 (t->hour != (uint) l_time->tm_hour || 00767 t->minute != (uint) l_time->tm_min || 00768 t->second != (uint) l_time->tm_sec); 00769 loop++) 00770 { /* One check should be enough ? */ 00771 /* Get difference in days */ 00772 int days= t->day - l_time->tm_mday; 00773 if (days < -1) 00774 days= 1; /* Month has wrapped */ 00775 else if (days > 1) 00776 days= -1; 00777 diff=(3600L*(long) (days*24+((int) t->hour - (int) l_time->tm_hour)) + 00778 (long) (60*((int) t->minute - (int) l_time->tm_min)) + 00779 (long) ((int) t->second - (int) l_time->tm_sec)); 00780 current_timezone+= diff+3600; /* Compensate for -3600 above */ 00781 tmp+= (time_t) diff; 00782 localtime_r(&tmp,&tm_tmp); 00783 l_time=&tm_tmp; 00784 } 00785 /* 00786 Fix that if we are in the non existing daylight saving time hour 00787 we move the start of the next real hour. 00788 00789 This code doesn't handle such exotical thing as time-gaps whose length 00790 is more than one hour or non-integer (latter can theoretically happen 00791 if one of seconds will be removed due leap correction, or because of 00792 general time correction like it happened for Africa/Monrovia time zone 00793 in year 1972). 00794 */ 00795 if (loop == 2 && t->hour != (uint) l_time->tm_hour) 00796 { 00797 int days= t->day - l_time->tm_mday; 00798 if (days < -1) 00799 days=1; /* Month has wrapped */ 00800 else if (days > 1) 00801 days= -1; 00802 diff=(3600L*(long) (days*24+((int) t->hour - (int) l_time->tm_hour))+ 00803 (long) (60*((int) t->minute - (int) l_time->tm_min)) + 00804 (long) ((int) t->second - (int) l_time->tm_sec)); 00805 if (diff == 3600) 00806 tmp+=3600 - t->minute*60 - t->second; /* Move to next hour */ 00807 else if (diff == -3600) 00808 tmp-=t->minute*60 + t->second; /* Move to previous hour */ 00809 00810 *in_dst_time_gap= 1; 00811 } 00812 *my_timezone= current_timezone; 00813 00814 return (my_time_t) tmp; 00815 } /* my_system_gmt_sec */
Here is the call graph for this function:

| int my_TIME_to_str | ( | const MYSQL_TIME * | l_time, | |
| char * | to | |||
| ) |
Definition at line 881 of file my_time.c.
References DBUG_ASSERT, my_date_to_str(), my_datetime_to_str(), my_time_to_str(), MYSQL_TIMESTAMP_DATE, MYSQL_TIMESTAMP_DATETIME, MYSQL_TIMESTAMP_ERROR, MYSQL_TIMESTAMP_NONE, MYSQL_TIMESTAMP_TIME, and st_mysql_time::time_type.
00882 { 00883 switch (l_time->time_type) { 00884 case MYSQL_TIMESTAMP_DATETIME: 00885 return my_datetime_to_str(l_time, to); 00886 case MYSQL_TIMESTAMP_DATE: 00887 return my_date_to_str(l_time, to); 00888 case MYSQL_TIMESTAMP_TIME: 00889 return my_time_to_str(l_time, to); 00890 case MYSQL_TIMESTAMP_NONE: 00891 case MYSQL_TIMESTAMP_ERROR: 00892 to[0]='\0'; 00893 return 0; 00894 default: 00895 DBUG_ASSERT(0); 00896 return 0; 00897 } 00898 }
Here is the call graph for this function:

| int my_time_to_str | ( | const MYSQL_TIME * | l_time, | |
| char * | to | |||
| ) |
Definition at line 840 of file my_time.c.
References st_mysql_time::hour, st_mysql_time::minute, my_sprintf, st_mysql_time::neg, and st_mysql_time::second.
00841 { 00842 uint extra_hours= 0; 00843 return my_sprintf(to, (to, "%s%02d:%02d:%02d", 00844 (l_time->neg ? "-" : ""), 00845 extra_hours+ l_time->hour, 00846 l_time->minute, 00847 l_time->second)); 00848 }
| longlong number_to_datetime | ( | longlong | nr, | |
| MYSQL_TIME * | time_res, | |||
| uint | flags, | |||
| int * | was_cut | |||
| ) |
Definition at line 927 of file my_time.c.
References check_date(), st_mysql_time::day, err, st_mysql_time::hour, int(), LL, st_mysql_time::minute, st_mysql_time::month, ok(), st_mysql_time::second, TIME_NO_ZERO_DATE, st_mysql_time::year, and YY_PART_YEAR.
00929 { 00930 long part1,part2; 00931 00932 *was_cut= 0; 00933 00934 if (nr == LL(0) || nr >= LL(10000101000000)) 00935 goto ok; 00936 if (nr < 101) 00937 goto err; 00938 if (nr <= (YY_PART_YEAR-1)*10000L+1231L) 00939 { 00940 nr= (nr+20000000L)*1000000L; /* YYMMDD, year: 2000-2069 */ 00941 goto ok; 00942 } 00943 if (nr < (YY_PART_YEAR)*10000L+101L) 00944 goto err; 00945 if (nr <= 991231L) 00946 { 00947 nr= (nr+19000000L)*1000000L; /* YYMMDD, year: 1970-1999 */ 00948 goto ok; 00949 } 00950 if (nr < 10000101L) 00951 goto err; 00952 if (nr <= 99991231L) 00953 { 00954 nr= nr*1000000L; 00955 goto ok; 00956 } 00957 if (nr < 101000000L) 00958 goto err; 00959 if (nr <= (YY_PART_YEAR-1)*LL(10000000000)+LL(1231235959)) 00960 { 00961 nr= nr+LL(20000000000000); /* YYMMDDHHMMSS, 2000-2069 */ 00962 goto ok; 00963 } 00964 if (nr < YY_PART_YEAR*LL(10000000000)+ LL(101000000)) 00965 goto err; 00966 if (nr <= LL(991231235959)) 00967 nr= nr+LL(19000000000000); /* YYMMDDHHMMSS, 1970-1999 */ 00968 00969 ok: 00970 part1=(long) (nr/LL(1000000)); 00971 part2=(long) (nr - (longlong) part1*LL(1000000)); 00972 time_res->year= (int) (part1/10000L); part1%=10000L; 00973 time_res->month= (int) part1 / 100; 00974 time_res->day= (int) part1 % 100; 00975 time_res->hour= (int) (part2/10000L); part2%=10000L; 00976 time_res->minute=(int) part2 / 100; 00977 time_res->second=(int) part2 % 100; 00978 00979 if (time_res->year <= 9999 && time_res->month <= 12 && 00980 time_res->day <= 31 && time_res->hour <= 23 && 00981 time_res->minute <= 59 && time_res->second <= 59 && 00982 !check_date(time_res, (nr != 0), flags, was_cut)) 00983 return nr; 00984 00985 /* Don't want to have was_cut get set if NO_ZERO_DATE was violated. */ 00986 if (!nr && (flags & TIME_NO_ZERO_DATE)) 00987 return LL(-1); 00988 00989 err: 00990 *was_cut= 1; 00991 return LL(-1); 00992 }
Here is the call graph for this function:

| void set_zero_time | ( | MYSQL_TIME * | tm, | |
| enum enum_mysql_timestamp_type | time_type | |||
| ) |
| enum enum_mysql_timestamp_type str_to_datetime | ( | const char * | str, | |
| uint | length, | |||
| MYSQL_TIME * | l_time, | |||
| uint | flags, | |||
| int * | was_cut | |||
| ) |
Definition at line 162 of file my_time.c.
References bzero, check_date(), st_mysql_time::day, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, err, st_mysql_time::hour, internal_format_positions, LINT_INIT, log_10_int, max, MAX_DATE_PARTS, st_mysql_time::minute, st_mysql_time::month, my_charset_latin1, my_isdigit, my_ispunct, my_isspace, MYSQL_TIMESTAMP_DATE, MYSQL_TIMESTAMP_DATETIME, MYSQL_TIMESTAMP_ERROR, MYSQL_TIMESTAMP_NONE, st_mysql_time::neg, pos(), st_mysql_time::second, st_mysql_time::second_part, set_if_bigger, start(), test, TIME_DATETIME_ONLY, st_mysql_time::year, and YY_PART_YEAR.
00164 { 00165 uint field_length, year_length, digits, i, number_of_fields; 00166 uint date[MAX_DATE_PARTS], date_len[MAX_DATE_PARTS]; 00167 uint add_hours= 0, start_loop; 00168 ulong not_zero_date, allow_space; 00169 my_bool is_internal_format; 00170 const char *pos, *last_field_pos; 00171 const char *end=str+length; 00172 const uchar *format_position; 00173 my_bool found_delimitier= 0, found_space= 0; 00174 uint frac_pos, frac_len; 00175 DBUG_ENTER("str_to_datetime"); 00176 DBUG_PRINT("ENTER",("str: %.*s",length,str)); 00177 00178 LINT_INIT(field_length); 00179 LINT_INIT(year_length); 00180 LINT_INIT(last_field_pos); 00181 00182 *was_cut= 0; 00183 00184 /* Skip space at start */ 00185 for (; str != end && my_isspace(&my_charset_latin1, *str) ; str++) 00186 ; 00187 if (str == end || ! my_isdigit(&my_charset_latin1, *str)) 00188 { 00189 *was_cut= 1; 00190 DBUG_RETURN(MYSQL_TIMESTAMP_NONE); 00191 } 00192 00193 is_internal_format= 0; 00194 /* This has to be changed if want to activate different timestamp formats */ 00195 format_position= internal_format_positions; 00196 00197 /* 00198 Calculate number of digits in first part. 00199 If length= 8 or >= 14 then year is of format YYYY. 00200 (YYYY-MM-DD, YYYYMMDD, YYYYYMMDDHHMMSS) 00201 */ 00202 for (pos=str; 00203 pos != end && (my_isdigit(&my_charset_latin1,*pos) || *pos == 'T'); 00204 pos++) 00205 ; 00206 00207 digits= (uint) (pos-str); 00208 start_loop= 0; /* Start of scan loop */ 00209 date_len[format_position[0]]= 0; /* Length of year field */ 00210 if (pos == end) 00211 { 00212 /* Found date in internal format (only numbers like YYYYMMDD) */ 00213 year_length= (digits == 4 || digits == 8 || digits >= 14) ? 4 : 2; 00214 field_length= year_length; 00215 is_internal_format= 1; 00216 format_position= internal_format_positions; 00217 } 00218 else 00219 { 00220 if (format_position[0] >= 3) /* If year is after HHMMDD */ 00221 { 00222 /* 00223 If year is not in first part then we have to determinate if we got 00224 a date field or a datetime field. 00225 We do this by checking if there is two numbers separated by 00226 space in the input. 00227 */ 00228 while (pos < end && !my_isspace(&my_charset_latin1, *pos)) 00229 pos++; 00230 while (pos < end && !my_isdigit(&my_charset_latin1, *pos)) 00231 pos++; 00232 if (pos == end) 00233 { 00234 if (flags & TIME_DATETIME_ONLY) 00235 { 00236 *was_cut= 1; 00237 DBUG_RETURN(MYSQL_TIMESTAMP_NONE); /* Can't be a full datetime */ 00238 } 00239 /* Date field. Set hour, minutes and seconds to 0 */ 00240 date[0]= date[1]= date[2]= date[3]= date[4]= 0; 00241 start_loop= 5; /* Start with first date part */ 00242 } 00243 } 00244 00245 field_length= format_position[0] == 0 ? 4 : 2; 00246 } 00247 00248 /* 00249 Only allow space in the first "part" of the datetime field and: 00250 - after days, part seconds 00251 - before and after AM/PM (handled by code later) 00252 00253 2003-03-03 20:00:20 AM 00254 20:00:20.000000 AM 03-03-2000 00255 */ 00256 i= max((uint) format_position[0], (uint) format_position[1]); 00257 set_if_bigger(i, (uint) format_position[2]); 00258 allow_space= ((1 << i) | (1 << format_position[6])); 00259 allow_space&= (1 | 2 | 4 | 8); 00260 00261 not_zero_date= 0; 00262 for (i = start_loop; 00263 i < MAX_DATE_PARTS-1 && str != end && 00264 my_isdigit(&my_charset_latin1,*str); 00265 i++) 00266 { 00267 const char *start= str; 00268 ulong tmp_value= (uint) (uchar) (*str++ - '0'); 00269 while (str != end && my_isdigit(&my_charset_latin1,str[0]) && 00270 (!is_internal_format || --field_length)) 00271 { 00272 tmp_value=tmp_value*10 + (ulong) (uchar) (*str - '0'); 00273 str++; 00274 } 00275 date_len[i]= (uint) (str - start); 00276 if (tmp_value > 999999) /* Impossible date part */ 00277 { 00278 *was_cut= 1; 00279 DBUG_RETURN(MYSQL_TIMESTAMP_NONE); 00280 } 00281 date[i]=tmp_value; 00282 not_zero_date|= tmp_value; 00283 00284 /* Length of next field */ 00285 field_length= format_position[i+1] == 0 ? 4 : 2; 00286 00287 if ((last_field_pos= str) == end) 00288 { 00289 i++; /* Register last found part */ 00290 break; 00291 } 00292 /* Allow a 'T' after day to allow CCYYMMDDT type of fields */ 00293 if (i == format_position[2] && *str == 'T') 00294 { 00295 str++; /* ISO8601: CCYYMMDDThhmmss */ 00296 continue; 00297 } 00298 if (i == format_position[5]) /* Seconds */ 00299 { 00300 if (*str == '.') /* Followed by part seconds */ 00301 { 00302 str++; 00303 field_length= 6; /* 6 digits */ 00304 } 00305 continue; 00306 00307 /* No part seconds */ 00308 date[++i]= 0; 00309 } 00310 while (str != end && 00311 (my_ispunct(&my_charset_latin1,*str) || 00312 my_isspace(&my_charset_latin1,*str))) 00313 { 00314 if (my_isspace(&my_charset_latin1,*str)) 00315 { 00316 if (!(allow_space & (1 << i))) 00317 { 00318 *was_cut= 1; 00319 DBUG_RETURN(MYSQL_TIMESTAMP_NONE); 00320 } 00321 found_space= 1; 00322 } 00323 str++; 00324 found_delimitier= 1; /* Should be a 'normal' date */ 00325 } 00326 /* Check if next position is AM/PM */ 00327 if (i == format_position[6]) /* Seconds, time for AM/PM */ 00328 { 00329 i++; /* Skip AM/PM part */ 00330 if (format_position[7] != 255) /* If using AM/PM */ 00331 { 00332 if (str+2 <= end && (str[1] == 'M' || str[1] == 'm')) 00333 { 00334 if (str[0] == 'p' || str[0] == 'P') 00335 add_hours= 12; 00336 else if (str[0] != 'a' || str[0] != 'A') 00337 continue; /* Not AM/PM */ 00338 str+= 2; /* Skip AM/PM */ 00339 /* Skip space after AM/PM */ 00340 while (str != end && my_isspace(&my_charset_latin1,*str)) 00341 str++; 00342 } 00343 } 00344 } 00345 last_field_pos= str; 00346 } 00347 if (found_delimitier && !found_space && (flags & TIME_DATETIME_ONLY)) 00348 { 00349 *was_cut= 1; 00350 DBUG_RETURN(MYSQL_TIMESTAMP_NONE); /* Can't be a datetime */ 00351 } 00352 00353 str= last_field_pos; 00354 00355 number_of_fields= i - start_loop; 00356 while (i < MAX_DATE_PARTS) 00357 { 00358 date_len[i]= 0; 00359 date[i++]= 0; 00360 } 00361 00362 if (!is_internal_format) 00363 { 00364 year_length= date_len[(uint) format_position[0]]; 00365 if (!year_length) /* Year must be specified */ 00366 { 00367 *was_cut= 1; 00368 DBUG_RETURN(MYSQL_TIMESTAMP_NONE); 00369 } 00370 00371 l_time->year= date[(uint) format_position[0]]; 00372 l_time->month= date[(uint) format_position[1]]; 00373 l_time->day= date[(uint) format_position[2]]; 00374 l_time->hour= date[(uint) format_position[3]]; 00375 l_time->minute= date[(uint) format_position[4]]; 00376 l_time->second= date[(uint) format_position[5]]; 00377 00378 frac_pos= (uint) format_position[6]; 00379 frac_len= date_len[frac_pos]; 00380 if (frac_len < 6) 00381 date[frac_pos]*= (uint) log_10_int[6 - frac_len]; 00382 l_time->second_part= date[frac_pos]; 00383 00384 if (format_position[7] != (uchar) 255) 00385 { 00386 if (l_time->hour > 12) 00387 { 00388 *was_cut= 1; 00389 goto err; 00390 } 00391 l_time->hour= l_time->hour%12 + add_hours; 00392 } 00393 } 00394 else 00395 { 00396 l_time->year= date[0]; 00397 l_time->month= date[1]; 00398 l_time->day= date[2]; 00399 l_time->hour= date[3]; 00400 l_time->minute= date[4]; 00401 l_time->second= date[5]; 00402 if (date_len[6] < 6) 00403 date[6]*= (uint) log_10_int[6 - date_len[6]]; 00404 l_time->second_part=date[6]; 00405 } 00406 l_time->neg= 0; 00407 00408 if (year_length == 2 && not_zero_date) 00409 l_time->year+= (l_time->year < YY_PART_YEAR ? 2000 : 1900); 00410 00411 if (number_of_fields < 3 || 00412 l_time->year > 9999 || l_time->month > 12 || 00413 l_time->day > 31 || l_time->hour > 23 || 00414 l_time->minute > 59 || l_time->second > 59) 00415 { 00416 /* Only give warning for a zero date if there is some garbage after */ 00417 if (!not_zero_date) /* If zero date */ 00418 { 00419 for (; str != end ; str++) 00420 { 00421 if (!my_isspace(&my_charset_latin1, *str)) 00422 { 00423 not_zero_date= 1; /* Give warning */ 00424 break; 00425 } 00426 } 00427 } 00428 *was_cut= test(not_zero_date); 00429 goto err; 00430 } 00431 00432 if ((my_bool)check_date(l_time, not_zero_date, flags, was_cut)) 00433 goto err; 00434 00435 l_time->time_type= (number_of_fields <= 3 ? 00436 MYSQL_TIMESTAMP_DATE : MYSQL_TIMESTAMP_DATETIME); 00437 00438 for (; str != end ; str++) 00439 { 00440 if (!my_isspace(&my_charset_latin1,*str)) 00441 { 00442 *was_cut= 1; 00443 break; 00444 } 00445 } 00446 00447 DBUG_RETURN(l_time->time_type= 00448 (number_of_fields <= 3 ? MYSQL_TIMESTAMP_DATE : 00449 MYSQL_TIMESTAMP_DATETIME)); 00450 00451 err: 00452 bzero((char*) l_time, sizeof(*l_time)); 00453 DBUG_RETURN(MYSQL_TIMESTAMP_ERROR); 00454 }
Here is the call graph for this function:

| my_bool str_to_time | ( | const char * | str, | |
| uint | length, | |||
| MYSQL_TIME * | l_time, | |||
| int * | was_cut | |||
| ) |
Definition at line 480 of file my_time.c.
References bmove_upp(), bzero, st_mysql_time::day, st_mysql_time::hour, internal_format_positions, LINT_INIT, log_10_int, st_mysql_time::minute, st_mysql_time::month, my_charset_latin1, my_isdigit, my_isspace, MYSQL_TIMESTAMP_ERROR, MYSQL_TIMESTAMP_TIME, st_mysql_time::neg, st_mysql_time::second, st_mysql_time::second_part, str_to_datetime(), TIME_DATETIME_ONLY, TIME_FUZZY_DATE, st_mysql_time::time_type, value, and st_mysql_time::year.
00482 { 00483 long date[5],value; 00484 const char *end=str+length, *end_of_days; 00485 my_bool found_days,found_hours; 00486 uint state; 00487 00488 l_time->neg=0; 00489 *was_cut= 0; 00490 for (; str != end && my_isspace(&my_charset_latin1,*str) ; str++) 00491 length--; 00492 if (str != end && *str == '-') 00493 { 00494 l_time->neg=1; 00495 str++; 00496 length--; 00497 } 00498 if (str == end) 00499 return 1; 00500 00501 /* Check first if this is a full TIMESTAMP */ 00502 if (length >= 12) 00503 { /* Probably full timestamp */ 00504 enum enum_mysql_timestamp_type 00505 res= str_to_datetime(str, length, l_time, 00506 (TIME_FUZZY_DATE | TIME_DATETIME_ONLY), was_cut); 00507 if ((int) res >= (int) MYSQL_TIMESTAMP_ERROR) 00508 return res == MYSQL_TIMESTAMP_ERROR; 00509 /* We need to restore was_cut flag since str_to_datetime can modify it */ 00510 *was_cut= 0; 00511 } 00512 00513 /* Not a timestamp. Try to get this as a DAYS_TO_SECOND string */ 00514 for (value=0; str != end && my_isdigit(&my_charset_latin1,*str) ; str++) 00515 value=value*10L + (long) (*str - '0'); 00516 00517 /* Skip all space after 'days' */ 00518 end_of_days= str; 00519 for (; str != end && my_isspace(&my_charset_latin1, str[0]) ; str++) 00520 ; 00521 00522 LINT_INIT(state); 00523 found_days=found_hours=0; 00524 if ((uint) (end-str) > 1 && str != end_of_days && 00525 my_isdigit(&my_charset_latin1, *str)) 00526 { /* Found days part */ 00527 date[0]= value; 00528 state= 1; /* Assume next is hours */ 00529 found_days= 1; 00530 } 00531 else if ((end-str) > 1 && *str == time_separator && 00532 my_isdigit(&my_charset_latin1, str[1])) 00533 { 00534 date[0]=0; /* Assume we found hours */ 00535 date[1]=value; 00536 state=2; 00537 found_hours=1; 00538 str++; /* skip ':' */ 00539 } 00540 else 00541 { 00542 /* String given as one number; assume HHMMSS format */ 00543 date[0]= 0; 00544 date[1]= value/10000; 00545 date[2]= value/100 % 100; 00546 date[3]= value % 100; 00547 state=4; 00548 goto fractional; 00549 } 00550 00551 /* Read hours, minutes and seconds */ 00552 for (;;) 00553 { 00554 for (value=0; str != end && my_isdigit(&my_charset_latin1,*str) ; str++) 00555 value=value*10L + (long) (*str - '0'); 00556 date[state++]=value; 00557 if (state == 4 || (end-str) < 2 || *str != time_separator || 00558 !my_isdigit(&my_charset_latin1,str[1])) 00559 break; 00560 str++; /* Skip time_separator (':') */ 00561 } 00562 00563 if (state != 4) 00564 { /* Not HH:MM:SS */ 00565 /* Fix the date to assume that seconds was given */ 00566 if (!found_hours && !found_days) 00567 { 00568 bmove_upp((char*) (date+4), (char*) (date+state), 00569 sizeof(long)*(state-1)); 00570 bzero((char*) date, sizeof(long)*(4-state)); 00571 } 00572 else 00573 bzero((char*) (date+state), sizeof(long)*(4-state)); 00574 } 00575 00576 fractional: 00577 /* Get fractional second part */ 00578 if ((end-str) >= 2 && *str == '.' && my_isdigit(&my_charset_latin1,str[1])) 00579 { 00580 int field_length= 5; 00581 str++; value=(uint) (uchar) (*str - '0'); 00582 while (++str != end && my_isdigit(&my_charset_latin1, *str)) 00583 { 00584 if (field_length-- > 0) 00585 value= value*10 + (uint) (uchar) (*str - '0'); 00586 } 00587 if (field_length > 0) 00588 value*= (long) log_10_int[field_length]; 00589 else if (field_length < 0) 00590 *was_cut= 1; 00591 date[4]=value; 00592 } 00593 else 00594 date[4]=0; 00595 00596 /* Check for exponent part: E<gigit> | E<sign><digit> */ 00597 /* (may occur as result of %g formatting of time value) */ 00598 if ((end - str) > 1 && 00599 (*str == 'e' || *str == 'E') && 00600 (my_isdigit(&my_charset_latin1, str[1]) || 00601 ((str[1] == '-' || str[1] == '+') && 00602 (end - str) > 2 && 00603 my_isdigit(&my_charset_latin1, str[2])))) 00604 { 00605 *was_cut= 1; 00606 return 1; 00607 } 00608 00609 if (internal_format_positions[7] != 255) 00610 { 00611 /* Read a possible AM/PM */ 00612 while (str != end && my_isspace(&my_charset_latin1, *str)) 00613 str++; 00614 if (str+2 <= end && (str[1] == 'M' || str[1] == 'm')) 00615 { 00616 if (str[0] == 'p' || str[0] == 'P') 00617 { 00618 str+= 2; 00619 date[1]= date[1]%12 + 12; 00620 } 00621 else if (str[0] == 'a' || str[0] == 'A') 00622 str+=2; 00623 } 00624 } 00625 00626 /* Some simple checks */ 00627 if (date[2] >= 60 || date[3] >= 60) 00628 { 00629 *was_cut= 1; 00630 return 1; 00631 } 00632 l_time->year= 0; /* For protocol::store_time */ 00633 l_time->month= 0; 00634 l_time->day= date[0]; 00635 l_time->hour= date[1]; 00636 l_time->minute= date[2]; 00637 l_time->second= date[3]; 00638 l_time->second_part= date[4]; 00639 l_time->time_type= MYSQL_TIMESTAMP_TIME; 00640 00641 /* Check if there is garbage at end of the TIME specification */ 00642 if (str != end) 00643 { 00644 do 00645 { 00646 if (!my_isspace(&my_charset_latin1,*str)) 00647 { 00648 *was_cut= 1; 00649 break; 00650 } 00651 } while (++str != end); 00652 } 00653 return 0; 00654 }
Here is the call graph for this function:

| ulonglong TIME_to_ulonglong | ( | const MYSQL_TIME * | time | ) |
Definition at line 1050 of file my_time.c.
References DBUG_ASSERT, MYSQL_TIMESTAMP_DATE, MYSQL_TIMESTAMP_DATETIME, MYSQL_TIMESTAMP_ERROR, MYSQL_TIMESTAMP_NONE, MYSQL_TIMESTAMP_TIME, TIME_to_ulonglong_date(), TIME_to_ulonglong_datetime(), TIME_to_ulonglong_time(), st_mysql_time::time_type, and ULL.
01051 { 01052 switch (time->time_type) { 01053 case MYSQL_TIMESTAMP_DATETIME: 01054 return TIME_to_ulonglong_datetime(time); 01055 case MYSQL_TIMESTAMP_DATE: 01056 return TIME_to_ulonglong_date(time); 01057 case MYSQL_TIMESTAMP_TIME: 01058 return TIME_to_ulonglong_time(time); 01059 case MYSQL_TIMESTAMP_NONE: 01060 case MYSQL_TIMESTAMP_ERROR: 01061 return ULL(0); 01062 default: 01063 DBUG_ASSERT(0); 01064 } 01065 return 0; 01066 }
Here is the call graph for this function:

| ulonglong TIME_to_ulonglong_date | ( | const MYSQL_TIME * | time | ) |
Definition at line 1010 of file my_time.c.
References st_mysql_time::day, st_mysql_time::month, and st_mysql_time::year.
| ulonglong TIME_to_ulonglong_datetime | ( | const MYSQL_TIME * | time | ) |
Definition at line 997 of file my_time.c.
References st_mysql_time::day, st_mysql_time::hour, st_mysql_time::minute, st_mysql_time::month, st_mysql_time::second, ULL, and st_mysql_time::year.
00998 { 00999 return ((ulonglong) (time->year * 10000UL + 01000 time->month * 100UL + 01001 time->day) * ULL(1000000) + 01002 (ulonglong) (time->hour * 10000UL + 01003 time->minute * 100UL + 01004 time->second)); 01005 }
| ulonglong TIME_to_ulonglong_time | ( | const MYSQL_TIME * | time | ) |
Definition at line 1022 of file my_time.c.
References st_mysql_time::hour, st_mysql_time::minute, and st_mysql_time::second.
01023 { 01024 return (ulonglong) (time->hour * 10000UL + 01025 time->minute * 100UL + 01026 time->second); 01027 }
ulong const days_at_timestart = 719528 [static] |
| uchar days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0} |
uchar internal_format_positions[] [static] |
Initial value:
{0, 1, 2, 3, 4, 5, 6, (uchar) 255}
Definition at line 35 of file my_time.c.
Referenced by str_to_datetime(), and str_to_time().
| ulonglong log_10_int[20] |
Initial value:
{
1, 10, 100, 1000, 10000UL, 100000UL, 1000000UL, 10000000UL,
ULL(100000000), ULL(1000000000), ULL(10000000000), ULL(100000000000),
ULL(1000000000000), ULL(10000000000000), ULL(100000000000000),
ULL(1000000000000000), ULL(10000000000000000), ULL(100000000000000000),
ULL(1000000000000000000), ULL(10000000000000000000)
}
long my_time_zone = 0 [static] |
char time_separator = ':' [static] |
1.4.7

