!3586 to_date函数支持秒单位后使用小数点
Merge pull request !3586 from zhangzhixian/to_date_compat
This commit is contained in:
@ -5131,6 +5131,7 @@ struct pg_tm* GetDateDetail(const char* dateString)
|
||||
|
||||
strLength = strlen(dateString);
|
||||
|
||||
int decimalPointIndex = -1;
|
||||
for (i = 0; i < strLength; i++) {
|
||||
if (' ' == dateString[i]) {
|
||||
if (spaceCount >= 5) {
|
||||
@ -5139,12 +5140,24 @@ struct pg_tm* GetDateDetail(const char* dateString)
|
||||
}
|
||||
spacePosition[spaceCount] = i;
|
||||
spaceCount++;
|
||||
} else if ('.' == dateString[i]) {
|
||||
if (decimalPointIndex != -1) {
|
||||
pfree(tm);
|
||||
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("the format is not correct")));
|
||||
}
|
||||
decimalPointIndex = i;
|
||||
}
|
||||
}
|
||||
/* there is no space in the date-string*/
|
||||
if (0 == spaceCount) {
|
||||
/* assume that the string is this kind of fommat like "19900304123045"*/
|
||||
if (DATE_WITHOUT_SPC_LEN == strLength) {
|
||||
/*
|
||||
* assume that the string is this kind of fommat like "19900304123045",
|
||||
* or like "19900304123045.345" with decimal format of second
|
||||
*/
|
||||
#define DECIMAL_POINT_INDEX_IN_NO_SPACE_INPUT 14
|
||||
if ((DATE_WITHOUT_SPC_LEN == strLength && decimalPointIndex == -1)
|
||||
/* in condition like '19900304123045.345', make sure decimal point in position behind 'yyyymmddhhminss' */
|
||||
|| (DATE_WITHOUT_SPC_LEN < strLength && decimalPointIndex == DECIMAL_POINT_INDEX_IN_NO_SPACE_INPUT)) {
|
||||
SplitWholeStrWithoutSeparator(dateString, tm);
|
||||
}
|
||||
/* there is only specific date in the string but no time information in the string*/
|
||||
@ -5161,7 +5174,8 @@ struct pg_tm* GetDateDetail(const char* dateString)
|
||||
errno_t rc = strncpy_s(dateStr, DATESTR_LEN, dateString, spacePosition[0]);
|
||||
securec_check(rc, "\0", "\0");
|
||||
/* get the specific time*/
|
||||
rc = strncpy_s(timeStr, TIMESTR_LEN, dateString + spacePosition[0] + 1, strLength - spacePosition[0]);
|
||||
int count = strLength - spacePosition[0] <= TIMESTR_LEN ? strLength - spacePosition[0] : TIMESTR_LEN - 1;
|
||||
rc = strncpy_s(timeStr, TIMESTR_LEN, dateString + spacePosition[0] + 1, count);
|
||||
securec_check(rc, "\0", "\0");
|
||||
|
||||
AnalyseDate(dateStr, tm);
|
||||
@ -5201,7 +5215,8 @@ void SplitWholeStrWithoutSeparator(const char* dateString, struct pg_tm* tm)
|
||||
strLength = strlen(dateString);
|
||||
|
||||
for (i = 0; i < strLength; i++) {
|
||||
if (dateString[i] < '0' || dateString[i] > '9') {
|
||||
/* '.' will not count as nonDigit since we are now compatible with input format "19900304123045.345" */
|
||||
if ((dateString[i] < '0' || dateString[i] > '9') && dateString[i] != '.') {
|
||||
nonDigitCount++;
|
||||
}
|
||||
}
|
||||
@ -5222,7 +5237,9 @@ void SplitWholeStrWithoutSeparator(const char* dateString, struct pg_tm* tm)
|
||||
rc = strncpy_s(minute, UNIT_LEN, dateString + FOUR_DIGIT_LEN + TWO_DIGIT_LEN * 3, TWO_DIGIT_LEN);
|
||||
securec_check(rc, "\0", "\0");
|
||||
/* get second*/
|
||||
rc = strncpy_s(second, UNIT_LEN, dateString + FOUR_DIGIT_LEN + TWO_DIGIT_LEN * 4, TWO_DIGIT_LEN);
|
||||
int secondLength = (int)strlen(dateString + FOUR_DIGIT_LEN + TWO_DIGIT_LEN * 4);
|
||||
int count = UNIT_LEN <= secondLength ? UNIT_LEN - 1 : secondLength;
|
||||
rc = strncpy_s(second, UNIT_LEN, dateString + FOUR_DIGIT_LEN + TWO_DIGIT_LEN * 4, count);
|
||||
securec_check(rc, "\0", "\0");
|
||||
|
||||
tm->tm_year = atoi(year);
|
||||
@ -5230,7 +5247,7 @@ void SplitWholeStrWithoutSeparator(const char* dateString, struct pg_tm* tm)
|
||||
tm->tm_mday = atoi(day);
|
||||
tm->tm_hour = atoi(hour);
|
||||
tm->tm_min = atoi(minute);
|
||||
tm->tm_sec = atoi(second);
|
||||
tm->tm_sec = (int)round(atof(second));
|
||||
} else {
|
||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("the format is not correct")));
|
||||
}
|
||||
@ -5356,6 +5373,7 @@ void AnalyseTime(const char* timeString, struct pg_tm* tm_time)
|
||||
int i;
|
||||
|
||||
int timeSeparatorCount = 0;
|
||||
int decimalPointCount = 0;
|
||||
int timeSeparatorPosition[5] = {0};
|
||||
|
||||
if (NULL == timeString || NULL == tm_time) {
|
||||
@ -5364,7 +5382,12 @@ void AnalyseTime(const char* timeString, struct pg_tm* tm_time)
|
||||
}
|
||||
strLength = strlen(timeString);
|
||||
for (i = 0; i < strLength; i++) {
|
||||
if (timeString[i] < '0' || timeString[i] > '9') {
|
||||
if (timeString[i] == '.') {
|
||||
decimalPointCount++;
|
||||
if (decimalPointCount > 1) {
|
||||
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("the format is not correct")));
|
||||
}
|
||||
} else if (timeString[i] < '0' || timeString[i] > '9') {
|
||||
timeSeparatorPosition[timeSeparatorCount] = i;
|
||||
timeSeparatorCount++;
|
||||
if (timeSeparatorCount > 5) {
|
||||
@ -5428,13 +5451,9 @@ void SplitTimestrBySeparator(const char* timeString, int strLength, const int* s
|
||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("the format is not correct")));
|
||||
return;
|
||||
}
|
||||
if (MINLEN_TIME > strLength || MAXLEN_TIME < strLength) {
|
||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("the time is not correct!")));
|
||||
}
|
||||
/* check the position of the oparator .1 and 2 are the posiible position of the first separator*/
|
||||
else if (1 != separatorPosition[0] && 2 != separatorPosition[0]) {
|
||||
if (1 != separatorPosition[0] && 2 != separatorPosition[0]) {
|
||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("the hour is invalid!")));
|
||||
|
||||
}
|
||||
/* 3 ,4 and 5 are the posiible position of the second separator*/
|
||||
else if (3 != separatorPosition[1] && 4 != separatorPosition[1] && 5 != separatorPosition[1]) {
|
||||
@ -5452,13 +5471,13 @@ void SplitTimestrBySeparator(const char* timeString, int strLength, const int* s
|
||||
errorno = strncpy_s(second,
|
||||
strLength - separatorPosition[1],
|
||||
timeString + separatorPosition[1] + 1,
|
||||
strLength - separatorPosition[1] - 1);
|
||||
strLength - separatorPosition[1] - 1 < UNIT_LEN ? strLength - separatorPosition[1] - 1 : UNIT_LEN);
|
||||
securec_check(errorno, "\0", "\0");
|
||||
|
||||
/* transfer char to int*/
|
||||
tm_time->tm_hour = atoi(hour);
|
||||
tm_time->tm_min = atoi(minute);
|
||||
tm_time->tm_sec = atoi(second);
|
||||
tm_time->tm_sec = (int)round(atof(second));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1038,3 +1038,51 @@ CONTEXT: referenced column: to_timestamp
|
||||
SELECT to_timestamp(-999888762478);
|
||||
ERROR: timestamp out of range: "-9.99889e+11"
|
||||
CONTEXT: referenced column: to_timestamp
|
||||
SELECT to_date('1992-01-01 12:34:56');
|
||||
to_date
|
||||
---------------------
|
||||
1992-01-01 12:34:56
|
||||
(1 row)
|
||||
|
||||
SELECT to_date('1992-01-01 12:34:56.545612164556');
|
||||
to_date
|
||||
---------------------
|
||||
1992-01-01 12:34:57
|
||||
(1 row)
|
||||
|
||||
SELECT to_date('1992-01-01 12:34:56.499999999999');
|
||||
to_date
|
||||
---------------------
|
||||
1992-01-01 12:34:56
|
||||
(1 row)
|
||||
|
||||
SELECT to_date('1992-01-01 12:34:56.500000000000');
|
||||
to_date
|
||||
---------------------
|
||||
1992-01-01 12:34:57
|
||||
(1 row)
|
||||
|
||||
SELECT to_date('19920101123456');
|
||||
to_date
|
||||
---------------------
|
||||
1992-01-01 12:34:56
|
||||
(1 row)
|
||||
|
||||
SELECT to_date('19920101123456.5848954380543');
|
||||
to_date
|
||||
---------------------
|
||||
1992-01-01 12:34:57
|
||||
(1 row)
|
||||
|
||||
SELECT to_date('19920101123456.5000000000000');
|
||||
to_date
|
||||
---------------------
|
||||
1992-01-01 12:34:57
|
||||
(1 row)
|
||||
|
||||
SELECT to_date('19920101123456.4999999999999');
|
||||
to_date
|
||||
---------------------
|
||||
1992-01-01 12:34:56
|
||||
(1 row)
|
||||
|
||||
|
@ -270,3 +270,12 @@ SELECT to_timestamp(' Infinity'::float);
|
||||
SELECT to_timestamp('-Infinity'::float);
|
||||
SELECT to_timestamp('NaN'::float);
|
||||
SELECT to_timestamp(-999888762478);
|
||||
|
||||
SELECT to_date('1992-01-01 12:34:56');
|
||||
SELECT to_date('1992-01-01 12:34:56.545612164556');
|
||||
SELECT to_date('1992-01-01 12:34:56.499999999999');
|
||||
SELECT to_date('1992-01-01 12:34:56.500000000000');
|
||||
SELECT to_date('19920101123456');
|
||||
SELECT to_date('19920101123456.5848954380543');
|
||||
SELECT to_date('19920101123456.5000000000000');
|
||||
SELECT to_date('19920101123456.4999999999999');
|
Reference in New Issue
Block a user