提交 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();
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论