package com.gwt.ui.client;
import java.util.Date;
/**
* This is a simple regular expression based parser for date notations.
* While our aim is to fully support in the future the JDK date parser, currently
* only numeric notations and literals are supported such as <code>dd/MM/yyyy HH:mm:ss.SSSS</code>.
* Each entity is parsed with the same number of digits, i.e. for <code>dd</code> two digits will be
* parsed while for <code>d</code> only one will be parsed.
*
* @author <a href="mailto:g.georgovassilis@gmail.com">George Georgovassilis</a>
*/
public class SimpleDateParser {
// private final static String DAY_IN_MONTH = "d";
//
// private final static String MONTH = "M";
//
// private final static String YEAR = "y";
//
// private final static String LITERAL = "\\";
private final static int DATE_PATTERN = 0;
private final static int REGEX_PATTERN = 1;
private final static int COMPONENT = 2;
private final static int REGEX = 0;
private final static int INSTRUCTION = 1;
private final static String[] TOKENS[] = {
{
"SSSS", "(\\d\\d\\d\\d)", DateLocale.TOKEN_MILLISECOND
}, {
"SSS", "(\\d\\d\\d)", DateLocale.TOKEN_MILLISECOND
}, {
"SS", "(\\d\\d)", DateLocale.TOKEN_MILLISECOND
}, {
"S", "(\\d)", DateLocale.TOKEN_MILLISECOND
}, {
"ss", "(\\d\\d)", DateLocale.TOKEN_SECOND
}, {
"s", "(\\d)", DateLocale.TOKEN_SECOND
}, {
"mm", "(\\d\\d)", DateLocale.TOKEN_MINUTE
}, {
"m", "(\\d)", DateLocale.TOKEN_MINUTE
}, {
"HH", "(\\d\\d)", DateLocale.TOKEN_HOUR_24
}, {
"H", "(\\d)", DateLocale.TOKEN_HOUR_24
}, {
"dd", "(\\d\\d)", DateLocale.TOKEN_DAY_OF_MONTH
}, {
"d", "(\\d)", DateLocale.TOKEN_DAY_OF_MONTH
}, {
"MM", "(\\d\\d)", DateLocale.TOKEN_MONTH
}, {
"M", "(\\d)", DateLocale.TOKEN_MONTH
}, {
"yyyy", "(\\d\\d\\d\\d)", DateLocale.TOKEN_YEAR
}, {
"yyy", "(\\d\\d\\d)", DateLocale.TOKEN_YEAR
}, {
"yy", "(\\d\\d)", DateLocale.TOKEN_YEAR
}, {
"y", "(\\d)", DateLocale.TOKEN_YEAR
}
};
private Pattern regularExpression;;
private String instructions = "";
private static void _parse(String format, String[] args) {
if (format.length() == 0)
return;
if (format.startsWith("'")) {
format = format.substring(1);
int end = format.indexOf("'");
if (end == -1)
throw new IllegalArgumentException("Unmatched single quotes.");
args[REGEX] += Pattern.quote(format.substring(0, end));
format = format.substring(end + 1);
}
for (int i = 0; i < TOKENS.length; i++) {
String[] row = TOKENS[i];
String datePattern = row[DATE_PATTERN];
if (!format.startsWith(datePattern))
continue;
format = format.substring(datePattern.length());
args[REGEX] += row[REGEX_PATTERN];
args[INSTRUCTION] += row[COMPONENT];
_parse(format, args);
return;
}
args[REGEX] += Pattern.quote("" + format.charAt(0));
format = format.substring(1);
_parse(format, args);
}
@SuppressWarnings("deprecation")
private static void load(Date date, String text, String component) {
if (component.equals(DateLocale.TOKEN_MILLISECOND)) {
// TODO: implement
}
if (component.equals(DateLocale.TOKEN_SECOND)) {
date.setSeconds(Integer.parseInt(text));
}
if (component.equals(DateLocale.TOKEN_MINUTE)) {
date.setMinutes(Integer.parseInt(text));
}
if (component.equals(DateLocale.TOKEN_HOUR_24)) {
date.setHours(Integer.parseInt(text));
}
if (component.equals(DateLocale.TOKEN_DAY_OF_MONTH)) {
date.setDate(Integer.parseInt(text));
}
if (component.equals(DateLocale.TOKEN_MONTH)) {
date.setMonth(Integer.parseInt(text) - 1);
}
if (component.equals(DateLocale.TOKEN_YEAR)) {
// TODO: fix for short patterns
date.setYear(Integer.parseInt(text) - 1900);
}
}
public SimpleDateParser(String format) {
String[] args = new String[] {
"", ""
};
_parse(format, args);
regularExpression = new Pattern(args[REGEX]);
instructions = args[INSTRUCTION];
}
@SuppressWarnings("deprecation")
public Date parse(String input) {
Date date = new Date(0, 0, 0, 0, 0, 0);
String matches[] = regularExpression.match(input);
if (matches == null)
throw new IllegalArgumentException(input + " does not match " + regularExpression.pattern());
if (matches.length - 1 != instructions.length())
throw new IllegalArgumentException("Different group count - " + input + " does not match " + regularExpression.pattern());
for (int group = 0; group < instructions.length(); group++) {
String match = matches[group + 1];
load(date, match, "" + instructions.charAt(group));
}
return date;
}
public static Date parse(String input, String pattern) {
return new SimpleDateParser(pattern).parse(input);
}
}