23 #include "sql_class.h"
42 LEX_STRING interval_type_to_name[INTERVAL_LAST] = {
43 { C_STRING_WITH_LEN(
"YEAR")},
44 { C_STRING_WITH_LEN(
"QUARTER")},
45 { C_STRING_WITH_LEN(
"MONTH")},
46 { C_STRING_WITH_LEN(
"WEEK")},
47 { C_STRING_WITH_LEN(
"DAY")},
48 { C_STRING_WITH_LEN(
"HOUR")},
49 { C_STRING_WITH_LEN(
"MINUTE")},
50 { C_STRING_WITH_LEN(
"SECOND")},
51 { C_STRING_WITH_LEN(
"MICROSECOND")},
52 { C_STRING_WITH_LEN(
"YEAR_MONTH")},
53 { C_STRING_WITH_LEN(
"DAY_HOUR")},
54 { C_STRING_WITH_LEN(
"DAY_MINUTE")},
55 { C_STRING_WITH_LEN(
"DAY_SECOND")},
56 { C_STRING_WITH_LEN(
"HOUR_MINUTE")},
57 { C_STRING_WITH_LEN(
"HOUR_SECOND")},
58 { C_STRING_WITH_LEN(
"MINUTE_SECOND")},
59 { C_STRING_WITH_LEN(
"DAY_MICROSECOND")},
60 { C_STRING_WITH_LEN(
"HOUR_MICROSECOND")},
61 { C_STRING_WITH_LEN(
"MINUTE_MICROSECOND")},
62 { C_STRING_WITH_LEN(
"SECOND_MICROSECOND")}
68 int calc_weekday(
long daynr,
bool sunday_first_day_of_week)
70 DBUG_ENTER(
"calc_weekday");
71 DBUG_RETURN ((
int) ((daynr + 5L + (sunday_first_day_of_week ? 1L : 0L)) % 7));
103 uint calc_week(
MYSQL_TIME *l_time, uint week_behaviour, uint *year)
106 ulong daynr=calc_daynr(l_time->year,l_time->month,l_time->day);
107 ulong first_daynr=calc_daynr(l_time->year,1,1);
108 bool monday_first=
test(week_behaviour & WEEK_MONDAY_FIRST);
109 bool week_year=
test(week_behaviour & WEEK_YEAR);
110 bool first_weekday=
test(week_behaviour & WEEK_FIRST_WEEKDAY);
112 uint weekday=calc_weekday(first_daynr, !monday_first);
115 if (l_time->month == 1 && l_time->day <= 7-weekday)
118 ((first_weekday && weekday != 0) ||
119 (!first_weekday && weekday >= 4)))
123 first_daynr-= (days=calc_days_in_year(*year));
124 weekday= (weekday + 53*7- days) % 7;
127 if ((first_weekday && weekday != 0) ||
128 (!first_weekday && weekday >= 4))
129 days= daynr - (first_daynr+ (7-weekday));
131 days= daynr - (first_daynr - weekday);
133 if (week_year && days >= 52*7)
135 weekday= (weekday + calc_days_in_year(*year)) % 7;
136 if ((!first_weekday && weekday < 4) ||
137 (first_weekday && weekday == 0))
149 void get_date_from_daynr(
long daynr,uint *ret_year,uint *ret_month,
152 uint year,
temp,leap_day,day_of_year,days_in_year;
154 DBUG_ENTER(
"get_date_from_daynr");
156 if (daynr <= 365L || daynr >= 3652500)
158 *ret_year= *ret_month = *ret_day =0;
162 year= (uint) (daynr*100 / 36525L);
163 temp=(((year-1)/100+1)*3)/4;
164 day_of_year=(uint) (daynr - (
long) year * 365L) - (year-1)/4 +
temp;
165 while (day_of_year > (days_in_year= calc_days_in_year(year)))
167 day_of_year-=days_in_year;
171 if (days_in_year == 366)
173 if (day_of_year > 31+28)
176 if (day_of_year == 31+28)
181 for (month_pos= days_in_month ;
182 day_of_year > (uint) *month_pos ;
183 day_of_year-= *(month_pos++), (*ret_month)++)
186 *ret_day=day_of_year+leap_day;
193 ulong convert_period_to_month(ulong period)
198 if ((a=period/100) < YY_PART_YEAR)
207 ulong convert_month_to_period(ulong month)
212 if ((year=month/12) < 100)
214 year+=(year < YY_PART_YEAR) ? 2000 : 1900;
216 return year*100+month%12+1;
232 const char *src, uint src_length,
233 char *dst, uint dst_length)
238 const char *srcend= src + src_length;
239 char *dst0= dst, *dstend= dst + dst_length - 1;
240 while (dst < dstend &&
241 (cnvres= (cs->cset->mb_wc)(cs, &wc,
243 (
const uchar*) srcend)) > 0 &&
255 bool str_to_time(
const CHARSET_INFO *cs,
const char *str,uint length,
258 char cnv[MAX_TIME_FULL_WIDTH + 3];
259 if ((cs->state & MY_CS_NONASCII) != 0)
261 length= to_ascii(cs, str, length, cnv,
sizeof(cnv));
264 return str_to_time(str, length, l_time, status) ||
265 (!(flags & TIME_NO_NSEC_ROUNDING) &&
266 time_add_nanoseconds_with_round(l_time, status->nanoseconds,
273 const char *str, uint length,
277 char cnv[MAX_DATETIME_FULL_WIDTH + 3];
278 if ((cs->state & MY_CS_NONASCII) != 0)
280 length= to_ascii(cs, str, length, cnv,
sizeof(cnv));
283 return str_to_datetime(str, length, l_time, flags, status) ||
284 (!(flags & TIME_NO_NSEC_ROUNDING) &&
285 datetime_add_nanoseconds_with_round(l_time,
299 bool time_add_nanoseconds_with_round(
MYSQL_TIME *ltime,
300 uint nanoseconds,
int *warnings)
303 DBUG_ASSERT(nanoseconds < 1000000000);
304 DBUG_ASSERT(!check_time_mmssff_range(ltime));
306 if (nanoseconds < 500)
314 if (ltime->second < 59)
321 if (ltime->minute < 59)
336 adjust_time_range(ltime, warnings);
349 bool datetime_add_nanoseconds_with_round(
MYSQL_TIME *ltime,
350 uint nanoseconds,
int *warnings)
352 DBUG_ASSERT(nanoseconds < 1000000000);
353 if (nanoseconds < 500)
362 memset(&interval, 0,
sizeof(interval));
365 if (check_date(ltime, non_zero_date(ltime),
366 (TIME_NO_ZERO_IN_DATE | TIME_NO_ZERO_DATE), warnings))
369 if (date_add_interval(ltime, INTERVAL_SECOND, interval))
371 *warnings|= MYSQL_TIME_WARN_OUT_OF_RANGE;
389 THD *thd= current_thd;
390 bool ret_val= str_to_datetime(str, l_time,
391 (flags | (thd->variables.sql_mode &
392 (MODE_INVALID_DATES | MODE_NO_ZERO_DATE))),
394 if (ret_val || status.warnings)
395 make_truncated_value_warning(
ErrConvString(str), l_time->time_type);
410 lldiv_t_to_datetime(lldiv_t lld,
MYSQL_TIME *ltime, uint flags,
int *warnings)
413 number_to_datetime(lld.quot, ltime, flags, warnings) == LL(-1))
416 set_zero_time(ltime, MYSQL_TIMESTAMP_ERROR);
418 *warnings|= MYSQL_TIME_WARN_TRUNCATED;
421 else if (ltime->time_type == MYSQL_TIMESTAMP_DATE)
428 if (lld.rem && !(flags & TIME_NO_DATE_FRAC_WARN))
429 *warnings|= MYSQL_TIME_WARN_TRUNCATED;
431 else if (!(flags & TIME_NO_NSEC_ROUNDING))
434 return datetime_add_nanoseconds_with_round(ltime, lld.rem % 1000, warnings);
448 my_decimal_to_datetime_with_warn(
const my_decimal *decimal,
455 if ((rc= my_decimal2lldiv_t(0, decimal, &lld)))
457 warnings|= MYSQL_TIME_WARN_TRUNCATED;
458 set_zero_time(ltime, MYSQL_TIMESTAMP_NONE);
461 rc= lldiv_t_to_datetime(lld, ltime, flags, &warnings);
464 make_truncated_value_warning(
ErrConvString(decimal), ltime->time_type);
477 my_double_to_datetime_with_warn(
double nr,
MYSQL_TIME *ltime, uint flags)
483 if ((rc= (double2lldiv_t(nr, &lld) != E_DEC_OK)))
485 warnings|= MYSQL_TIME_WARN_TRUNCATED;
486 set_zero_time(ltime, MYSQL_TIMESTAMP_NONE);
489 rc= lldiv_t_to_datetime(lld, ltime, flags, &warnings);
492 make_truncated_value_warning(
ErrConvString(nr), ltime->time_type);
504 my_longlong_to_datetime_with_warn(longlong nr,
MYSQL_TIME *ltime, uint flags)
507 bool rc= number_to_datetime(nr, ltime, flags, &warnings) == LL(-1);
509 make_truncated_value_warning(
ErrConvString(nr), MYSQL_TIMESTAMP_NONE);
523 static bool lldiv_t_to_time(lldiv_t lld,
MYSQL_TIME *ltime,
int *warnings)
525 if (number_to_time(lld.quot, ltime, warnings))
531 if ((ltime->neg|= (lld.rem < 0)))
534 return time_add_nanoseconds_with_round(ltime, lld.rem % 1000, warnings);
551 if ((rc= my_decimal2lldiv_t(0, decimal, &lld)))
553 warnings|= MYSQL_TIME_WARN_TRUNCATED;
554 set_zero_time(ltime, MYSQL_TIMESTAMP_TIME);
557 rc= lldiv_t_to_time(lld, ltime, &warnings);
560 make_truncated_value_warning(
ErrConvString(decimal), MYSQL_TIMESTAMP_TIME);
573 bool my_double_to_time_with_warn(
double nr,
MYSQL_TIME *ltime)
579 if ((rc= (double2lldiv_t(nr, &lld) != E_DEC_OK)))
581 warnings|= MYSQL_TIME_WARN_TRUNCATED;
582 set_zero_time(ltime, MYSQL_TIMESTAMP_TIME);
585 rc= lldiv_t_to_time(lld, ltime, &warnings);
588 make_truncated_value_warning(
ErrConvString(nr), MYSQL_TIMESTAMP_TIME);
601 bool my_longlong_to_time_with_warn(longlong nr,
MYSQL_TIME *ltime)
604 bool rc= number_to_time(nr, ltime, &warnings);
606 make_truncated_value_warning(
ErrConvString(nr), MYSQL_TIMESTAMP_TIME);
624 my_time_t TIME_to_timestamp(THD *thd,
const MYSQL_TIME *t, my_bool *in_dst_time_gap)
630 timestamp= thd->time_zone()->TIME_to_gmt_sec(t, in_dst_time_gap);
669 bool datetime_with_no_zero_in_date_to_timeval(THD *thd,
676 DBUG_ASSERT(!ltime->year && !ltime->day);
677 if (non_zero_time(ltime))
683 *warnings|= MYSQL_TIME_WARN_TRUNCATED;
686 tm->tv_sec= tm->tv_usec= 0;
690 my_bool in_dst_time_gap;
691 if (!(tm->tv_sec= TIME_to_timestamp(current_thd, ltime, &in_dst_time_gap)))
697 *warnings|= MYSQL_TIME_WARN_OUT_OF_RANGE;
700 else if (in_dst_time_gap)
708 *warnings|= MYSQL_TIME_WARN_INVALID_TIMESTAMP;
742 bool datetime_to_timeval(THD *thd,
const MYSQL_TIME *ltime,
743 struct timeval *tm,
int *warnings)
746 check_date(ltime, non_zero_date(ltime), TIME_NO_ZERO_IN_DATE, warnings) ||
747 datetime_with_no_zero_in_date_to_timeval(current_thd, ltime, tm, warnings);
762 bool ret_val= str_to_time(str, l_time, 0, &status);
763 if (ret_val || status.warnings)
764 make_truncated_value_warning(
ErrConvString(str), MYSQL_TIMESTAMP_TIME);
778 thd->variables.time_zone->gmt_sec_to_TIME(ltime2, thd->query_start());
779 ltime2->hour= ltime2->minute= ltime2->second= ltime2->
second_part= 0;
780 ltime2->time_type= MYSQL_TIMESTAMP_DATE;
781 mix_date_and_time(ltime2, ltime);
793 to->year= (int) ((from->tm_year+1900) % 10000);
794 to->month= (int) from->tm_mon+1;
795 to->day= (
int) from->tm_mday;
796 to->hour= (int) from->tm_hour;
797 to->minute= (
int) from->tm_min;
798 to->second= (int) from->tm_sec;
801 void calc_time_from_sec(
MYSQL_TIME *to, longlong seconds,
long microseconds)
805 to->time_type= MYSQL_TIMESTAMP_TIME;
809 DBUG_ASSERT(seconds < (0xFFFFFFFFLL * 3600LL));
810 to->hour= (long) (seconds / 3600L);
811 t_seconds= (long) (seconds % 3600L);
812 to->minute= t_seconds/60L;
813 to->second= t_seconds%60L;
844 bool parse_date_time_format(timestamp_type format_type,
845 const char *format, uint format_length,
848 uint
offset= 0, separators= 0;
849 const char *ptr= format, *format_str;
850 const char *end= ptr+format_length;
851 uchar *dt_pos= date_time_format->positions;
853 bool need_p= 0, allow_separator= 0;
854 ulong part_map= 0, separator_map= 0;
855 const char *parts[16];
857 date_time_format->time_separator= 0;
858 date_time_format->flag= 0;
864 dt_pos[0]= dt_pos[1]= dt_pos[2]= dt_pos[3]=
865 dt_pos[4]= dt_pos[5]= dt_pos[6]= dt_pos[7]= 255;
867 for (; ptr != end; ptr++)
869 if (*ptr ==
'%' && ptr+1 != end)
904 if (dt_pos[5] != offset-1 || ptr[-2] !=
'.')
915 if (dt_pos[position] != 255)
917 parts[position]= ptr-1;
923 if (part_map && position <= 2 && !(part_map & (1 | 2 | 4)))
925 part_map|= (ulong) 1 << position;
926 dt_pos[position]= offset++;
935 if (!allow_separator)
940 if (my_ispunct(&my_charset_latin1, *ptr))
941 separator_map|= (ulong) 1 << (offset-1);
942 else if (!my_isspace(&my_charset_latin1, *ptr))
948 if ((part_map & 32) && !(part_map & 64))
950 dt_pos[6]= dt_pos[5] +1;
952 if (dt_pos[6] == dt_pos[7])
963 if ((format_type == MYSQL_TIMESTAMP_DATETIME &&
964 !test_all_bits(part_map, (1 | 2 | 4 | 8 | 16 | 32))) ||
965 (format_type == MYSQL_TIMESTAMP_DATE && part_map != (1 | 2 | 4)) ||
966 (format_type == MYSQL_TIMESTAMP_TIME &&
967 !test_all_bits(part_map, 8 | 16 | 32)) ||
969 (need_p && dt_pos[6] +1 != dt_pos[7]) ||
970 (need_p ^ (dt_pos[7] != 255)))
973 if (dt_pos[6] != 255)
976 uint pos= dt_pos[6] -1;
978 separator_map= ((separator_map & ((ulong) (1 << pos)-1)) |
979 ((separator_map & ~((ulong) (1 << pos)-1)) >> 1));
991 if (dt_pos[7] != 255)
993 if (need_p && parts[7] != parts[6]+2)
1002 offset= dt_pos[6] <= 3 ? 3 : 6;
1004 separator_map= ((separator_map & ((ulong) (1 << offset)-1)) |
1005 ((separator_map & ~((ulong) (1 << offset)-1)) >> 1));
1008 switch (format_type) {
1009 case MYSQL_TIMESTAMP_DATE:
1010 format_str= known_date_time_formats[INTERNAL_FORMAT].date_format;
1012 case MYSQL_TIMESTAMP_TIME:
1014 format_str=known_date_time_formats[INTERNAL_FORMAT].time_format;
1020 if (format_length == 6 && !need_p &&
1021 !my_strnncoll(&my_charset_bin,
1022 (
const uchar *) format, 6,
1023 (
const uchar *) format_str, 6))
1025 if (separator_map == (1 | 2))
1027 if (format_type == MYSQL_TIMESTAMP_TIME)
1029 if (*(format+2) != *(format+5))
1032 date_time_format->time_separator= *(format+2);
1037 case MYSQL_TIMESTAMP_DATETIME:
1043 if ((format_length == 12 && !need_p &&
1044 !my_strnncoll(&my_charset_bin,
1045 (
const uchar *) format, 12,
1046 (
const uchar*) known_date_time_formats[INTERNAL_FORMAT].datetime_format,
1048 (separators == 5 && separator_map == (1 | 2 | 8 | 16)))
1077 *date_time_format_make(timestamp_type format_type,
1078 const char *format_str, uint format_length)
1082 if (format_length && format_length < 255 &&
1083 !parse_date_time_format(format_type, format_str,
1084 format_length, &tmp))
1086 tmp.format.str= (
char*) format_str;
1087 tmp.format.length= format_length;
1088 return date_time_format_copy((THD *)0, &tmp);
1113 ulong length=
sizeof(*format) + format->format.length + 1;
1122 new_format->format.str= (
char*) (new_format+1);
1123 memcpy((
char*) new_format->positions, (
char*) format->positions,
1124 sizeof(format->positions));
1125 new_format->time_separator= format->time_separator;
1127 memcpy((
char*) new_format->format.str, format->format.str,
1128 format->format.length);
1129 new_format->format.str[format->format.length]= 0;
1130 new_format->format.length= format->format.length;
1138 {
"USA",
"%m.%d.%Y",
"%Y-%m-%d %H.%i.%s",
"%h:%i:%s %p" },
1139 {
"JIS",
"%Y-%m-%d",
"%Y-%m-%d %H:%i:%s",
"%H:%i:%s" },
1140 {
"ISO",
"%Y-%m-%d",
"%Y-%m-%d %H:%i:%s",
"%H:%i:%s" },
1141 {
"EUR",
"%d.%m.%Y",
"%Y-%m-%d %H.%i.%s",
"%H.%i.%s" },
1142 {
"INTERNAL",
"%Y%m%d",
"%Y%m%d%H%i%s",
"%H%i%s" },
1153 timestamp_type
type)
1156 case MYSQL_TIMESTAMP_DATE:
1157 return format->date_format;
1158 case MYSQL_TIMESTAMP_DATETIME:
1159 return format->datetime_format;
1160 case MYSQL_TIMESTAMP_TIME:
1161 return format->time_format;
1193 uint length= (uint) my_time_to_str(l_time, (
char*) str->ptr(), dec);
1194 str->length(length);
1195 str->set_charset(&my_charset_numeric);
1208 uint length= (uint) my_date_to_str(l_time, (
char*) str->ptr());
1209 str->length(length);
1210 str->set_charset(&my_charset_numeric);
1224 uint length= (uint) my_datetime_to_str(l_time, (
char*) str->ptr(), dec);
1225 str->length(length);
1226 str->set_charset(&my_charset_numeric);
1238 if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
1240 str->set_charset(&my_charset_numeric);
1241 str->length(my_TIME_to_str(ltime, const_cast<char*>(str->ptr()), dec));
1246 void make_truncated_value_warning(THD *thd,
1247 Sql_condition::enum_warning_level
level,
1249 const char *field_name)
1251 char warn_buff[MYSQL_ERRMSG_SIZE];
1252 const char *type_str;
1255 switch (time_type) {
1256 case MYSQL_TIMESTAMP_DATE:
1259 case MYSQL_TIMESTAMP_TIME:
1262 case MYSQL_TIMESTAMP_DATETIME:
1264 type_str=
"datetime";
1268 cs->cset->snprintf(cs, warn_buff,
sizeof(warn_buff),
1269 ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
1270 type_str, val.ptr(), field_name,
1271 (ulong) thd->get_stmt_da()->current_row_for_warning());
1274 if (time_type > MYSQL_TIMESTAMP_ERROR)
1275 cs->cset->snprintf(cs, warn_buff,
sizeof(warn_buff),
1276 ER(ER_TRUNCATED_WRONG_VALUE),
1277 type_str, val.ptr());
1279 cs->cset->snprintf(cs, warn_buff,
sizeof(warn_buff),
1280 ER(ER_WRONG_VALUE), type_str, val.ptr());
1282 push_warning(thd, level, ER_TRUNCATED_WRONG_VALUE, warn_buff);
1287 #define MAX_DAY_NUMBER 3652424L
1295 sign= (interval.neg ? -1 : 1);
1298 case INTERVAL_SECOND:
1299 case INTERVAL_SECOND_MICROSECOND:
1300 case INTERVAL_MICROSECOND:
1301 case INTERVAL_MINUTE:
1303 case INTERVAL_MINUTE_MICROSECOND:
1304 case INTERVAL_MINUTE_SECOND:
1305 case INTERVAL_HOUR_MICROSECOND:
1306 case INTERVAL_HOUR_SECOND:
1307 case INTERVAL_HOUR_MINUTE:
1308 case INTERVAL_DAY_MICROSECOND:
1309 case INTERVAL_DAY_SECOND:
1310 case INTERVAL_DAY_MINUTE:
1311 case INTERVAL_DAY_HOUR:
1313 longlong sec, days, daynr, microseconds, extra_sec;
1314 ltime->time_type= MYSQL_TIMESTAMP_DATETIME;
1315 microseconds= ltime->
second_part + sign*interval.second_part;
1316 extra_sec= microseconds/1000000L;
1317 microseconds= microseconds%1000000L;
1319 sec=((ltime->day-1)*3600*24L+ltime->hour*3600+ltime->minute*60+
1321 sign* (longlong) (interval.day*3600*24L +
1322 interval.hour*LL(3600)+interval.minute*LL(60)+
1323 interval.second))+ extra_sec;
1324 if (microseconds < 0)
1326 microseconds+= LL(1000000);
1329 days= sec/(3600*LL(24));
1330 sec-= days*3600*LL(24);
1337 ltime->second= (uint) (sec % 60);
1338 ltime->minute= (uint) (sec/60 % 60);
1339 ltime->hour= (uint) (sec/3600);
1340 daynr= calc_daynr(ltime->year,ltime->month,1) + days;
1344 get_date_from_daynr((
long) daynr, <ime->year, <ime->month,
1350 period= (calc_daynr(ltime->year,ltime->month,ltime->day) +
1351 sign * (long) interval.day);
1355 get_date_from_daynr((
long) period,<ime->year,<ime->month,<ime->day);
1358 ltime->year+= sign * (long) interval.year;
1359 if ((ulong) ltime->year >= 10000L)
1361 if (ltime->month == 2 && ltime->day == 29 &&
1362 calc_days_in_year(ltime->year) != 366)
1365 case INTERVAL_YEAR_MONTH:
1366 case INTERVAL_QUARTER:
1367 case INTERVAL_MONTH:
1368 period= (ltime->year*12 + sign * (
long) interval.year*12 +
1369 ltime->month-1 + sign * (long) interval.month);
1370 if ((ulong) period >= 120000L)
1372 ltime->year= (uint) (period / 12);
1373 ltime->month= (uint) (period % 12L)+1;
1375 if (ltime->day > days_in_month[ltime->month-1])
1377 ltime->day = days_in_month[ltime->month-1];
1378 if (ltime->month == 2 && calc_days_in_year(ltime->year) == 366)
1389 push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
1390 ER_DATETIME_FUNCTION_OVERFLOW,
1391 ER(ER_DATETIME_FUNCTION_OVERFLOW),
1426 int l_sign, longlong *seconds_out,
long *microseconds_out)
1430 longlong microseconds;
1437 if (l_time1->time_type == MYSQL_TIMESTAMP_TIME)
1438 days= (long)l_time1->day - l_sign * (
long)l_time2->day;
1441 days= calc_daynr((uint) l_time1->year,
1442 (uint) l_time1->month,
1443 (uint) l_time1->day);
1444 if (l_time2->time_type == MYSQL_TIMESTAMP_TIME)
1445 days-= l_sign * (long)l_time2->day;
1447 days-= l_sign*calc_daynr((uint) l_time2->year,
1448 (uint) l_time2->month,
1449 (uint) l_time2->day);
1452 microseconds= ((longlong)days * SECONDS_IN_24H +
1453 (longlong)(l_time1->hour*3600L +
1454 l_time1->minute*60L +
1456 l_sign*(longlong)(l_time2->hour*3600L +
1457 l_time2->minute*60L +
1458 l_time2->second)) * LL(1000000) +
1463 if (microseconds < 0)
1465 microseconds= -microseconds;
1468 *seconds_out= microseconds/1000000L;
1469 *microseconds_out= (long) (microseconds%1000000L);
1492 ulonglong a_t= TIME_to_ulonglong_datetime(a);
1493 ulonglong b_t= TIME_to_ulonglong_datetime(b);
1510 static uint msec_round_add[7]=
1529 bool my_time_round(
MYSQL_TIME *ltime, uint dec)
1532 DBUG_ASSERT(dec <= DATETIME_MAX_DECIMALS);
1534 bool rc= time_add_nanoseconds_with_round(ltime,
1535 msec_round_add[dec], &warnings);
1537 my_time_trunc(ltime, dec);
1549 bool my_datetime_round(
MYSQL_TIME *ltime, uint dec,
int *warnings)
1551 DBUG_ASSERT(dec <= DATETIME_MAX_DECIMALS);
1553 bool rc= datetime_add_nanoseconds_with_round(ltime,
1554 msec_round_add[dec], warnings);
1556 my_time_trunc(ltime, dec);
1568 bool my_timeval_round(
struct timeval *tv, uint decimals)
1570 DBUG_ASSERT(decimals <= DATETIME_MAX_DECIMALS);
1571 uint nanoseconds= msec_round_add[decimals];
1572 tv->tv_usec+= (nanoseconds + 500) / 1000;
1573 if (tv->tv_usec < 1000000)
1578 if (!IS_TIME_T_VALID_FOR_TIMESTAMP(tv->tv_sec))
1580 tv->tv_sec= TIMESTAMP_MAX_VALUE;
1585 my_timeval_trunc(tv, decimals);
1598 DBUG_ASSERT(ldate->time_type == MYSQL_TIMESTAMP_DATE ||
1599 ldate->time_type == MYSQL_TIMESTAMP_DATETIME);
1601 if (!ltime->neg && ltime->hour < 24)
1607 ldate->hour= ltime->hour;
1608 ldate->minute= ltime->minute;
1609 ldate->second= ltime->second;
1616 long days, useconds;
1617 int sign= ltime->neg ? 1 : -1;
1618 ldate->neg= calc_time_diff(ldate, ltime, sign, &seconds, &useconds);
1619 DBUG_ASSERT(!ldate->neg);
1626 DBUG_ASSERT(ldate->year > 0);
1628 days= (long) (seconds / SECONDS_IN_24H);
1629 calc_time_from_sec(ldate, seconds % SECONDS_IN_24H, useconds);
1630 get_date_from_daynr(days, &ldate->year, &ldate->month, &ldate->day);
1632 ldate->time_type= MYSQL_TIMESTAMP_DATETIME;
1643 longlong TIME_to_longlong_packed(
const MYSQL_TIME *ltime,
1644 enum enum_field_types type)
1648 case MYSQL_TYPE_TIME:
1649 return TIME_to_longlong_time_packed(ltime);
1650 case MYSQL_TYPE_DATETIME:
1651 case MYSQL_TYPE_TIMESTAMP:
1652 return TIME_to_longlong_datetime_packed(ltime);
1653 case MYSQL_TYPE_DATE:
1654 return TIME_to_longlong_date_packed(ltime);
1656 return TIME_to_longlong_packed(ltime);
1668 void TIME_from_longlong_packed(
MYSQL_TIME *ltime,
1669 enum enum_field_types type,
1670 longlong packed_value)
1674 case MYSQL_TYPE_TIME:
1675 TIME_from_longlong_time_packed(ltime, packed_value);
1677 case MYSQL_TYPE_DATE:
1678 TIME_from_longlong_date_packed(ltime, packed_value);
1680 case MYSQL_TYPE_DATETIME:
1681 case MYSQL_TYPE_TIMESTAMP:
1682 TIME_from_longlong_datetime_packed(ltime, packed_value);
1686 set_zero_time(ltime, MYSQL_TIMESTAMP_ERROR);
1703 enum enum_field_types type,
1704 longlong packed_value)
1709 case MYSQL_TYPE_TIME:
1710 TIME_from_longlong_time_packed(<ime, packed_value);
1711 return time2my_decimal(<ime, dec);
1712 case MYSQL_TYPE_DATE:
1713 TIME_from_longlong_date_packed(<ime, packed_value);
1714 ulonglong2decimal(TIME_to_ulonglong_date(<ime), dec);
1716 case MYSQL_TYPE_DATETIME:
1717 case MYSQL_TYPE_TIMESTAMP:
1718 TIME_from_longlong_datetime_packed(<ime, packed_value);
1719 return date2my_decimal(<ime, dec);
1722 ulonglong2decimal(0, dec);
1736 longlong longlong_from_datetime_packed(
enum enum_field_types type,
1737 longlong packed_value)
1742 case MYSQL_TYPE_TIME:
1743 TIME_from_longlong_time_packed(<ime, packed_value);
1744 return TIME_to_ulonglong_time(<ime);
1745 case MYSQL_TYPE_DATE:
1746 TIME_from_longlong_date_packed(<ime, packed_value);
1747 return TIME_to_ulonglong_date(<ime);
1748 case MYSQL_TYPE_DATETIME:
1749 case MYSQL_TYPE_TIMESTAMP:
1750 TIME_from_longlong_datetime_packed(<ime, packed_value);
1751 return TIME_to_ulonglong_datetime(<ime);
1768 double double_from_datetime_packed(
enum enum_field_types type,
1769 longlong packed_value)
1771 longlong result= longlong_from_datetime_packed(type, packed_value);
1773 ((double) MY_PACKED_TIME_GET_FRAC_PART(packed_value)) / 1000000;