in core/src/main/java/org/apache/calcite/avatica/util/DateTimeUtils.java [224:284]
public static PrecisionTime parsePrecisionDateTimeLiteral(String s,
DateFormat dateFormat, TimeZone tz, int maxPrecision) {
final ParsePosition pp = new ParsePosition(0);
final Calendar cal = parseDateFormat(s, dateFormat, tz, pp);
if (cal == null) {
return null; // Invalid date/time format
}
// Note: the Java SimpleDateFormat 'S' treats any number after
// the decimal as milliseconds. That means 12:00:00.9 has 9
// milliseconds and 12:00:00.9999 has 9999 milliseconds.
int p = 0;
String secFraction = "";
if (pp.getIndex() < s.length()) {
// Check to see if rest is decimal portion
if (s.charAt(pp.getIndex()) != '.') {
return null;
}
// Skip decimal sign
pp.setIndex(pp.getIndex() + 1);
// Parse decimal portion
if (pp.getIndex() < s.length()) {
secFraction = s.substring(pp.getIndex());
if (!secFraction.matches("\\d+")) {
return null;
}
NumberFormat nf = NumberFormat.getIntegerInstance(Locale.ROOT);
Number num = nf.parse(s, pp);
if (num == null || pp.getIndex() != s.length()) {
// Invalid decimal portion
return null;
}
// Determine precision - only support prec 3 or lower
// (milliseconds) Higher precisions are quietly rounded away
p = secFraction.length();
if (maxPrecision >= 0) {
// If there is a maximum precision, ignore subsequent digits
p = Math.min(maxPrecision, p);
secFraction = secFraction.substring(0, p);
}
// Calculate milliseconds
String millis = secFraction;
if (millis.length() > 3) {
millis = secFraction.substring(0, 3);
}
while (millis.length() < 3) {
millis = millis + "0";
}
int ms = Integer.parseInt(millis);
cal.add(Calendar.MILLISECOND, ms);
}
}
assert pp.getIndex() == s.length();
return new PrecisionTime(cal, secFraction, p);
}