14
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
16
#include <my_time.h>
17
#include <mystrings/m_string.h>
18
#include <mystrings/m_ctype.h>
19
19
/* Windows version of localtime_r() is declared in my_ptrhead.h */
20
#include <my_pthread.h>
20
#include <mysys/my_pthread.h>
22
22
uint64_t log_10_int[20]=
78
my_bool check_date(const MYSQL_TIME *ltime, my_bool not_zero_date,
78
bool check_date(const DRIZZLE_TIME *ltime, bool not_zero_date,
79
79
ulong flags, int *was_cut)
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,
159
enum enum_drizzle_timestamp_type
160
str_to_datetime(const char *str, uint length, DRIZZLE_TIME *l_time,
161
161
uint flags, int *was_cut)
163
163
uint field_length, year_length=4, digits, i, number_of_fields;
164
164
uint date[MAX_DATE_PARTS], date_len[MAX_DATE_PARTS];
165
165
uint add_hours= 0, start_loop;
166
166
ulong not_zero_date, allow_space;
167
my_bool is_internal_format;
167
bool is_internal_format;
168
168
const char *pos, *last_field_pos=NULL;
169
169
const char *end=str+length;
170
170
const uchar *format_position;
171
my_bool found_delimitier= 0, found_space= 0;
171
bool found_delimitier= 0, found_space= 0;
172
172
uint frac_pos, frac_len;
226
226
if (flags & TIME_DATETIME_ONLY)
229
return(MYSQL_TIMESTAMP_NONE); /* Can't be a full datetime */
229
return(DRIZZLE_TIMESTAMP_NONE); /* Can't be a full datetime */
231
231
/* Date field. Set hour, minutes and seconds to 0 */
232
232
date[0]= date[1]= date[2]= date[3]= date[4]= 0;
436
436
return(l_time->time_type=
437
(number_of_fields <= 3 ? MYSQL_TIMESTAMP_DATE :
438
MYSQL_TIMESTAMP_DATETIME));
437
(number_of_fields <= 3 ? DRIZZLE_TIMESTAMP_DATE :
438
DRIZZLE_TIMESTAMP_DATETIME));
441
bzero((char*) l_time, sizeof(*l_time));
442
return(MYSQL_TIMESTAMP_ERROR);
441
memset((char*) l_time, 0, sizeof(*l_time));
442
return(DRIZZLE_TIMESTAMP_ERROR);
447
Convert a time string to a MYSQL_TIME struct.
447
Convert a time string to a DRIZZLE_TIME struct.
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 MYSQL_TIME_WARN_TRUNCATED flag if the input string
457
warning Set DRIZZLE_TIME_WARN_TRUNCATED flag if the input string
458
458
was cut during conversion, and/or
459
MYSQL_TIME_WARN_OUT_OF_RANGE flag, if the value is
459
DRIZZLE_TIME_WARN_OUT_OF_RANGE flag, if the value is
471
my_bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
471
bool str_to_time(const char *str, uint length, DRIZZLE_TIME *l_time,
476
476
const char *end=str+length, *end_of_days;
477
my_bool found_days,found_hours;
477
bool found_days,found_hours;
494
494
if (length >= 12)
495
495
{ /* Probably full timestamp */
497
enum enum_mysql_timestamp_type
497
enum enum_drizzle_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) MYSQL_TIMESTAMP_ERROR)
500
if ((int) res >= (int) DRIZZLE_TIMESTAMP_ERROR)
503
*warning|= MYSQL_TIME_WARN_TRUNCATED;
504
return res == MYSQL_TIMESTAMP_ERROR;
503
*warning|= DRIZZLE_TIME_WARN_TRUNCATED;
504
return res == DRIZZLE_TIMESTAMP_ERROR;
562
562
bmove_upp((uchar*) (date+4), (uchar*) (date+state),
563
563
sizeof(long)*(state-1));
564
bzero((uchar*) date, sizeof(long)*(4-state));
564
memset((uchar*) date, 0, sizeof(long)*(4-state));
567
bzero((uchar*) (date+state), sizeof(long)*(4-state));
567
memset((uchar*) (date+state), 0, sizeof(long)*(4-state));
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= MYSQL_TIMESTAMP_TIME;
630
l_time->time_type= DRIZZLE_TIMESTAMP_TIME;
632
/* 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 */
633
633
if (check_time_range(l_time, warning))
636
/* 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 */
641
641
if (!my_isspace(&my_charset_latin1,*str))
643
*warning|= MYSQL_TIME_WARN_TRUNCATED;
643
*warning|= DRIZZLE_TIME_WARN_TRUNCATED;
646
646
} while (++str != end);
653
Check 'time' value to lie in the MYSQL_TIME range
653
Check 'time' value to lie in the DRIZZLE_TIME range
656
656
check_time_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
657
time pointer to DRIZZLE_TIME value
658
warning set DRIZZLE_TIME_WARN_OUT_OF_RANGE flag if the value is out of range
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
MYSQL_TIME_WARN_OUT_OF_RANGE flag in the 'warning' variable.
663
DRIZZLE_TIME_WARN_OUT_OF_RANGE flag in the 'warning' variable.
666
666
0 time value is valid, but was possibly truncated
667
667
1 time value is invalid
670
int check_time_range(struct st_mysql_time *my_time, int *warning)
670
int check_time_range(DRIZZLE_TIME *my_time, int *warning)
791
791
Time in UTC seconds since Unix Epoch representation.
794
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,
795
795
bool *in_dst_time_gap)
801
MYSQL_TIME *t= &tmp_time;
800
DRIZZLE_TIME tmp_time;
801
DRIZZLE_TIME *t= &tmp_time;
802
802
struct tm *l_time,tm_tmp;
803
803
long diff, current_timezone;
806
806
Use temp variable to avoid trashing input data, which could happen in
807
807
case of shift required for boundary dates processing.
809
memcpy(&tmp_time, t_src, sizeof(MYSQL_TIME));
809
memcpy(&tmp_time, t_src, sizeof(DRIZZLE_TIME));
811
811
if (!validate_timestamp_range(t))
980
980
} /* my_system_gmt_sec */
983
/* 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 */
985
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)
987
bzero((void*) tm, sizeof(*tm));
987
memset((void*) tm, 0, sizeof(*tm));
988
988
tm->time_type= time_type;
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 MYSQL_TIME structure members are
995
This functions don't check that given DRIZZLE_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'
1005
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)
1007
1007
uint extra_hours= 0;
1008
1008
return sprintf(to, "%s%02u:%02u:%02u",
1012
1012
l_time->second);
1015
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)
1017
1017
return sprintf(to, "%04u-%02u-%02u",
1023
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)
1025
1025
return sprintf(to, "%04u-%02u-%02u %02u:%02u:%02u",
1043
1043
The string must have at least MAX_DATE_STRING_REP_LENGTH bytes reserved.
1046
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)
1048
1048
switch (l_time->time_type) {
1049
case MYSQL_TIMESTAMP_DATETIME:
1049
case DRIZZLE_TIMESTAMP_DATETIME:
1050
1050
return my_datetime_to_str(l_time, to);
1051
case MYSQL_TIMESTAMP_DATE:
1051
case DRIZZLE_TIMESTAMP_DATE:
1052
1052
return my_date_to_str(l_time, to);
1053
case MYSQL_TIMESTAMP_TIME:
1053
case DRIZZLE_TIMESTAMP_TIME:
1054
1054
return my_time_to_str(l_time, to);
1055
case MYSQL_TIMESTAMP_NONE:
1056
case MYSQL_TIMESTAMP_ERROR:
1055
case DRIZZLE_TIMESTAMP_NONE:
1056
case DRIZZLE_TIMESTAMP_ERROR:
1080
1080
Convert a datetime value of formats YYMMDD, YYYYMMDD, YYMMDDHHMSS,
1081
YYYYMMDDHHMMSS to broken-down MYSQL_TIME representation. Return value in
1081
YYYYMMDDHHMMSS to broken-down DRIZZLE_TIME representation. Return value in
1082
1082
YYYYMMDDHHMMSS format as side-effect.
1084
1084
This function also checks if datetime value fits in DATETIME range.
1089
1089
Datetime value in YYYYMMDDHHMMSS format.
1092
int64_t number_to_datetime(int64_t nr, MYSQL_TIME *time_res,
1092
int64_t number_to_datetime(int64_t nr, DRIZZLE_TIME *time_res,
1093
1093
uint flags, int *was_cut)
1095
1095
long part1,part2;
1098
bzero((char*) time_res, sizeof(*time_res));
1099
time_res->time_type=MYSQL_TIMESTAMP_DATE;
1098
memset((char*) time_res, 0, sizeof(*time_res));
1099
time_res->time_type=DRIZZLE_TIMESTAMP_DATE;
1101
1101
if (nr == 0LL || nr >= 10000101000000LL)
1103
time_res->time_type=MYSQL_TIMESTAMP_DATETIME;
1103
time_res->time_type=DRIZZLE_TIMESTAMP_DATETIME;
1168
1168
/* Convert time value to integer in YYYYMMDDHHMMSS format */
1170
uint64_t TIME_to_uint64_t_datetime(const MYSQL_TIME *my_time)
1170
uint64_t TIME_to_uint64_t_datetime(const DRIZZLE_TIME *my_time)
1172
1172
return ((uint64_t) (my_time->year * 10000UL +
1173
1173
my_time->month * 100UL +
1181
/* Convert MYSQL_TIME value to integer in YYYYMMDD format */
1181
/* Convert DRIZZLE_TIME value to integer in YYYYMMDD format */
1183
uint64_t TIME_to_uint64_t_date(const MYSQL_TIME *my_time)
1183
uint64_t TIME_to_uint64_t_date(const DRIZZLE_TIME *my_time)
1185
1185
return (uint64_t) (my_time->year * 10000UL + my_time->month * 100UL +
1191
Convert MYSQL_TIME value to integer in HHMMSS format.
1191
Convert DRIZZLE_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.
1196
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)
1198
1198
return (uint64_t) (my_time->hour * 10000UL +
1199
1199
my_time->minute * 100UL +
1205
Convert struct MYSQL_TIME (date and time split into year/month/day/hour/...
1205
Convert struct DRIZZLE_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).
1219
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
1220
1220
in valid range. If they are not, return value won't reflect any
1221
1221
valid date either.
1224
uint64_t TIME_to_uint64_t(const MYSQL_TIME *my_time)
1224
uint64_t TIME_to_uint64_t(const DRIZZLE_TIME *my_time)
1226
1226
switch (my_time->time_type) {
1227
case MYSQL_TIMESTAMP_DATETIME:
1227
case DRIZZLE_TIMESTAMP_DATETIME:
1228
1228
return TIME_to_uint64_t_datetime(my_time);
1229
case MYSQL_TIMESTAMP_DATE:
1229
case DRIZZLE_TIMESTAMP_DATE:
1230
1230
return TIME_to_uint64_t_date(my_time);
1231
case MYSQL_TIMESTAMP_TIME:
1231
case DRIZZLE_TIMESTAMP_TIME:
1232
1232
return TIME_to_uint64_t_time(my_time);
1233
case MYSQL_TIMESTAMP_NONE:
1234
case MYSQL_TIMESTAMP_ERROR:
1233
case DRIZZLE_TIMESTAMP_NONE:
1234
case DRIZZLE_TIMESTAMP_ERROR: