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); } }