提交 769aa54b authored 作者: Patrick Brielmayer's avatar Patrick Brielmayer

Improvements

Fixed misspelling
Renamed ToDateParams to ToDateParser
Code cleanup
上级 d1514e17
...@@ -10,7 +10,6 @@ package org.h2.util; ...@@ -10,7 +10,6 @@ package org.h2.util;
import java.sql.Date; import java.sql.Date;
import java.sql.Time; import java.sql.Time;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*; import java.util.*;
...@@ -581,59 +580,6 @@ public class DateTimeUtils { ...@@ -581,59 +580,6 @@ public class DateTimeUtils {
} }
} }
@SuppressWarnings("serial")
private static final Map<String, String> DATE_FORMAT_REGEXPS = new HashMap<String, String>() {
{
put("^\\d{8}[^\\d]*", "yyyyMMdd");
put("^\\d{1,2}\\.\\d{1,2}\\.\\d{4}[^\\d]*", "dd.MM.yyyy");
put("^\\d{4}\\.\\d{1,2}\\.\\d{1,2}[^\\d]*", "yyyy.MM.dd");
put("^\\d{4}-\\d{1,2}-\\d{1,2}[^\\d]*", "yyyy-MM-dd");
put("^\\d{1,2}-\\d{1,2}-\\d{4}[^\\d]*", "dd-MM-yyyy");
put("^\\d{1,2}/\\d{1,2}/\\d{4}[^\\d]*", "dd/MM/yyyy");
put("^\\d{4}/\\d{1,2}/\\d{1,2}[^\\d]*", "yyyy/MM/dd");
put("^\\d{1,2}/\\d{1,2}/\\d{4}[^\\d]*", "dd/MM/yyyy");
put("^\\d{1,2}-[^\\d]{3}-\\d{4}[^\\d]*", "dd-MMM-yyyy");
put("^\\d{4}-[^\\d]{3}-\\d{1,2}[^\\d]*", "yyyy-MMM-dd");
put("^.{2}\\s.{3}\\s\\d{1,2}\\s\\d{1,2}\\:\\d{1,2}\\:\\d{1,2}\\s.{3}\\s\\d{4}$",
"EEE MMM dd hh:mm:ss z yyyy");
}
};
/**
* Determine SimpleDateFormat pattern matching with the given date string. Returns null if format is unknown. You can
* simply extend DateUtil with more formats if needed.
*
* @param dateString
* The date string to determine the SimpleDateFormat pattern for.
* @return The matching SimpleDateFormat pattern, or null if format is unknown.
*/
private static String determineDateFormat(final String dateString) {
for (String regexp : DATE_FORMAT_REGEXPS.keySet()) {
if (dateString.toLowerCase().matches(regexp)) {
return DATE_FORMAT_REGEXPS.get(regexp);
}
}
return null; // Unknown format.
}
/**
* Parse date-string in "Best Effort" (BE) manner.
* Uses a predefined list of date patterns to parse a string into a date.
*/
public static java.util.Date parseDateBestEffort(final String dateStr) {
String dateFormat = determineDateFormat(dateStr);
if (dateFormat == null) {
// The source does not contain a date that can be parsed.
throw DbException.get(ErrorCode.PARSE_ERROR_1, "Invalid date. " + dateStr);
}
SimpleDateFormat formatter = new SimpleDateFormat(dateFormat);
try {
return formatter.parse(dateStr);
} catch (ParseException e) {
throw DbException.get(ErrorCode.PARSE_ERROR_1, e, "Invalid date. " + dateStr);
}
}
/** /**
* Parses a date using a format string. * Parses a date using a format string.
* *
......
package org.h2.util; package org.h2.util;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.List; import java.util.Date;
import org.h2.util.ToDateTokenizer.FormatTokenEnum;
/** /**
* Emulates Oracle's TO_DATE function.<br> * Emulates Oracle's TO_DATE function.<br>
* Main class * Main class
*/ */
public class ToDate { public class ToDate {
public enum ToDateFunctionName {
TO_DATE("DD MON YYYY"), TO_TIMESTAMP("DD MON YYYY HH:MI:SS");
private final String defaultFormatStr;
ToDateFunctionName(final String defaultFormatStr) {
this.defaultFormatStr = defaultFormatStr;
}
String getDefaultFormatStr() {
return defaultFormatStr;
}
};
public static Timestamp TO_DATE(final String input, final String format) { public static Timestamp TO_DATE(final String input, final String format) {
ToDateParams parsed = parse(new ToDateParams(ToDateFunctionName.TO_DATE, input, format)); ToDateParser parser = ToDateParser.toDate(input, format);
return parsed.getResultingTimestamp(); return parser.getResultingTimestamp();
} }
public static Timestamp TO_TIMESTAMP(final String input, final String format) { public static Timestamp TO_TIMESTAMP(final String input, final String format) {
ToDateParams parsed = parse(new ToDateParams(ToDateFunctionName.TO_TIMESTAMP, input, format)); ToDateParser parser = ToDateParser.toTimestamp(input, format);
return parsed.getResultingTimestamp(); return parser.getResultingTimestamp();
} }
/**
* Parse the format-string with passed token of {@link FormatTokenEnum}}.<br>
* if token matches return true otherwise false.
*/
private static ToDateParams parse(final ToDateParams p) {
while (p.hasToParseData()) {
List<FormatTokenEnum> tokenList = FormatTokenEnum.getTokensInQuestion(p);
if (tokenList.isEmpty()) {
p.removeFirstChar();
continue;
}
boolean foundAnToken = false;
for (FormatTokenEnum token : tokenList) {
if (token.parseFormatStrWithToken(p)) {
foundAnToken = true;
break;
}
}
if (!foundAnToken) {
p.removeFirstChar();
continue;
}
}
return p;
}
} }
\ No newline at end of file
...@@ -2,31 +2,53 @@ package org.h2.util; ...@@ -2,31 +2,53 @@ package org.h2.util;
import static java.lang.String.format; import static java.lang.String.format;
import java.sql.Date;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date;
import org.h2.util.ToDate.ToDateFunctionName; import java.util.List;
/** /**
* Emulates Oracle's TO_DATE function.<br> * Emulates Oracle's TO_DATE function.<br>
* This class holds and handles the input data form the TO_DATE-method * This class holds and handles the input data form the TO_DATE-method
*/ */
class ToDateParams { class ToDateParser {
private final String unmodifiedInputStr; private final String unmodifiedInputStr;
private final String unmodifiedFormatStr; private final String unmodifiedFormatStr;
private final ToDateFunctionName functionName; private final ConfigParam functionName;
private String inputStr; private String inputStr;
private String formatStr; private String formatStr;
private final Calendar resultCalendar = (Calendar) Calendar.getInstance().clone(); private final Calendar resultCalendar = (Calendar) Calendar.getInstance().clone();
private Integer nanos = null; private Integer nanos = null;
private enum ConfigParam {
TO_DATE("DD MON YYYY"), TO_TIMESTAMP("DD MON YYYY HH:MI:SS");
private final String defaultFormatStr;
ConfigParam (final String defaultFormatStr) {
this.defaultFormatStr = defaultFormatStr;
}
String getDefaultFormatStr() {
return defaultFormatStr;
}
}
static ToDateParser toDate(final String input, final String format) {
ToDateParser result = new ToDateParser(ConfigParam.TO_DATE, input, format);
parse(result);
return result;
}
static ToDateParser toTimestamp(final String input, final String format) {
ToDateParser result = new ToDateParser(ConfigParam.TO_TIMESTAMP, input, format);
parse(result);
return result;
}
/** /**
* @param input the input date with the date-time info * @param input the input date with the date-time info
* @param format the format of date-time info * @param format the format of date-time info
* @param functionName one of [TO_DATE, TO_TIMESTAMP] (both share the same code) * @param functionName one of [TO_DATE, TO_TIMESTAMP] (both share the same code)
*/ */
ToDateParams(final ToDateFunctionName functionName, final String input, final String format) { ToDateParser(final ConfigParam functionName, final String input, final String format) {
// reset calendar - default oracle behaviour // reset calendar - default oracle behaviour
resultCalendar.set(Calendar.YEAR, 1970); resultCalendar.set(Calendar.YEAR, 1970);
resultCalendar.set(Calendar.MONTH, Calendar.getInstance().get(Calendar.MONTH)); resultCalendar.set(Calendar.MONTH, Calendar.getInstance().get(Calendar.MONTH));
...@@ -52,10 +74,6 @@ class ToDateParams { ...@@ -52,10 +74,6 @@ class ToDateParams {
unmodifiedFormatStr = formatStr; // Keep a copy unmodifiedFormatStr = formatStr; // Keep a copy
} }
Date getResultingDate() {
return new Date(getResultCalendar().getTimeInMillis());
}
Timestamp getResultingTimestamp() { Timestamp getResultingTimestamp() {
Calendar cal = (Calendar) getResultCalendar().clone(); Calendar cal = (Calendar) getResultCalendar().clone();
int nanosToSet = nanos == null ? cal.get(Calendar.MILLISECOND) * 1000000 : nanos.intValue(); int nanosToSet = nanos == null ? cal.get(Calendar.MILLISECOND) * 1000000 : nanos.intValue();
...@@ -77,8 +95,8 @@ class ToDateParams { ...@@ -77,8 +95,8 @@ class ToDateParams {
return formatStr; return formatStr;
} }
ToDateFunctionName getFunctionName() { String getFunctionName() {
return functionName; return functionName.name();
} }
void setNanos(final int nanos) { void setNanos(final int nanos) {
...@@ -98,6 +116,28 @@ class ToDateParams { ...@@ -98,6 +116,28 @@ class ToDateParams {
} }
} }
private static ToDateParser parse(final ToDateParser p) {
while (p.hasToParseData()) {
List<ToDateTokenizer.FormatTokenEnum> tokenList = ToDateTokenizer.FormatTokenEnum.getTokensInQuestion(p.getFormatStr());
if (tokenList.isEmpty()) {
p.removeFirstChar();
continue;
}
boolean foundAnToken = false;
for (ToDateTokenizer.FormatTokenEnum token : tokenList) {
if (token.parseFormatStrWithToken(p)) {
foundAnToken = true;
break;
}
}
if (!foundAnToken) {
p.removeFirstChar();
continue;
}
}
return p;
}
void remove(final String toIgnore) { void remove(final String toIgnore) {
if (toIgnore != null) { if (toIgnore != null) {
int trimLeng = toIgnore.length(); int trimLeng = toIgnore.length();
......
...@@ -27,7 +27,6 @@ class ToDateTokenizer { ...@@ -27,7 +27,6 @@ class ToDateTokenizer {
private static final Pattern PATTERN_BC_AD = Pattern.compile("^(BC|B\\.C\\.|AD|A\\.D\\.)", Pattern.CASE_INSENSITIVE); private static final Pattern PATTERN_BC_AD = Pattern.compile("^(BC|B\\.C\\.|AD|A\\.D\\.)", Pattern.CASE_INSENSITIVE);
private static final YearParslet PARSLET_YEAR = new YearParslet(); private static final YearParslet PARSLET_YEAR = new YearParslet();
private static final MonthParslet PARSLET_MONTH = new MonthParslet(); private static final MonthParslet PARSLET_MONTH = new MonthParslet();
//private static final WeekParslet PARSLET_Week = new WeekParslet();
private static final DayParslet PARSLET_DAY = new DayParslet(); private static final DayParslet PARSLET_DAY = new DayParslet();
private static final TimeParslet PARSLET_TIME = new TimeParslet(); private static final TimeParslet PARSLET_TIME = new TimeParslet();
...@@ -48,8 +47,6 @@ class ToDateTokenizer { ...@@ -48,8 +47,6 @@ class ToDateTokenizer {
, MON(PARSLET_MONTH) // Abbreviated name of month. , MON(PARSLET_MONTH) // Abbreviated name of month.
, MM(PARSLET_MONTH) // Month (01-12; JAN = 01). , MM(PARSLET_MONTH) // Month (01-12; JAN = 01).
, RM(PARSLET_MONTH) // Roman numeral month (I-XII; JAN = I). , RM(PARSLET_MONTH) // Roman numeral month (I-XII; JAN = I).
//, WW(PARSLET_Week) // Week of year (1-53)
//, IW(PARSLET_Week) // Week of year (1-52 or 1-53) based on the ISO standard.
, DDD(PARSLET_DAY) // Day of year (1-366). , DDD(PARSLET_DAY) // Day of year (1-366).
, DAY(PARSLET_DAY) // Name of day. , DAY(PARSLET_DAY) // Name of day.
, DD(PARSLET_DAY) // Day of month (1-31). , DD(PARSLET_DAY) // Day of month (1-31).
...@@ -71,7 +68,6 @@ class ToDateTokenizer { ...@@ -71,7 +68,6 @@ class ToDateTokenizer {
, Y(PARSLET_YEAR) // , Y(PARSLET_YEAR) //
, I(PARSLET_YEAR) // , I(PARSLET_YEAR) //
, Q(PARSLET_MONTH) // Quarter of year (1, 2, 3, 4; JAN-MAR = 1). , Q(PARSLET_MONTH) // Quarter of year (1, 2, 3, 4; JAN-MAR = 1).
//, W(PARSLET_Week) // Week of month (1-5)
, D(PARSLET_DAY) // Day of week (1-7). , D(PARSLET_DAY) // Day of week (1-7).
, J(PARSLET_DAY); // NOT supported yet - Julian day; the number of days since Jan 1, 4712 BC. , J(PARSLET_DAY); // NOT supported yet - Julian day; the number of days since Jan 1, 4712 BC.
...@@ -96,12 +92,11 @@ class ToDateTokenizer { ...@@ -96,12 +92,11 @@ class ToDateTokenizer {
* OPTIMISATION: Only return a list of {@link FormatTokenEnum} that share the same 1st char * OPTIMISATION: Only return a list of {@link FormatTokenEnum} that share the same 1st char
* using the 1st char of the 'to parse' formatStr. Or return empty list if no match. * using the 1st char of the 'to parse' formatStr. Or return empty list if no match.
*/ */
static List<FormatTokenEnum> getTokensInQuestion(final ToDateParams params) { static List<FormatTokenEnum> getTokensInQuestion(String formatStr) {
List<FormatTokenEnum> result = EMPTY_LIST; List<FormatTokenEnum> result = EMPTY_LIST;
if (cache.size() <= 0) { if (cache.size() <= 0) {
initCache(); initCache();
} }
String formatStr = params.getFormatStr();
if (formatStr != null && formatStr.length() > 0) { if (formatStr != null && formatStr.length() > 0) {
Character key = Character.toUpperCase(formatStr.charAt(0)); Character key = Character.toUpperCase(formatStr.charAt(0));
result = cache.get(key); result = cache.get(key);
...@@ -142,9 +137,9 @@ class ToDateTokenizer { ...@@ -142,9 +137,9 @@ class ToDateTokenizer {
/** /**
* Parse the format-string with passed token of {@link FormatTokenEnum}}.<br> * Parse the format-string with passed token of {@link FormatTokenEnum}}.<br>
* if token matches return true otherwise false. * If token matches return true, otherwise false.
*/ */
boolean parseFormatStrWithToken(final ToDateParams params) { boolean parseFormatStrWithToken(final ToDateParser params) {
Matcher matcher = patternToUse.matcher(params.getFormatStr()); Matcher matcher = patternToUse.matcher(params.getFormatStr());
boolean foundToken = matcher.find(); boolean foundToken = matcher.find();
if (foundToken) { if (foundToken) {
...@@ -159,15 +154,15 @@ class ToDateTokenizer { ...@@ -159,15 +154,15 @@ class ToDateTokenizer {
* Interface of the classes that can parse a specialized small bit of the TO_DATE format-string * Interface of the classes that can parse a specialized small bit of the TO_DATE format-string
*/ */
interface ToDateParslet { interface ToDateParslet {
ToDateParams parse(ToDateParams params, FormatTokenEnum formatTokenEnum, String formatTokenStr); void parse(ToDateParser params, FormatTokenEnum formatTokenEnum, String formatTokenStr);
} }
/** /**
* * Parslet responsible for parsing year parameter
*/ */
private static final class YearParslet implements ToDateParslet { private static final class YearParslet implements ToDateParslet {
@Override @Override
public ToDateParams parse(final ToDateParams params, final FormatTokenEnum formatTokenEnum, public void parse(final ToDateParser params, final FormatTokenEnum formatTokenEnum,
final String formatTokenStr) { final String formatTokenStr) {
final Calendar result = params.getResultCalendar(); final Calendar result = params.getResultCalendar();
String inputFragmentStr = null; String inputFragmentStr = null;
...@@ -241,19 +236,18 @@ class ToDateTokenizer { ...@@ -241,19 +236,18 @@ class ToDateTokenizer {
.getSimpleName(), formatTokenEnum)); .getSimpleName(), formatTokenEnum));
} }
params.remove(inputFragmentStr, formatTokenStr); params.remove(inputFragmentStr, formatTokenStr);
return params;
} }
} }
/** /**
* * Parslet responsible for parsing month parameter
*/ */
private static final class MonthParslet implements ToDateParslet { private static final class MonthParslet implements ToDateParslet {
private static String[] ROMAN_Month = { "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", private static final String[] ROMAN_Month = { "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X",
"XII" }; "XI", "XII" };
@Override @Override
public ToDateParams parse(final ToDateParams params, final FormatTokenEnum formatTokenEnum, public void parse(final ToDateParser params, final FormatTokenEnum formatTokenEnum,
final String formatTokenStr) { final String formatTokenStr) {
final Calendar result = params.getResultCalendar(); final Calendar result = params.getResultCalendar();
final String s = params.getInputStr(); final String s = params.getInputStr();
...@@ -288,7 +282,7 @@ class ToDateTokenizer { ...@@ -288,7 +282,7 @@ class ToDateTokenizer {
} }
if (inputFragmentStr == null || inputFragmentStr.isEmpty()) { if (inputFragmentStr == null || inputFragmentStr.isEmpty()) {
throwException(params, throwException(params,
format("Issue happend when parsing token '%s'. Expected one of: %s", format("Issue happened when parsing token '%s'. Expected one of: %s",
formatTokenEnum.name(), Arrays.toString(ROMAN_Month))); formatTokenEnum.name(), Arrays.toString(ROMAN_Month)));
} }
break; break;
...@@ -297,60 +291,15 @@ class ToDateTokenizer { ...@@ -297,60 +291,15 @@ class ToDateTokenizer {
.getSimpleName(), formatTokenEnum)); .getSimpleName(), formatTokenEnum));
} }
params.remove(inputFragmentStr, formatTokenStr); params.remove(inputFragmentStr, formatTokenStr);
return params;
} }
} }
/** /**
* Week parsing can be used by TO_CHAR but not by TO_DATE * Parslet responsible for parsing day parameter
*
private static final class WeekParslet implements ToDateParslet {
@Override
public ToDateParams parse(final ToDateParams params, final FormatTokenEnum formatTokenEnum,
final String formatTokenStr) {
final Calendar result = params.getResultCalendar();
String inputFragmentStr = null;
int dateNr = 0;
switch (formatTokenEnum) {
case WW:
inputFragmentStr = matchStringOrDie(PATTERN_TWO_DIGITS_OR_LESS, params, formatTokenEnum);
dateNr = parseInt(inputFragmentStr);
// The first week of the month, as defined by
// getFirstDayOfWeek() and getMinimalDaysInFirstWeek(),
result.set(Calendar.WEEK_OF_YEAR, dateNr);
break;
case IW:
inputFragmentStr = matchStringOrDie(PATTERN_TWO_DIGITS_OR_LESS, params, formatTokenEnum);
dateNr = parseInt(inputFragmentStr);
// Build set the calendar to ISO8601 (see
// http://en.wikipedia.org/wiki/ISO_8601_week_number)
result.setMinimalDaysInFirstWeek(4);
result.setFirstDayOfWeek(Calendar.MONDAY);
result.set(Calendar.WEEK_OF_YEAR, dateNr);
break;
case W:
inputFragmentStr = matchStringOrDie(PATTERN_ONE_DIGIT, params, formatTokenEnum);
dateNr = parseInt(inputFragmentStr);
// The first week of the month, as defined by
// getFirstDayOfWeek() and getMinimalDaysInFirstWeek(),
result.set(Calendar.WEEK_OF_MONTH, dateNr);
break;
default:
throw new IllegalArgumentException(format("%s: Internal Error. Unhandled case: %s", this.getClass()
.getSimpleName(), formatTokenEnum));
}
params.remove(inputFragmentStr, formatTokenStr);
return params;
}
}
*/
/**
*
*/ */
private static final class DayParslet implements ToDateParslet { private static final class DayParslet implements ToDateParslet {
@Override @Override
public ToDateParams parse(final ToDateParams params, final FormatTokenEnum formatTokenEnum, public void parse(final ToDateParser params, final FormatTokenEnum formatTokenEnum,
final String formatTokenStr) { final String formatTokenStr) {
final Calendar result = params.getResultCalendar(); final Calendar result = params.getResultCalendar();
String inputFragmentStr = null; String inputFragmentStr = null;
...@@ -391,19 +340,18 @@ class ToDateTokenizer { ...@@ -391,19 +340,18 @@ class ToDateTokenizer {
.getSimpleName(), formatTokenEnum)); .getSimpleName(), formatTokenEnum));
} }
params.remove(inputFragmentStr, formatTokenStr); params.remove(inputFragmentStr, formatTokenStr);
return params;
} }
} }
private static int MILLIS_in_hour = 60 * 60 * 1000; private static int MILLIS_in_hour = 60 * 60 * 1000;
/** /**
* * Parslet responsible for parsing time parameter
*/ */
private static final class TimeParslet implements ToDateParslet { private static final class TimeParslet implements ToDateParslet {
@Override @Override
public ToDateParams parse(final ToDateParams params, final FormatTokenEnum formatTokenEnum, public void parse(final ToDateParser params, final FormatTokenEnum formatTokenEnum,
final String formatTokenStr) { final String formatTokenStr) {
final Calendar result = params.getResultCalendar(); final Calendar result = params.getResultCalendar();
String inputFragmentStr = null; String inputFragmentStr = null;
...@@ -495,11 +443,9 @@ class ToDateTokenizer { ...@@ -495,11 +443,9 @@ class ToDateTokenizer {
.getSimpleName(), formatTokenEnum)); .getSimpleName(), formatTokenEnum));
} }
params.remove(inputFragmentStr, formatTokenStr); params.remove(inputFragmentStr, formatTokenStr);
return params;
} }
} }
// ========== PRIVATE ===================
private static int parseInt(final String s) { private static int parseInt(final String s) {
int result = 0; int result = 0;
if (s.length() > 0 && s.charAt(0) == '+') { if (s.length() > 0 && s.charAt(0) == '+') {
...@@ -510,7 +456,7 @@ class ToDateTokenizer { ...@@ -510,7 +456,7 @@ class ToDateTokenizer {
return result; return result;
} }
private static String matchStringOrDie(final Pattern p, final ToDateParams params, final Enum<?> aEnum) { private static String matchStringOrDie(final Pattern p, final ToDateParser params, final Enum<?> aEnum) {
final String s = params.getInputStr(); final String s = params.getInputStr();
Matcher matcher = p.matcher(s); Matcher matcher = p.matcher(s);
if (!matcher.find()) { if (!matcher.find()) {
...@@ -519,7 +465,7 @@ class ToDateTokenizer { ...@@ -519,7 +465,7 @@ class ToDateTokenizer {
return matcher.group(1); return matcher.group(1);
} }
private static String setByName(final Calendar c, final ToDateParams params, final int field, final int style) { private static String setByName(final Calendar c, final ToDateParser params, final int field, final int style) {
String inputFragmentStr = null; String inputFragmentStr = null;
String s = params.getInputStr(); String s = params.getInputStr();
Map<String, Integer> timeStringMap = c.getDisplayNames(field, style, Locale.getDefault()); Map<String, Integer> timeStringMap = c.getDisplayNames(field, style, Locale.getDefault());
...@@ -532,16 +478,16 @@ class ToDateTokenizer { ...@@ -532,16 +478,16 @@ class ToDateTokenizer {
} }
} }
if (inputFragmentStr == null || inputFragmentStr.isEmpty()) { if (inputFragmentStr == null || inputFragmentStr.isEmpty()) {
throwException(params, format("Tryed to parse one of '%s' but failed (may be an internal error?)", throwException(params, format("Tried to parse one of '%s' but failed (may be an internal error?)",
timeStringMap.keySet())); timeStringMap.keySet()));
} }
return inputFragmentStr; return inputFragmentStr;
} }
private static void throwException(final ToDateParams params, final String errorStr) { private static void throwException(final ToDateParser params, final String errorStr) {
throw DbException.get( throw DbException.get(
ErrorCode.INVALID_TO_DATE_FORMAT, ErrorCode.INVALID_TO_DATE_FORMAT,
params.getFunctionName().name(), params.getFunctionName(),
format(" %s. Details: %s", errorStr, params)); format(" %s. Details: %s", errorStr, params));
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论