98
bool Time::check(bool not_zero_date, uint32_t flags, type::cut_t &was_cut) const
93
bool check_date(const DRIZZLE_TIME *ltime, bool not_zero_date,
94
uint32_t flags, int *was_cut)
100
96
if (not_zero_date)
102
98
if ((((flags & TIME_NO_ZERO_IN_DATE) || !(flags & TIME_FUZZY_DATE)) &&
103
(month == 0 || day == 0)) ||
104
(not (flags & TIME_INVALID_DATES) &&
105
month && day > days_in_month[month-1] &&
106
(month != 2 || calc_days_in_year(year) != 366 ||
99
(ltime->month == 0 || ltime->day == 0)) ||
100
(!(flags & TIME_INVALID_DATES) &&
101
ltime->month && ltime->day > days_in_month[ltime->month-1] &&
102
(ltime->month != 2 || calc_days_in_year(ltime->year) != 366 ||
109
was_cut= type::INVALID;
113
109
else if (flags & TIME_NO_ZERO_DATE)
116
We don't set &was_cut here to signal that the problem was a zero date
112
We don't set *was_cut here to signal that the problem was a zero date
117
113
and not an invalid date
366
if (!is_internal_format)
370
if (not is_internal_format)
372
year_length= date_len[(uint32_t) format_position[0]];
373
if (!year_length) /* Year must be specified */
368
year_length= date_len[(uint32_t) format_position[0]];
369
if (!year_length) /* Year must be specified */
372
return(DRIZZLE_TIMESTAMP_NONE);
375
l_time->year= date[(uint32_t) format_position[0]];
376
l_time->month= date[(uint32_t) format_position[1]];
377
l_time->day= date[(uint32_t) format_position[2]];
378
l_time->hour= date[(uint32_t) format_position[3]];
379
l_time->minute= date[(uint32_t) format_position[4]];
380
l_time->second= date[(uint32_t) format_position[5]];
382
frac_pos= (uint32_t) format_position[6];
383
frac_len= date_len[frac_pos];
385
date[frac_pos]*= (uint32_t) log_10_int[6 - frac_len];
386
l_time->second_part= date[frac_pos];
388
if (format_position[7] != (unsigned char) 255)
390
if (l_time->hour > 12)
376
return(type::DRIZZLE_TIMESTAMP_NONE);
379
this->year= date[(uint32_t) format_position[0]];
380
this->month= date[(uint32_t) format_position[1]];
381
this->day= date[(uint32_t) format_position[2]];
382
this->hour= date[(uint32_t) format_position[3]];
383
this->minute= date[(uint32_t) format_position[4]];
384
this->second= date[(uint32_t) format_position[5]];
386
frac_pos= (uint32_t) format_position[6];
387
frac_len= date_len[frac_pos];
389
date[frac_pos]*= (uint32_t) log_10_int[6 - frac_len];
390
this->second_part= date[frac_pos];
392
if (format_position[7] != (unsigned char) 255)
395
l_time->hour= l_time->hour%12 + add_hours;
400
l_time->year= date[0];
401
l_time->month= date[1];
402
l_time->day= date[2];
403
l_time->hour= date[3];
404
l_time->minute= date[4];
405
l_time->second= date[5];
407
date[6]*= (uint32_t) log_10_int[6 - date_len[6]];
408
l_time->second_part=date[6];
412
if (year_length == 2 && not_zero_date)
413
l_time->year+= (l_time->year < YY_PART_YEAR ? 2000 : 1900);
415
if (number_of_fields < 3 ||
416
l_time->year > 9999 || l_time->month > 12 ||
417
l_time->day > 31 || l_time->hour > 23 ||
418
l_time->minute > 59 || l_time->second > 59)
420
/* Only give warning for a zero date if there is some garbage after */
421
if (!not_zero_date) /* If zero date */
423
for (; str != end ; str++)
425
if (!my_isspace(&my_charset_utf8_general_ci, *str))
427
not_zero_date= 1; /* Give warning */
399
this->hour= this->hour%12 + add_hours;
405
this->month= date[1];
408
this->minute= date[4];
409
this->second= date[5];
411
date[6]*= (uint32_t) log_10_int[6 - date_len[6]];
412
this->second_part=date[6];
416
if (year_length == 2 && not_zero_date)
417
this->year+= (this->year < YY_PART_YEAR ? 2000 : 1900);
419
if (number_of_fields < 3 ||
420
this->year > 9999 || this->month > 12 ||
421
this->day > 31 || this->hour > 23 ||
422
this->minute > 59 || this->second > 59)
424
/* Only give warning for a zero date if there is some garbage after */
425
if (!not_zero_date) /* If zero date */
427
for (; str != end ; str++)
429
if (!my_isspace(&my_charset_utf8_general_ci, *str))
431
not_zero_date= 1; /* Give warning */
436
was_cut= test(not_zero_date) ? type::CUT : type::VALID;
440
if (check(not_zero_date != 0, flags, was_cut))
445
this->time_type= (number_of_fields <= 3 ?
446
type::DRIZZLE_TIMESTAMP_DATE : type::DRIZZLE_TIMESTAMP_DATETIME);
448
for (; str != end ; str++)
450
if (!my_isspace(&my_charset_utf8_general_ci,*str))
457
return(time_type= (number_of_fields <= 3 ? type::DRIZZLE_TIMESTAMP_DATE : type::DRIZZLE_TIMESTAMP_DATETIME));
462
return type::DRIZZLE_TIMESTAMP_ERROR;
465
type::timestamp_t Time::store(const char *str, uint32_t length, uint32_t flags)
468
return store(str, length, flags, was_cut);
432
*was_cut= test(not_zero_date);
436
if (check_date(l_time, not_zero_date != 0, flags, was_cut))
439
l_time->time_type= (number_of_fields <= 3 ?
440
DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME);
442
for (; str != end ; str++)
444
if (!my_isspace(&my_charset_utf8_general_ci,*str))
451
return(l_time->time_type=
452
(number_of_fields <= 3 ? DRIZZLE_TIMESTAMP_DATE :
453
DRIZZLE_TIMESTAMP_DATETIME));
456
memset(l_time, 0, sizeof(*l_time));
457
return(DRIZZLE_TIMESTAMP_ERROR);
472
Convert a time string to a type::Time struct.
462
Convert a time string to a DRIZZLE_TIME struct.
501
492
bool found_days,found_hours;
504
assert(arg == DRIZZLE_TIMESTAMP_TIME);
508
497
for (; str != end && my_isspace(&my_charset_utf8_general_ci,*str) ; str++)
510
499
if (str != end && *str == '-')
519
508
/* Check first if this is a full TIMESTAMP */
520
509
if (length >= 12)
521
510
{ /* Probably full timestamp */
523
type::timestamp_t res= this->store(str, length, (TIME_FUZZY_DATE | TIME_DATETIME_ONLY), was_cut);
524
if ((int) res >= (int) type::DRIZZLE_TIMESTAMP_ERROR)
512
enum enum_drizzle_timestamp_type
513
res= str_to_datetime(str, length, l_time,
514
(TIME_FUZZY_DATE | TIME_DATETIME_ONLY), &was_cut);
515
if ((int) res >= (int) DRIZZLE_TIMESTAMP_ERROR)
526
if (was_cut != type::VALID)
527
warning|= DRIZZLE_TIME_WARN_TRUNCATED;
529
return res == type::DRIZZLE_TIMESTAMP_ERROR;
518
*warning|= DRIZZLE_TIME_WARN_TRUNCATED;
519
return res == DRIZZLE_TIMESTAMP_ERROR;
1009
985
/* shift back, if we were dealing with boundary dates */
1010
epoch+= shift*86400L;
1013
989
This is possible for dates, which slightly exceed boundaries.
1014
990
Conversion will pass ok for them, but we don't allow them.
1015
991
First check will pass for platforms with signed time_t.
1016
instruction above (epoch+= shift*86400L) could exceed
992
instruction above (tmp+= shift*86400L) could exceed
1017
993
MAX_INT32 (== TIMESTAMP_MAX_VALUE) and overflow will happen.
1018
So, epoch < TIMESTAMP_MIN_VALUE will be triggered.
994
So, tmp < TIMESTAMP_MIN_VALUE will be triggered. On platfroms
995
with unsigned time_t tmp+= shift*86400L might result in a number,
996
larger then TIMESTAMP_MAX_VALUE, so another check will work.
1020
if (epoch < TIMESTAMP_MIN_VALUE)
998
if ((tmp < TIMESTAMP_MIN_VALUE) || (tmp > TIMESTAMP_MAX_VALUE))
1001
return (time_t) tmp;
1024
1002
} /* my_system_gmt_sec */
1027
void Time::store(const struct tm &from)
1029
_is_local_time= false;
1032
year= (int32_t) ((from.tm_year+1900) % 10000);
1033
month= (int32_t) from.tm_mon+1;
1034
day= (int32_t) from.tm_mday;
1035
hour= (int32_t) from.tm_hour;
1036
minute= (int32_t) from.tm_min;
1037
second= (int32_t) from.tm_sec;
1039
time_type= DRIZZLE_TIMESTAMP_DATETIME;
1042
void Time::store(const struct timeval &from)
1044
store(from.tv_sec, (usec_t)from.tv_usec);
1045
time_type= type::DRIZZLE_TIMESTAMP_DATETIME;
1049
void Time::store(const type::Time::epoch_t &from, bool use_localtime)
1051
store(from, 0, use_localtime);
1054
void Time::store(const type::Time::epoch_t &from_arg, const usec_t &from_fractional_seconds, bool use_localtime)
1056
epoch_t from= from_arg;
1060
util::localtime(from, *this);
1061
_is_local_time= true;
1065
util::gmtime(from, *this);
1068
// Since time_t/epoch_t doesn't have fractional seconds, we have to
1069
// collect them outside of the gmtime function.
1070
second_part= from_fractional_seconds;
1071
time_type= DRIZZLE_TIMESTAMP_DATETIME;
1074
// Only implemented for one case, extend as needed.
1075
void Time::truncate(const timestamp_t arg)
1077
assert(arg == type::DRIZZLE_TIMESTAMP_TIME);
1078
year= month= day= 0;
1083
void Time::convert(String &str, timestamp_t arg)
1085
str.alloc(MAX_STRING_LENGTH);
1086
size_t length= MAX_STRING_LENGTH;
1088
convert(str.c_ptr(), length, arg);
1091
str.set_charset(&my_charset_bin);
1094
void Time::convert(char *str, size_t &to_length, timestamp_t arg)
1005
/* Set DRIZZLE_TIME structure to 0000-00-00 00:00:00.000000 */
1007
void set_zero_time(DRIZZLE_TIME *tm, enum enum_drizzle_timestamp_type time_type)
1009
memset(tm, 0, sizeof(*tm));
1010
tm->time_type= time_type;
1015
Functions to convert time/date/datetime value to a string,
1016
using default format.
1017
This functions don't check that given DRIZZLE_TIME structure members are
1018
in valid range. If they are not, return value won't reflect any
1019
valid date either. Additionally, make_time doesn't take into
1020
account time->day member: it's assumed that days have been converted
1024
number of characters written to 'to'
1027
int my_time_to_str(const DRIZZLE_TIME *l_time, char *to)
1029
uint32_t extra_hours= 0;
1030
return sprintf(to, "%s%02u:%02u:%02u",
1031
(l_time->neg ? "-" : ""),
1032
extra_hours+ l_time->hour,
1037
int my_date_to_str(const DRIZZLE_TIME *l_time, char *to)
1039
return sprintf(to, "%04u-%02u-%02u",
1045
int my_datetime_to_str(const DRIZZLE_TIME *l_time, char *to)
1047
return sprintf(to, "%04u-%02u-%02u %02u:%02u:%02u",
1058
Convert struct DATE/TIME/DATETIME value to string using built-in
1059
MySQL time conversion formats.
1065
The string must have at least MAX_DATE_STRING_REP_LENGTH bytes reserved.
1068
int my_TIME_to_str(const DRIZZLE_TIME *l_time, char *to)
1070
switch (l_time->time_type) {
1098
1071
case DRIZZLE_TIMESTAMP_DATETIME:
1099
length= snprintf(str, to_length,
1100
"%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32
1101
" %02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 ".%06" PRIu32,
1072
return my_datetime_to_str(l_time, to);
1111
1073
case DRIZZLE_TIMESTAMP_DATE:
1112
length= snprintf(str, to_length, "%04u-%02u-%02u",
1074
return my_date_to_str(l_time, to);
1118
1075
case DRIZZLE_TIMESTAMP_TIME:
1120
uint32_t extra_hours= 0;
1122
length= snprintf(str, to_length,
1076
return my_time_to_str(l_time, to);
1131
1077
case DRIZZLE_TIMESTAMP_NONE:
1132
1078
case DRIZZLE_TIMESTAMP_ERROR:
1149
1089
Convert datetime value specified as number to broken-down TIME
1234
1174
if (time_res->year <= 9999 && time_res->month <= 12 &&
1235
1175
time_res->day <= 31 && time_res->hour <= 23 &&
1236
1176
time_res->minute <= 59 && time_res->second <= 59 &&
1237
not time_res->check((nr != 0), flags, was_cut))
1177
!check_date(time_res, (nr != 0), flags, was_cut))
1242
1180
/* Don't want to have was_cut get set if NO_ZERO_DATE was violated. */
1243
1181
if (!nr && (flags & TIME_NO_ZERO_DATE))
1254
void Time::convert(datetime_t &ret, int64_t nr, uint32_t flags)
1256
type::cut_t was_cut;
1257
ret= number_to_datetime(nr, this, flags, was_cut);
1260
void Time::convert(datetime_t &ret, int64_t nr, uint32_t flags, type::cut_t &was_cut)
1262
ret= number_to_datetime(nr, this, flags, was_cut);
1266
Convert struct type::Time (date and time split into year/month/day/hour/...
1190
/* Convert time value to integer in YYYYMMDDHHMMSS format */
1192
uint64_t TIME_to_uint64_t_datetime(const DRIZZLE_TIME *my_time)
1194
return ((uint64_t) (my_time->year * 10000UL +
1195
my_time->month * 100UL +
1196
my_time->day) * 1000000ULL +
1197
(uint64_t) (my_time->hour * 10000UL +
1198
my_time->minute * 100UL +
1203
/* Convert DRIZZLE_TIME value to integer in YYYYMMDD format */
1205
static uint64_t TIME_to_uint64_t_date(const DRIZZLE_TIME *my_time)
1207
return (uint64_t) (my_time->year * 10000UL + my_time->month * 100UL +
1213
Convert DRIZZLE_TIME value to integer in HHMMSS format.
1214
This function doesn't take into account time->day member:
1215
it's assumed that days have been converted to hours already.
1218
static uint64_t TIME_to_uint64_t_time(const DRIZZLE_TIME *my_time)
1220
return (uint64_t) (my_time->hour * 10000UL +
1221
my_time->minute * 100UL +
1227
Convert struct DRIZZLE_TIME (date and time split into year/month/day/hour/...
1267
1228
to a number in format YYYYMMDDHHMMSS (DATETIME),
1268
1229
YYYYMMDD (DATE) or HHMMSS (TIME).
1235
The function is used when we need to convert value of time item
1236
to a number if it's used in numeric context, i. e.:
1237
SELECT NOW()+1, CURDATE()+0, CURTIMIE()+0;
1241
This function doesn't check that given DRIZZLE_TIME structure members are
1242
in valid range. If they are not, return value won't reflect any
1272
void Time::convert(datetime_t &datetime, timestamp_t arg)
1246
uint64_t TIME_to_uint64_t(const DRIZZLE_TIME *my_time)
1276
// Convert to YYYYMMDDHHMMSS format
1277
case type::DRIZZLE_TIMESTAMP_DATETIME:
1278
datetime= ((int64_t) (year * 10000UL + month * 100UL + day) * 1000000ULL +
1279
(int64_t) (hour * 10000UL + minute * 100UL + second));
1282
// Convert to YYYYMMDD
1283
case type::DRIZZLE_TIMESTAMP_DATE:
1284
datetime= (year * 10000UL + month * 100UL + day);
1287
// Convert to HHMMSS
1288
case type::DRIZZLE_TIMESTAMP_TIME:
1289
datetime= (hour * 10000UL + minute * 100UL + second);
1292
case type::DRIZZLE_TIMESTAMP_NONE:
1293
case type::DRIZZLE_TIMESTAMP_ERROR:
1248
switch (my_time->time_type) {
1249
case DRIZZLE_TIMESTAMP_DATETIME:
1250
return TIME_to_uint64_t_datetime(my_time);
1251
case DRIZZLE_TIMESTAMP_DATE:
1252
return TIME_to_uint64_t_date(my_time);
1253
case DRIZZLE_TIMESTAMP_TIME:
1254
return TIME_to_uint64_t_time(my_time);
1255
case DRIZZLE_TIMESTAMP_NONE:
1256
case DRIZZLE_TIMESTAMP_ERROR:
1300
1264
} /* namespace drizzled */