in src/main/java/org/mariadb/jdbc/internal/com/read/resultset/rowprotocol/TextRowProtocol.java [480:627]
public Date getInternalDate(ColumnDefinition columnInfo, Calendar cal, TimeZone timeZone)
throws SQLException {
if (lastValueWasNull()) {
return null;
}
int partIdx = 0;
switch (columnInfo.getColumnType()) {
case DATE:
int[] datePart = new int[] {0, 0, 0};
for (int begin = pos; begin < pos + length; begin++) {
byte b = buf[begin];
if (b == '-') {
partIdx++;
continue;
}
if (b < '0' || b > '9') {
throw new SQLException(
"cannot parse data in date string '"
+ new String(buf, pos, length, StandardCharsets.UTF_8)
+ "'");
}
datePart[partIdx] = datePart[partIdx] * 10 + b - 48;
}
if (datePart[0] == 0 && datePart[1] == 0 && datePart[2] == 0) {
lastValueNull |= BIT_LAST_ZERO_DATE;
return null;
}
return new Date(datePart[0] - 1900, datePart[1] - 1, datePart[2]);
case TIMESTAMP:
case DATETIME:
int nanoBegin = -1;
int[] timestampsPart = new int[] {0, 0, 0, 0, 0, 0, 0};
for (int begin = pos; begin < pos + length; begin++) {
byte b = buf[begin];
if (b == '-' || b == ' ' || b == ':') {
partIdx++;
continue;
}
if (b == '.') {
partIdx++;
nanoBegin = begin;
continue;
}
if (b < '0' || b > '9') {
throw new SQLException(
"cannot parse data in timestamp string '"
+ new String(buf, pos, length, StandardCharsets.UTF_8)
+ "'");
}
timestampsPart[partIdx] = timestampsPart[partIdx] * 10 + b - 48;
}
if (timestampsPart[0] == 0
&& timestampsPart[1] == 0
&& timestampsPart[2] == 0
&& timestampsPart[3] == 0
&& timestampsPart[4] == 0
&& timestampsPart[5] == 0
&& timestampsPart[6] == 0) {
lastValueNull |= BIT_LAST_ZERO_DATE;
return null;
}
// fix non leading tray for nanoseconds
if (nanoBegin > 0) {
for (int begin = 0; begin < 6 - (pos + length - nanoBegin - 1); begin++) {
timestampsPart[6] = timestampsPart[6] * 10;
}
}
if (timeZone == null) {
// legacy is to send timestamps with current driver timezone. So display, is immediate
Calendar calendar = (cal != null) ? cal : Calendar.getInstance();
synchronized (calendar) {
calendar.clear();
calendar.set(Calendar.YEAR, timestampsPart[0]);
calendar.set(Calendar.MONTH, timestampsPart[1] - 1);
calendar.set(Calendar.DAY_OF_MONTH, timestampsPart[2]);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return new Date(calendar.getTimeInMillis());
}
}
// timestamp is saved in server timezone,
LocalDateTime ldt =
LocalDateTime.of(
timestampsPart[0],
timestampsPart[1],
timestampsPart[2],
timestampsPart[3],
timestampsPart[4],
timestampsPart[5],
timestampsPart[6] * 1000);
ZonedDateTime zdt =
ldt.atZone(timeZone.toZoneId()).withZoneSameInstant(TimeZone.getDefault().toZoneId());
Calendar calendar = cal != null ? cal : Calendar.getInstance();
synchronized (calendar) {
calendar.clear();
calendar.set(Calendar.YEAR, zdt.getYear());
calendar.set(Calendar.MONTH, zdt.getMonthValue() - 1);
calendar.set(Calendar.DAY_OF_MONTH, zdt.getDayOfMonth());
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return new Date(calendar.getTimeInMillis());
}
case TIME:
throw new SQLException("Cannot read DATE using a Types.TIME field");
case YEAR:
int year = 0;
for (int begin = pos; begin < pos + length; begin++) {
year = year * 10 + buf[begin] - 48;
}
if (length == 2 && columnInfo.getLength() == 2) {
if (year <= 69) {
year += 2000;
} else {
year += 1900;
}
}
return new Date(year - 1900, 0, 1);
default:
try {
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
if (timeZone != null) {
sdf.setTimeZone(timeZone);
}
java.util.Date utilDate = sdf.parse(new String(buf, pos, length, StandardCharsets.UTF_8));
return new Date(utilDate.getTime());
} catch (ParseException e) {
throw ExceptionFactory.INSTANCE.create(
"Could not get object as Date : " + e.getMessage(), "S1009", e);
}
}
}