提交 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;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
......@@ -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.
*
......
package org.h2.util;
import java.sql.Timestamp;
import java.util.List;
import org.h2.util.ToDateTokenizer.FormatTokenEnum;
import java.util.Date;
/**
* Emulates Oracle's TO_DATE function.<br>
* Main class
*/
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) {
ToDateParams parsed = parse(new ToDateParams(ToDateFunctionName.TO_DATE, input, format));
return parsed.getResultingTimestamp();
ToDateParser parser = ToDateParser.toDate(input, format);
return parser.getResultingTimestamp();
}
public static Timestamp TO_TIMESTAMP(final String input, final String format) {
ToDateParams parsed = parse(new ToDateParams(ToDateFunctionName.TO_TIMESTAMP, input, format));
return parsed.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;
ToDateParser parser = ToDateParser.toTimestamp(input, format);
return parser.getResultingTimestamp();
}
}
\ No newline at end of file
......@@ -2,31 +2,53 @@ package org.h2.util;
import static java.lang.String.format;
import java.sql.Date;
import java.sql.Timestamp;
import java.util.Calendar;
import org.h2.util.ToDate.ToDateFunctionName;
import java.util.Date;
import java.util.List;
/**
* Emulates Oracle's TO_DATE function.<br>
* This class holds and handles the input data form the TO_DATE-method
*/
class ToDateParams {
class ToDateParser {
private final String unmodifiedInputStr;
private final String unmodifiedFormatStr;
private final ToDateFunctionName functionName;
private final ConfigParam functionName;
private String inputStr;
private String formatStr;
private final Calendar resultCalendar = (Calendar) Calendar.getInstance().clone();
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 format the format of date-time info
* @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
resultCalendar.set(Calendar.YEAR, 1970);
resultCalendar.set(Calendar.MONTH, Calendar.getInstance().get(Calendar.MONTH));
......@@ -52,10 +74,6 @@ class ToDateParams {
unmodifiedFormatStr = formatStr; // Keep a copy
}
Date getResultingDate() {
return new Date(getResultCalendar().getTimeInMillis());
}
Timestamp getResultingTimestamp() {
Calendar cal = (Calendar) getResultCalendar().clone();
int nanosToSet = nanos == null ? cal.get(Calendar.MILLISECOND) * 1000000 : nanos.intValue();
......@@ -77,8 +95,8 @@ class ToDateParams {
return formatStr;
}
ToDateFunctionName getFunctionName() {
return functionName;
String getFunctionName() {
return functionName.name();
}
void setNanos(final int nanos) {
......@@ -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) {
if (toIgnore != null) {
int trimLeng = toIgnore.length();
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论