95
95
next week is week 1.
98
uint32_t calc_week(DRIZZLE_TIME *l_time, uint32_t week_behaviour, uint32_t *year)
98
uint calc_week(MYSQL_TIME *l_time, uint week_behaviour, uint *year)
101
101
ulong daynr=calc_daynr(l_time->year,l_time->month,l_time->day);
102
102
ulong first_daynr=calc_daynr(l_time->year,1,1);
103
103
bool monday_first= test(week_behaviour & WEEK_MONDAY_FIRST);
104
104
bool week_year= test(week_behaviour & WEEK_YEAR);
105
105
bool first_weekday= test(week_behaviour & WEEK_FIRST_WEEKDAY);
107
uint32_t weekday=calc_weekday(first_daynr, !monday_first);
107
uint weekday=calc_weekday(first_daynr, !monday_first);
108
108
*year=l_time->year;
110
110
if (l_time->month == 1 && l_time->day <= 7-weekday)
138
138
/* Change a daynr to year, month and day */
139
139
/* Daynr 0 is returned as date 00.00.00 */
141
void get_date_from_daynr(long daynr,uint32_t *ret_year,uint32_t *ret_month,
141
void get_date_from_daynr(long daynr,uint *ret_year,uint *ret_month,
144
uint32_t year,temp,leap_day,day_of_year,days_in_year;
145
unsigned char *month_pos;
144
uint year,temp,leap_day,day_of_year,days_in_year;
147
147
if (daynr <= 365L || daynr >= 3652500)
148
148
{ /* Fix if wrong daynr */
212
Convert a timestamp string to a DRIZZLE_TIME value and produce a warning
212
Convert a timestamp string to a MYSQL_TIME value and produce a warning
213
213
if string was truncated during conversion.
216
216
See description of str_to_datetime() for more information.
219
enum enum_drizzle_timestamp_type
220
str_to_datetime_with_warn(const char *str, uint32_t length, DRIZZLE_TIME *l_time,
220
str_to_datetime_with_warn(const char *str, uint length, MYSQL_TIME *l_time,
224
224
THD *thd= current_thd;
225
enum enum_drizzle_timestamp_type ts_type;
225
timestamp_type ts_type;
227
227
ts_type= str_to_datetime(str, length, l_time,
228
228
(flags | (thd->variables.sql_mode &
229
229
(MODE_INVALID_DATES |
230
230
MODE_NO_ZERO_DATE))),
232
if (was_cut || ts_type <= DRIZZLE_TIMESTAMP_ERROR)
233
make_truncated_value_warning(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
234
str, length, ts_type, NULL);
232
if (was_cut || ts_type <= MYSQL_TIMESTAMP_ERROR)
233
make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
234
str, length, ts_type, NullS);
240
Convert a datetime from broken-down DRIZZLE_TIME representation to corresponding
240
Convert a datetime from broken-down MYSQL_TIME representation to corresponding
275
Convert a time string to a DRIZZLE_TIME struct and produce a warning
275
Convert a time string to a MYSQL_TIME struct and produce a warning
276
276
if string was cut during conversion.
279
279
See str_to_time() for more info.
282
str_to_time_with_warn(const char *str, uint32_t length, DRIZZLE_TIME *l_time)
282
str_to_time_with_warn(const char *str, uint length, MYSQL_TIME *l_time)
285
285
bool ret_val= str_to_time(str, length, l_time, &warning);
286
286
if (ret_val || warning)
287
make_truncated_value_warning(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
288
str, length, DRIZZLE_TIMESTAMP_TIME, NULL);
287
make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
288
str, length, MYSQL_TIMESTAMP_TIME, NullS);
306
306
to->second= (int) from->tm_sec;
309
void calc_time_from_sec(DRIZZLE_TIME *to, long seconds, long microseconds)
309
void calc_time_from_sec(MYSQL_TIME *to, long seconds, long microseconds)
312
312
// to->neg is not cleared, it may already be set to a useful value
313
to->time_type= DRIZZLE_TIMESTAMP_TIME;
313
to->time_type= MYSQL_TIMESTAMP_TIME;
351
bool parse_date_time_format(enum enum_drizzle_timestamp_type format_type,
352
const char *format, uint32_t format_length,
351
bool parse_date_time_format(timestamp_type format_type,
352
const char *format, uint format_length,
353
353
DATE_TIME_FORMAT *date_time_format)
355
uint32_t offset= 0, separators= 0;
355
uint offset= 0, separators= 0;
356
356
const char *ptr= format, *format_str;
357
357
const char *end= ptr+format_length;
358
unsigned char *dt_pos= date_time_format->positions;
358
uchar *dt_pos= date_time_format->positions;
359
359
/* need_p is set if we are using AM/PM format */
360
360
bool need_p= 0, allow_separator= 0;
361
uint32_t part_map= 0, separator_map= 0;
361
ulong part_map= 0, separator_map= 0;
362
362
const char *parts[16];
364
364
date_time_format->time_separator= 0;
443
443
allow_separator= 0; // Don't allow two separators
445
445
/* Store in separator_map which parts are punct characters */
446
if (my_ispunct(&my_charset_utf8_general_ci, *ptr))
446
if (my_ispunct(&my_charset_latin1, *ptr))
447
447
separator_map|= (ulong) 1 << (offset-1);
448
else if (!my_isspace(&my_charset_utf8_general_ci, *ptr))
448
else if (!my_isspace(&my_charset_latin1, *ptr))
466
466
The last test is to ensure that %p is used if and only if
469
if ((format_type == DRIZZLE_TIMESTAMP_DATETIME &&
470
!test_all_bits(part_map, (uint32_t) (1 | 2 | 4 | 8 | 16 | 32))) ||
471
(format_type == DRIZZLE_TIMESTAMP_DATE && part_map != (1 | 2 | 4)) ||
472
(format_type == DRIZZLE_TIMESTAMP_TIME &&
473
!test_all_bits(part_map, (uint32_t) (8 | 16 | 32))) ||
469
if ((format_type == MYSQL_TIMESTAMP_DATETIME &&
470
!test_all_bits(part_map, (1 | 2 | 4 | 8 | 16 | 32))) ||
471
(format_type == MYSQL_TIMESTAMP_DATE && part_map != (1 | 2 | 4)) ||
472
(format_type == MYSQL_TIMESTAMP_TIME &&
473
!test_all_bits(part_map, 8 | 16 | 32)) ||
474
474
!allow_separator || // %option should be last
475
475
(need_p && dt_pos[6] +1 != dt_pos[7]) ||
476
476
(need_p ^ (dt_pos[7] != 255)))
526
526
if (format_length == 6 && !need_p &&
527
527
!my_strnncoll(&my_charset_bin,
528
(const unsigned char *) format, 6,
529
(const unsigned char *) format_str, 6))
528
(const uchar *) format, 6,
529
(const uchar *) format_str, 6))
531
531
if (separator_map == (1 | 2))
533
if (format_type == DRIZZLE_TIMESTAMP_TIME)
533
if (format_type == MYSQL_TIMESTAMP_TIME)
535
535
if (*(format+2) != *(format+5))
549
549
if ((format_length == 12 && !need_p &&
550
550
!my_strnncoll(&my_charset_bin,
551
(const unsigned char *) format, 12,
552
(const unsigned char*) known_date_time_formats[INTERNAL_FORMAT].datetime_format,
551
(const uchar *) format, 12,
552
(const uchar*) known_date_time_formats[INTERNAL_FORMAT].datetime_format,
554
554
(separators == 5 && separator_map == (1 | 2 | 8 | 16)))
627
627
/* Put format string after current pos */
628
628
new_format->format.str= (char*) (new_format+1);
629
memcpy(new_format->positions, format->positions,
629
memcpy((char*) new_format->positions, (char*) format->positions,
630
630
sizeof(format->positions));
631
631
new_format->time_separator= format->time_separator;
632
632
/* We make the string null terminated for easy printf in SHOW VARIABLES */
633
memcpy(new_format->format.str, format->format.str,
633
memcpy((char*) new_format->format.str, format->format.str,
634
634
format->format.length);
635
635
new_format->format.str[format->format.length]= 0;
636
636
new_format->format.length= format->format.length;
658
658
const char *get_date_time_format_str(KNOWN_DATE_TIME_FORMAT *format,
659
enum enum_drizzle_timestamp_type type)
662
case DRIZZLE_TIMESTAMP_DATE:
662
case MYSQL_TIMESTAMP_DATE:
663
663
return format->date_format;
664
case DRIZZLE_TIMESTAMP_DATETIME:
664
case MYSQL_TIMESTAMP_DATETIME:
665
665
return format->datetime_format;
666
case DRIZZLE_TIMESTAMP_TIME:
666
case MYSQL_TIMESTAMP_TIME:
667
667
return format->time_format;
669
669
assert(0); // Impossible
679
679
MySQL doesn't support comparing of date/time/datetime strings that
680
680
are not in arbutary order as dates are compared as strings in some
682
This functions don't check that given DRIZZLE_TIME structure members are
682
This functions don't check that given MYSQL_TIME structure members are
683
683
in valid range. If they are not, return value won't reflect any
684
684
valid date either. Additionally, make_time doesn't take into
685
685
account time->day member: it's assumed that days have been converted
687
687
****************************************************************************/
689
689
void make_time(const DATE_TIME_FORMAT *format __attribute__((unused)),
690
const DRIZZLE_TIME *l_time, String *str)
690
const MYSQL_TIME *l_time, String *str)
692
uint32_t length= (uint) my_time_to_str(l_time, (char*) str->ptr());
692
uint length= (uint) my_time_to_str(l_time, (char*) str->ptr());
693
693
str->length(length);
694
694
str->set_charset(&my_charset_bin);
698
698
void make_date(const DATE_TIME_FORMAT *format __attribute__((unused)),
699
const DRIZZLE_TIME *l_time, String *str)
699
const MYSQL_TIME *l_time, String *str)
701
uint32_t length= (uint) my_date_to_str(l_time, (char*) str->ptr());
701
uint length= (uint) my_date_to_str(l_time, (char*) str->ptr());
702
702
str->length(length);
703
703
str->set_charset(&my_charset_bin);
707
707
void make_datetime(const DATE_TIME_FORMAT *format __attribute__((unused)),
708
const DRIZZLE_TIME *l_time, String *str)
708
const MYSQL_TIME *l_time, String *str)
710
uint32_t length= (uint) my_datetime_to_str(l_time, (char*) str->ptr());
710
uint length= (uint) my_datetime_to_str(l_time, (char*) str->ptr());
711
711
str->length(length);
712
712
str->set_charset(&my_charset_bin);
716
void make_truncated_value_warning(THD *thd, DRIZZLE_ERROR::enum_warning_level level,
716
void make_truncated_value_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
717
717
const char *str_val,
719
enum enum_drizzle_timestamp_type time_type,
718
uint str_length, timestamp_type time_type,
720
719
const char *field_name)
722
char warn_buff[DRIZZLE_ERRMSG_SIZE];
721
char warn_buff[MYSQL_ERRMSG_SIZE];
723
722
const char *type_str;
724
CHARSET_INFO *cs= &my_charset_utf8_general_ci;
723
CHARSET_INFO *cs= &my_charset_latin1;
726
String str(buff,(uint32_t) sizeof(buff), system_charset_info);
725
String str(buff,(uint32) sizeof(buff), system_charset_info);
727
726
str.copy(str_val, str_length, system_charset_info);
728
727
str[str_length]= 0; // Ensure we have end 0 for snprintf
730
729
switch (time_type) {
731
case DRIZZLE_TIMESTAMP_DATE:
730
case MYSQL_TIMESTAMP_DATE:
732
731
type_str= "date";
734
case DRIZZLE_TIMESTAMP_TIME:
733
case MYSQL_TIMESTAMP_TIME:
735
734
type_str= "time";
737
case DRIZZLE_TIMESTAMP_DATETIME: // FALLTHROUGH
736
case MYSQL_TIMESTAMP_DATETIME: // FALLTHROUGH
739
738
type_str= "datetime";
786
785
case INTERVAL_DAY_HOUR:
788
787
int64_t sec, days, daynr, microseconds, extra_sec;
789
ltime->time_type= DRIZZLE_TIMESTAMP_DATETIME; // Return full date
788
ltime->time_type= MYSQL_TIMESTAMP_DATETIME; // Return full date
790
789
microseconds= ltime->second_part + sign*interval.second_part;
791
790
extra_sec= microseconds/1000000L;
792
791
microseconds= microseconds%1000000L;
794
793
sec=((ltime->day-1)*3600*24L+ltime->hour*3600+ltime->minute*60+
796
795
sign* (int64_t) (interval.day*3600*24L +
797
interval.hour*3600L+interval.minute*60L+
796
interval.hour*3600LL+interval.minute*60LL+
798
797
interval.second))+ extra_sec;
799
798
if (microseconds < 0)
801
microseconds+= 1000000L;
800
microseconds+= 1000000LL;
804
days= sec/(3600*24L);
803
days= sec/(3600*24LL);
804
sec-= days*3600*24LL;
811
810
ltime->second_part= (uint) microseconds;
812
811
ltime->second= (uint) (sec % 60);
905
904
int64_t microseconds;
908
We suppose that if first argument is DRIZZLE_TIMESTAMP_TIME
907
We suppose that if first argument is MYSQL_TIMESTAMP_TIME
909
908
the second argument should be TIMESTAMP_TIME also.
910
909
We should check it before calc_time_diff call.
912
if (l_time1->time_type == DRIZZLE_TIMESTAMP_TIME) // Time value
911
if (l_time1->time_type == MYSQL_TIMESTAMP_TIME) // Time value
913
912
days= (long)l_time1->day - l_sign * (long)l_time2->day;
916
915
days= calc_daynr((uint) l_time1->year,
917
916
(uint) l_time1->month,
918
917
(uint) l_time1->day);
919
if (l_time2->time_type == DRIZZLE_TIMESTAMP_TIME)
918
if (l_time2->time_type == MYSQL_TIMESTAMP_TIME)
920
919
days-= l_sign * (long)l_time2->day;
922
921
days-= l_sign*calc_daynr((uint) l_time2->year,
924
923
(uint) l_time2->day);
927
microseconds= ((int64_t)days*86400L +
926
microseconds= ((int64_t)days*86400LL +
928
927
(int64_t)(l_time1->hour*3600L +
929
928
l_time1->minute*60L +
930
929
l_time1->second) -
931
930
l_sign*(int64_t)(l_time2->hour*3600L +
932
931
l_time2->minute*60L +
933
l_time2->second)) * 1000000L +
932
l_time2->second)) * 1000000LL +
934
933
(int64_t)l_time1->second_part -
935
934
l_sign*(int64_t)l_time2->second_part;
968
my_time_compare(DRIZZLE_TIME *a, DRIZZLE_TIME *b)
967
my_time_compare(MYSQL_TIME *a, MYSQL_TIME *b)
970
uint64_t a_t= TIME_to_uint64_t_datetime(a);
971
uint64_t b_t= TIME_to_uint64_t_datetime(b);
969
my_uint64_t a_t= TIME_to_uint64_t_datetime(a);
970
my_uint64_t b_t= TIME_to_uint64_t_datetime(b);