[Bug] Fix the bug of cast string to datetime return not null (#6228)
This commit is contained in:
@ -61,21 +61,19 @@ static uint32_t calc_days_in_year(uint32_t year) {
|
||||
|
||||
RE2 DateTimeValue::time_zone_offset_format_reg("^[+-]{1}\\d{2}\\:\\d{2}$");
|
||||
|
||||
bool DateTimeValue::check_range() const {
|
||||
return _year > 9999 || _month > 12 || _day > 31 ||
|
||||
_hour > (_type == TIME_TIME ? TIME_MAX_HOUR : 23) || _minute > 59 || _second > 59 ||
|
||||
_microsecond > 999999;
|
||||
bool DateTimeValue::check_range(uint32_t year, uint32_t month, uint32_t day, uint32_t hour,
|
||||
uint32_t minute, uint32_t second, uint32_t microsecond, uint16_t type) {
|
||||
bool time = hour > (type == TIME_TIME ? TIME_MAX_HOUR : 23) || minute > 59 || second > 59 ||
|
||||
microsecond > 999999;
|
||||
return time || check_date(year, month, day);
|
||||
}
|
||||
|
||||
bool DateTimeValue::check_date() const {
|
||||
if (_month != 0 && _day > s_days_in_month[_month]) {
|
||||
bool DateTimeValue::check_date(uint32_t year, uint32_t month, uint32_t day) {
|
||||
if (month != 0 && month <= 12 && day > s_days_in_month[month]) {
|
||||
// Feb 29 in leap year is valid.
|
||||
if (_month == 2 && _day == 29 && is_leap(_year)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
if (!(month == 2 && day == 29 && is_leap(year))) return true;
|
||||
}
|
||||
return false;
|
||||
return year > 9999 || month > 12 || day > 31;
|
||||
}
|
||||
|
||||
// The interval format is that with no delimiters
|
||||
@ -182,30 +180,21 @@ bool DateTimeValue::from_date_str(const char* date_str, int len) {
|
||||
date_len[field_idx] = 0;
|
||||
date_val[field_idx] = 0;
|
||||
}
|
||||
_year = date_val[0];
|
||||
_month = date_val[1];
|
||||
_day = date_val[2];
|
||||
_hour = date_val[3];
|
||||
_minute = date_val[4];
|
||||
_second = date_val[5];
|
||||
_microsecond = date_val[6];
|
||||
if (_microsecond && date_len[6] < 6) {
|
||||
_microsecond *= log_10_int[6 - date_len[6]];
|
||||
|
||||
if (date_val[6] && date_len[6] < 6) {
|
||||
date_val[6] *= log_10_int[6 - date_len[6]];
|
||||
}
|
||||
if (year_len == 2) {
|
||||
if (_year < YY_PART_YEAR) {
|
||||
_year += 2000;
|
||||
if (date_val[0] < YY_PART_YEAR) {
|
||||
date_val[0] += 2000;
|
||||
} else {
|
||||
_year += 1900;
|
||||
date_val[0] += 1900;
|
||||
}
|
||||
}
|
||||
if (num_field < 3 || check_range()) {
|
||||
return false;
|
||||
}
|
||||
if (check_date()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
if (num_field < 3) return false;
|
||||
return check_range_and_set_time(date_val[0], date_val[1], date_val[2],
|
||||
date_val[3], date_val[4], date_val[5], date_val[6], _type);
|
||||
}
|
||||
|
||||
// [0, 101) invalid
|
||||
@ -289,20 +278,18 @@ bool DateTimeValue::from_date_int64(int64_t value) {
|
||||
uint64_t date = value / 1000000;
|
||||
uint64_t time = value % 1000000;
|
||||
|
||||
_year = date / 10000;
|
||||
auto [year, month, day, hour, minute, second, microsecond] = std::tuple{0,0,0,0,0,0,0};
|
||||
year = date / 10000;
|
||||
date %= 10000;
|
||||
_month = date / 100;
|
||||
_day = date % 100;
|
||||
_hour = time / 10000;
|
||||
month = date / 100;
|
||||
day = date % 100;
|
||||
hour = time / 10000;
|
||||
time %= 10000;
|
||||
_minute = time / 100;
|
||||
_second = time % 100;
|
||||
_microsecond = 0;
|
||||
minute = time / 100;
|
||||
second = time % 100;
|
||||
microsecond = 0;
|
||||
|
||||
if (check_range() || check_date()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return check_range_and_set_time(year, month, day, hour, minute, second, microsecond, _type);
|
||||
}
|
||||
|
||||
void DateTimeValue::set_zero(int type) {
|
||||
@ -478,14 +465,16 @@ bool DateTimeValue::get_date_from_daynr(uint64_t daynr) {
|
||||
if (daynr <= 0 || daynr > DATE_MAX_DAYNR) {
|
||||
return false;
|
||||
}
|
||||
_year = daynr / 365;
|
||||
|
||||
auto [year, month, day] = std::tuple{0, 0, 0};
|
||||
year = daynr / 365;
|
||||
uint32_t days_befor_year = 0;
|
||||
while (daynr < (days_befor_year = calc_daynr(_year, 1, 1))) {
|
||||
_year--;
|
||||
while (daynr < (days_befor_year = calc_daynr(year, 1, 1))) {
|
||||
year--;
|
||||
}
|
||||
uint32_t days_of_year = daynr - days_befor_year + 1;
|
||||
int leap_day = 0;
|
||||
if (is_leap(_year)) {
|
||||
if (is_leap(year)) {
|
||||
if (days_of_year > 31 + 28) {
|
||||
days_of_year--;
|
||||
if (days_of_year == 31 + 28) {
|
||||
@ -493,12 +482,17 @@ bool DateTimeValue::get_date_from_daynr(uint64_t daynr) {
|
||||
}
|
||||
}
|
||||
}
|
||||
_month = 1;
|
||||
while (days_of_year > s_days_in_month[_month]) {
|
||||
days_of_year -= s_days_in_month[_month];
|
||||
_month++;
|
||||
month = 1;
|
||||
while (days_of_year > s_days_in_month[month]) {
|
||||
days_of_year -= s_days_in_month[month];
|
||||
month++;
|
||||
}
|
||||
_day = days_of_year + leap_day;
|
||||
day = days_of_year + leap_day;
|
||||
|
||||
if (check_range(year, month, day, 0, 0, 0, 0, _type)) {
|
||||
return false;
|
||||
}
|
||||
set_time(year, month, day, _hour, _minute, _second, _microsecond);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1091,6 +1085,7 @@ bool DateTimeValue::from_date_format_str(const char* format, int format_len, con
|
||||
bool date_part_used = false;
|
||||
bool time_part_used = false;
|
||||
bool frac_part_used = false;
|
||||
bool already_set_time_part = false;
|
||||
|
||||
int day_part = 0;
|
||||
int weekday = -1;
|
||||
@ -1103,6 +1098,7 @@ bool DateTimeValue::from_date_format_str(const char* format, int format_len, con
|
||||
int strict_week_number_year = -1;
|
||||
bool usa_time = false;
|
||||
|
||||
auto [year, month, day, hour, minute, second, microsecond] = std::tuple{0,0,0,0,0,0,0};
|
||||
while (ptr < end && val < val_end) {
|
||||
// Skip space character
|
||||
while (val < val_end && isspace(*val)) {
|
||||
@ -1125,7 +1121,7 @@ bool DateTimeValue::from_date_format_str(const char* format, int format_len, con
|
||||
return false;
|
||||
}
|
||||
int_value += int_value >= 70 ? 1900 : 2000;
|
||||
_year = int_value;
|
||||
year = int_value;
|
||||
val = tmp;
|
||||
date_part_used = true;
|
||||
break;
|
||||
@ -1138,7 +1134,7 @@ bool DateTimeValue::from_date_format_str(const char* format, int format_len, con
|
||||
if (tmp - val <= 2) {
|
||||
int_value += int_value >= 70 ? 1900 : 2000;
|
||||
}
|
||||
_year = int_value;
|
||||
year = int_value;
|
||||
val = tmp;
|
||||
date_part_used = true;
|
||||
break;
|
||||
@ -1149,7 +1145,7 @@ bool DateTimeValue::from_date_format_str(const char* format, int format_len, con
|
||||
if (!str_to_int64(val, &tmp, &int_value)) {
|
||||
return false;
|
||||
}
|
||||
_month = int_value;
|
||||
month = int_value;
|
||||
val = tmp;
|
||||
date_part_used = true;
|
||||
break;
|
||||
@ -1158,14 +1154,14 @@ bool DateTimeValue::from_date_format_str(const char* format, int format_len, con
|
||||
if (int_value < 0) {
|
||||
return false;
|
||||
}
|
||||
_month = int_value;
|
||||
month = int_value;
|
||||
break;
|
||||
case 'b':
|
||||
int_value = check_word(s_ab_month_name, val, val_end, &val);
|
||||
if (int_value < 0) {
|
||||
return false;
|
||||
}
|
||||
_month = int_value;
|
||||
month = int_value;
|
||||
break;
|
||||
// Day
|
||||
case 'd':
|
||||
@ -1174,7 +1170,7 @@ bool DateTimeValue::from_date_format_str(const char* format, int format_len, con
|
||||
if (!str_to_int64(val, &tmp, &int_value)) {
|
||||
return false;
|
||||
}
|
||||
_day = int_value;
|
||||
day = int_value;
|
||||
val = tmp;
|
||||
date_part_used = true;
|
||||
break;
|
||||
@ -1183,7 +1179,7 @@ bool DateTimeValue::from_date_format_str(const char* format, int format_len, con
|
||||
if (!str_to_int64(val, &tmp, &int_value)) {
|
||||
return false;
|
||||
}
|
||||
_day = int_value;
|
||||
day = int_value;
|
||||
val = tmp + min(2, val_end - tmp);
|
||||
date_part_used = true;
|
||||
break;
|
||||
@ -1199,7 +1195,7 @@ bool DateTimeValue::from_date_format_str(const char* format, int format_len, con
|
||||
if (!str_to_int64(val, &tmp, &int_value)) {
|
||||
return false;
|
||||
}
|
||||
_hour = int_value;
|
||||
hour = int_value;
|
||||
val = tmp;
|
||||
time_part_used = true;
|
||||
break;
|
||||
@ -1209,7 +1205,7 @@ bool DateTimeValue::from_date_format_str(const char* format, int format_len, con
|
||||
if (!str_to_int64(val, &tmp, &int_value)) {
|
||||
return false;
|
||||
}
|
||||
_minute = int_value;
|
||||
minute = int_value;
|
||||
val = tmp;
|
||||
time_part_used = true;
|
||||
break;
|
||||
@ -1220,7 +1216,7 @@ bool DateTimeValue::from_date_format_str(const char* format, int format_len, con
|
||||
if (!str_to_int64(val, &tmp, &int_value)) {
|
||||
return false;
|
||||
}
|
||||
_second = int_value;
|
||||
second = int_value;
|
||||
val = tmp;
|
||||
time_part_used = true;
|
||||
break;
|
||||
@ -1231,7 +1227,7 @@ bool DateTimeValue::from_date_format_str(const char* format, int format_len, con
|
||||
return false;
|
||||
}
|
||||
int_value *= log_10_int[6 - (tmp - val)];
|
||||
_microsecond = int_value;
|
||||
microsecond = int_value;
|
||||
val = tmp;
|
||||
frac_part_used = true;
|
||||
break;
|
||||
@ -1326,12 +1322,14 @@ bool DateTimeValue::from_date_format_str(const char* format, int format_len, con
|
||||
}
|
||||
val = tmp;
|
||||
time_part_used = true;
|
||||
already_set_time_part = true;
|
||||
break;
|
||||
case 'T':
|
||||
if (!from_date_format_str("%H:%i:%S", 8, val, val_end - val, &tmp)) {
|
||||
return false;
|
||||
}
|
||||
time_part_used = true;
|
||||
already_set_time_part = true;
|
||||
val = tmp;
|
||||
break;
|
||||
case '.':
|
||||
@ -1397,18 +1395,39 @@ bool DateTimeValue::from_date_format_str(const char* format, int format_len, con
|
||||
}
|
||||
|
||||
if (usa_time) {
|
||||
if (_hour > 12 || _hour < 1) {
|
||||
if (hour > 12 || hour < 1) {
|
||||
return false;
|
||||
}
|
||||
_hour = (_hour % 12) + day_part;
|
||||
hour = (hour % 12) + day_part;
|
||||
}
|
||||
if (sub_val_end) {
|
||||
*sub_val_end = val;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Compute timestamp type
|
||||
if (frac_part_used) {
|
||||
if (date_part_used) {
|
||||
_type = TIME_DATETIME;
|
||||
} else {
|
||||
_type = TIME_TIME;
|
||||
}
|
||||
} else {
|
||||
if (date_part_used) {
|
||||
if (time_part_used) {
|
||||
_type = TIME_DATETIME;
|
||||
} else {
|
||||
_type = TIME_DATE;
|
||||
}
|
||||
} else {
|
||||
_type = TIME_TIME;
|
||||
}
|
||||
}
|
||||
|
||||
_neg = false;
|
||||
|
||||
// Year day
|
||||
if (yearday > 0) {
|
||||
uint64_t days = calc_daynr(_year, 1, 1) + yearday - 1;
|
||||
uint64_t days = calc_daynr(year, 1, 1) + yearday - 1;
|
||||
if (!get_date_from_daynr(days)) {
|
||||
return false;
|
||||
}
|
||||
@ -1434,31 +1453,17 @@ bool DateTimeValue::from_date_format_str(const char* format, int format_len, con
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// 1. already_set_date_part means _year, _month, _day be set, so we only set time part
|
||||
// 2. already_set_time_part means _hour, _minute, _second, _microsecond be set,
|
||||
// so we only neet to set date part
|
||||
// 3. if both are true, means all part of date_time be set, no need check_range_and_set_time
|
||||
bool already_set_date_part = yearday > 0 || (week_num >= 0 && weekday > 0);
|
||||
if (already_set_date_part && already_set_time_part) return true;
|
||||
if (already_set_date_part) return check_range_and_set_time(_year, _month, _day, hour, minute, second, microsecond, _type);
|
||||
if (already_set_time_part) return check_range_and_set_time(year, month, day,
|
||||
_hour, _minute, _second, _microsecond, _type);
|
||||
|
||||
// Compute timestamp type
|
||||
if (frac_part_used) {
|
||||
if (date_part_used) {
|
||||
_type = TIME_DATETIME;
|
||||
} else {
|
||||
_type = TIME_TIME;
|
||||
}
|
||||
} else {
|
||||
if (date_part_used) {
|
||||
if (time_part_used) {
|
||||
_type = TIME_DATETIME;
|
||||
} else {
|
||||
_type = TIME_DATE;
|
||||
}
|
||||
} else {
|
||||
_type = TIME_TIME;
|
||||
}
|
||||
}
|
||||
|
||||
if (check_range() || check_date()) {
|
||||
return false;
|
||||
}
|
||||
_neg = false;
|
||||
return true;
|
||||
return check_range_and_set_time(year, month, day, hour, minute, second, microsecond, _type);
|
||||
}
|
||||
|
||||
bool DateTimeValue::date_add_interval(const TimeInterval& interval, TimeUnit unit) {
|
||||
@ -1615,6 +1620,17 @@ DateTimeValue DateTimeValue::local_time() {
|
||||
return value;
|
||||
}
|
||||
|
||||
void DateTimeValue::set_time(uint32_t year, uint32_t month, uint32_t day, uint32_t hour,
|
||||
uint32_t minute, uint32_t second, uint32_t microsecond) {
|
||||
_year = year;
|
||||
_month = month;
|
||||
_day = day;
|
||||
_hour = hour;
|
||||
_minute = minute;
|
||||
_second = second;
|
||||
_microsecond = microsecond;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const DateTimeValue& value) {
|
||||
char buf[64];
|
||||
value.to_string(buf);
|
||||
|
||||
@ -155,6 +155,9 @@ public:
|
||||
|
||||
DateTimeValue(int64_t t) { from_date_int64(t); }
|
||||
|
||||
void set_time(uint32_t year, uint32_t month, uint32_t day, uint32_t hour,
|
||||
uint32_t minute, uint32_t second, uint32_t microsecond);
|
||||
|
||||
// Converted from Olap Date or Datetime
|
||||
bool from_olap_datetime(uint64_t datetime) {
|
||||
_neg = 0;
|
||||
@ -162,20 +165,18 @@ public:
|
||||
uint64_t date = datetime / 1000000;
|
||||
uint64_t time = datetime % 1000000;
|
||||
|
||||
_year = date / 10000;
|
||||
auto [year, month, day, hour, minute, second, microsecond] = std::tuple{0,0,0,0,0,0,0};
|
||||
year = date / 10000;
|
||||
date %= 10000;
|
||||
_month = date / 100;
|
||||
_day = date % 100;
|
||||
_hour = time / 10000;
|
||||
month = date / 100;
|
||||
day = date % 100;
|
||||
hour = time / 10000;
|
||||
time %= 10000;
|
||||
_minute = time / 100;
|
||||
_second = time % 100;
|
||||
_microsecond = 0;
|
||||
minute = time / 100;
|
||||
second = time % 100;
|
||||
microsecond = 0;
|
||||
|
||||
if (check_range() || check_date()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return check_range_and_set_time(year, month, day, hour, minute, second, microsecond, _type);
|
||||
}
|
||||
|
||||
uint64_t to_olap_datetime() const {
|
||||
@ -187,22 +188,16 @@ public:
|
||||
bool from_olap_date(uint64_t date) {
|
||||
_neg = 0;
|
||||
_type = TIME_DATE;
|
||||
_hour = 0;
|
||||
_minute = 0;
|
||||
_second = 0;
|
||||
_microsecond = 0;
|
||||
|
||||
_day = date & 0x1f;
|
||||
auto [year, month, day, hour, minute, second, microsecond] = std::tuple{0,0,0,0,0,0,0};
|
||||
|
||||
day = date & 0x1f;
|
||||
date >>= 5;
|
||||
|
||||
_month = date & 0x0f;
|
||||
month = date & 0x0f;
|
||||
date >>= 4;
|
||||
year = date;
|
||||
|
||||
_year = date;
|
||||
if (check_range() || check_date()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return check_range_and_set_time(year, month, day, hour, minute, second, microsecond, _type);
|
||||
}
|
||||
|
||||
uint64_t to_olap_date() const {
|
||||
@ -254,10 +249,25 @@ public:
|
||||
// compute the length of data format pattern
|
||||
static int compute_format_len(const char* format, int len);
|
||||
|
||||
// Return true if range or date is invalid
|
||||
static bool check_range(uint32_t year, uint32_t month, uint32_t day, uint32_t hour,
|
||||
uint32_t minute, uint32_t second, uint32_t microsecond, uint16_t type);
|
||||
|
||||
static bool check_date(uint32_t year, uint32_t month, uint32_t day);
|
||||
|
||||
// Convert this value to uint64_t
|
||||
// Will check its type
|
||||
int64_t to_int64() const;
|
||||
|
||||
bool check_range_and_set_time(uint32_t year, uint32_t month, uint32_t day, uint32_t hour,
|
||||
uint32_t minute, uint32_t second, uint32_t microsecond, uint16_t type) {
|
||||
if (check_range(year, month, day, hour, minute, second, microsecond, type)) {
|
||||
return false;
|
||||
}
|
||||
set_time(year, month, day, hour, minute, second, microsecond);
|
||||
return true;
|
||||
};
|
||||
|
||||
inline uint64_t daynr() const { return calc_daynr(_year, _month, _day); }
|
||||
|
||||
// Calculate how many days since 0000-01-01
|
||||
@ -272,6 +282,7 @@ public:
|
||||
int hour() const { return _hour; }
|
||||
int minute() const { return _minute; }
|
||||
int second() const { return _second; }
|
||||
int microsecond() const { return _microsecond; }
|
||||
|
||||
bool check_loss_accuracy_cast_to_date() {
|
||||
auto loss_accuracy = _hour != 0 || _minute != 0 || _second != 0 || _microsecond != 0;
|
||||
@ -455,7 +466,8 @@ public:
|
||||
|
||||
int type() const { return _type; }
|
||||
|
||||
bool is_valid_date() const { return !check_range() && !check_date() && _month > 0 && _day > 0; }
|
||||
bool is_valid_date() const { return !check_range(_year, _month, _day,
|
||||
_hour, _minute, _second, _microsecond, _type) && _month > 0 && _day > 0; }
|
||||
|
||||
private:
|
||||
// Used to make sure sizeof DateTimeValue
|
||||
@ -497,10 +509,6 @@ private:
|
||||
return _neg ? -tmp : tmp;
|
||||
}
|
||||
|
||||
// Return true if range or date is invalid
|
||||
bool check_range() const;
|
||||
bool check_date() const;
|
||||
|
||||
// Used to construct from int value
|
||||
int64_t standardize_timevalue(int64_t value);
|
||||
|
||||
|
||||
@ -388,7 +388,7 @@ TEST_F(TimestampFunctionsTest, timestampdiff_test) {
|
||||
ASSERT_DIFF(month, 0, tv2, tv1);
|
||||
ASSERT_DIFF(month, 0, tv2, tv1);
|
||||
ASSERT_DIFF(month, 0, 20120924000000, tv1);
|
||||
ASSERT_DIFF(month, 1, tv1, 20120631000000);
|
||||
ASSERT_DIFF(month, 1, tv1, 20120630000000);
|
||||
//WEEK
|
||||
ASSERT_DIFF(week, 0, tv2, tv1);
|
||||
//DAY
|
||||
|
||||
@ -191,40 +191,48 @@ TEST_F(DateTimeValueTest, local_time) {
|
||||
// Test check range
|
||||
TEST_F(DateTimeValueTest, check_range) {
|
||||
DateTimeValue value;
|
||||
value.from_date_int64(19880201123456);
|
||||
ASSERT_FALSE(value.check_range());
|
||||
ASSERT_TRUE(value.from_date_int64(19880201123456));
|
||||
|
||||
value._year = 10000;
|
||||
ASSERT_TRUE(value.check_range());
|
||||
ASSERT_TRUE(DateTimeValue::check_range(value.year(), value.month(), value.day(),
|
||||
value.hour(), value.minute(), value.second(), value.microsecond(), value.type()));
|
||||
value._year = 1988;
|
||||
|
||||
value._month = 13;
|
||||
ASSERT_TRUE(value.check_range());
|
||||
ASSERT_TRUE(DateTimeValue::check_range(value.year(), value.month(), value.day(),
|
||||
value.hour(), value.minute(), value.second(), value.microsecond(), value.type()));
|
||||
value._month = 2;
|
||||
|
||||
value._day = 32;
|
||||
ASSERT_TRUE(value.check_range());
|
||||
ASSERT_TRUE(DateTimeValue::check_range(value.year(), value.month(), value.day(),
|
||||
value.hour(), value.minute(), value.second(), value.microsecond(), value.type()));
|
||||
value._day = 1;
|
||||
|
||||
value._hour = TIME_MAX_HOUR;
|
||||
ASSERT_TRUE(value.check_range());
|
||||
ASSERT_TRUE(DateTimeValue::check_range(value.year(), value.month(), value.day(),
|
||||
value.hour(), value.minute(), value.second(), value.microsecond(), value.type()));
|
||||
value._type = TIME_TIME;
|
||||
ASSERT_FALSE(value.check_range());
|
||||
ASSERT_FALSE(DateTimeValue::check_range(value.year(), value.month(), value.day(),
|
||||
value.hour(), value.minute(), value.second(), value.microsecond(), value.type()));
|
||||
value._hour = TIME_MAX_HOUR + 1;
|
||||
ASSERT_TRUE(value.check_range());
|
||||
ASSERT_TRUE(DateTimeValue::check_range(value.year(), value.month(), value.day(),
|
||||
value.hour(), value.minute(), value.second(), value.microsecond(), value.type()));
|
||||
value._type = TIME_DATETIME;
|
||||
value._hour = 12;
|
||||
|
||||
value._minute = 60;
|
||||
ASSERT_TRUE(value.check_range());
|
||||
ASSERT_TRUE(DateTimeValue::check_range(value.year(), value.month(), value.day(),
|
||||
value.hour(), value.minute(), value.second(), value.microsecond(), value.type()));
|
||||
value._minute = 34;
|
||||
|
||||
value._second = 60;
|
||||
ASSERT_TRUE(value.check_range());
|
||||
ASSERT_TRUE(DateTimeValue::check_range(value.year(), value.month(), value.day(),
|
||||
value.hour(), value.minute(), value.second(), value.microsecond(), value.type()));
|
||||
value._second = 56;
|
||||
|
||||
value._microsecond = 1000000;
|
||||
ASSERT_TRUE(value.check_range());
|
||||
ASSERT_TRUE(DateTimeValue::check_range(value.year(), value.month(), value.day(),
|
||||
value.hour(), value.minute(), value.second(), value.microsecond(), value.type()));
|
||||
value._month = 0;
|
||||
}
|
||||
|
||||
@ -233,16 +241,20 @@ TEST_F(DateTimeValueTest, check_date) {
|
||||
ASSERT_TRUE(value.from_date_int64(19880201));
|
||||
|
||||
value._month = 0;
|
||||
ASSERT_FALSE(value.check_date());
|
||||
ASSERT_FALSE(DateTimeValue::check_range(value.year(), value.month(), value.day(),
|
||||
value.hour(), value.minute(), value.second(), value.microsecond(), value.type()));
|
||||
value._month = 2;
|
||||
|
||||
value._day = 0;
|
||||
ASSERT_FALSE(value.check_date());
|
||||
ASSERT_FALSE(DateTimeValue::check_range(value.year(), value.month(), value.day(),
|
||||
value.hour(), value.minute(), value.second(), value.microsecond(), value.type()));
|
||||
value._year = 1987;
|
||||
value._day = 29;
|
||||
ASSERT_TRUE(value.check_date());
|
||||
ASSERT_TRUE(DateTimeValue::check_range(value.year(), value.month(), value.day(),
|
||||
value.hour(), value.minute(), value.second(), value.microsecond(), value.type()));
|
||||
value._year = 2000;
|
||||
ASSERT_FALSE(value.check_date());
|
||||
ASSERT_FALSE(DateTimeValue::check_range(value.year(), value.month(), value.day(),
|
||||
value.hour(), value.minute(), value.second(), value.microsecond(), value.type()));
|
||||
}
|
||||
|
||||
// Calculate format
|
||||
|
||||
Reference in New Issue
Block a user