Revision: 19884 http://sourceforge.net/p/gate/code/19884 Author: markagreenwood Date: 2016-12-20 23:15:07 +0000 (Tue, 20 Dec 2016) Log Message: ----------- converted to maven and moved the actual parser code into the plugin from my own svn repo and at the same time relicesed it as LGPL rather than GPL to make everyones life easier
Modified Paths: -------------- gate/branches/sawdust2/plugins/Tagger_DateNormalizer/.classpath gate/branches/sawdust2/plugins/Tagger_DateNormalizer/.project gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/main/java/gate/creole/dates/DateAnnotationNormalizer.java Added Paths: ----------- gate/branches/sawdust2/plugins/Tagger_DateNormalizer/pom.xml gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/main/ gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/main/java/ gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/main/java/gate/ gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/main/java/mark/ gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/main/java/mark/util/ gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/main/java/mark/util/DateParser.java gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/main/java/mark/util/ParsePositionEx.java gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/main/resources/ gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/main/resources/creole.xml gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/main/resources/gate/ gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/main/resources/gate/resources/ gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/test/ gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/test/java/ gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/test/java/mark/ gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/test/java/mark/util/ gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/test/java/mark/util/DateParserTest.java Removed Paths: ------------- gate/branches/sawdust2/plugins/Tagger_DateNormalizer/build.xml gate/branches/sawdust2/plugins/Tagger_DateNormalizer/creole.xml gate/branches/sawdust2/plugins/Tagger_DateNormalizer/doc/ gate/branches/sawdust2/plugins/Tagger_DateNormalizer/lib/ gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/gate/ gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/main/java/gate/resources/ Property Changed: ---------------- gate/branches/sawdust2/plugins/Tagger_DateNormalizer/ Index: gate/branches/sawdust2/plugins/Tagger_DateNormalizer =================================================================== --- gate/branches/sawdust2/plugins/Tagger_DateNormalizer 2016-12-20 22:38:09 UTC (rev 19883) +++ gate/branches/sawdust2/plugins/Tagger_DateNormalizer 2016-12-20 23:15:07 UTC (rev 19884) Property changes on: gate/branches/sawdust2/plugins/Tagger_DateNormalizer ___________________________________________________________________ Modified: svn:ignore ## -1,3 +1,2 ## -classes -DateNormalizer.jar +target .settings Modified: gate/branches/sawdust2/plugins/Tagger_DateNormalizer/.classpath =================================================================== --- gate/branches/sawdust2/plugins/Tagger_DateNormalizer/.classpath 2016-12-20 22:38:09 UTC (rev 19883) +++ gate/branches/sawdust2/plugins/Tagger_DateNormalizer/.classpath 2016-12-20 23:15:07 UTC (rev 19884) @@ -1,8 +1,31 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> - <classpathentry kind="src" path="src"/> - <classpathentry exported="true" kind="lib" path="lib/DateParser.jar"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> - <classpathentry combineaccessrules="false" exported="true" kind="src" path="/GATE"/> - <classpathentry kind="output" path="classes"/> + <classpathentry kind="src" output="target/classes" path="src/main/java"> + <attributes> + <attribute name="optional" value="true"/> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="src" output="target/test-classes" path="src/test/java"> + <attributes> + <attribute name="optional" value="true"/> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="output" path="target/classes"/> </classpath> Modified: gate/branches/sawdust2/plugins/Tagger_DateNormalizer/.project =================================================================== --- gate/branches/sawdust2/plugins/Tagger_DateNormalizer/.project 2016-12-20 22:38:09 UTC (rev 19883) +++ gate/branches/sawdust2/plugins/Tagger_DateNormalizer/.project 2016-12-20 23:15:07 UTC (rev 19884) @@ -10,8 +10,14 @@ <arguments> </arguments> </buildCommand> + <buildCommand> + <name>org.eclipse.m2e.core.maven2Builder</name> + <arguments> + </arguments> + </buildCommand> </buildSpec> <natures> <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.m2e.core.maven2Nature</nature> </natures> </projectDescription> Deleted: gate/branches/sawdust2/plugins/Tagger_DateNormalizer/build.xml =================================================================== --- gate/branches/sawdust2/plugins/Tagger_DateNormalizer/build.xml 2016-12-20 22:38:09 UTC (rev 19883) +++ gate/branches/sawdust2/plugins/Tagger_DateNormalizer/build.xml 2016-12-20 23:15:07 UTC (rev 19884) @@ -1,85 +0,0 @@ -<project name="DateNormalizer" basedir="." default="build"> - <!-- Prevent Ant from warning about includeantruntime not being set --> - <property name="build.sysclasspath" value="ignore" /> - - <property file="build.properties" /> - - <property name="gate.home" location="../.." /> - <property name="gate.lib" location="${gate.home}/lib" /> - <property name="gate.jar" location="${gate.home}/bin/gate.jar" /> - <property name="src.dir" location="src" /> - <property name="classes.dir" location="classes" /> - <property name="jar.location" location="DateNormalizer.jar" /> - <property name="lib" location="lib" /> - <property name="doc.dir" location="doc" /> - <property name="javadoc.dir" location="${doc.dir}/javadoc" /> - - <!-- Path to compile - includes gate.jar and GATE/lib/*.jar --> - <path id="compile.classpath"> - <fileset dir="lib"> - <include name="**/*.jar" /> - </fileset> - <pathelement location="${gate.jar}" /> - <fileset dir="${gate.lib}"> - <include name="**/*.jar" /> - <include name="**/*.zip" /> - </fileset> - </path> - - <!-- create build directory structure --> - <target name="prepare"> - <mkdir dir="${classes.dir}" /> - </target> - - <target name="resources" depends="prepare"> - <copy todir="${classes.dir}/gate/resources" includeEmptyDirs="true"> - <fileset dir="${src.dir}/gate/resources" /> - </copy> - </target> - - <!-- compile the source --> - <target name="compile" depends="prepare, resources"> - <javac classpathref="compile.classpath" srcdir="${src.dir}" destdir="${classes.dir}" debug="true" debuglevel="lines,source" source="1.5" target="1.5"> - </javac> - </target> - - <!-- create the JAR file --> - <target name="jar" depends="compile"> - <jar destfile="${jar.location}" update="false" basedir="${classes.dir}" /> - </target> - - <!-- remove the generated .class files --> - <target name="clean.classes"> - <delete dir="${classes.dir}" /> - </target> - - <!-- Clean up - remove .class and .jar files --> - <target name="clean" depends="clean.classes"> - <delete file="${jar.location}" /> - </target> - - <!-- Build JavaDoc documentation --> - <target name="doc.prepare"> - <mkdir dir="${javadoc.dir}" /> - </target> - - <target name="javadoc" depends="jar, doc.prepare"> - <javadoc destdir="${javadoc.dir}" packagenames="*" classpathref="compile.classpath" encoding="UTF-8" windowtitle="DateNormalizer JavaDoc" source="1.6"> - <sourcepath> - <pathelement location="${src.dir}" /> - </sourcepath> - <link href="http://docs.oracle.com/javase/6/docs/api/" /> - <link href="http://gate.ac.uk/gate/doc/javadoc/" /> - </javadoc> - </target> - - <!-- Targets used by the main GATE build file: - build: build the plugin - just calls "jar" target - test : run the unit tests - there aren't any - distro.prepare: remove intermediate files that shouldn't be in the - distribution - --> - <target name="build" depends="jar" /> - <target name="test" /> - <target name="distro.prepare" depends="clean.classes" /> -</project> Deleted: gate/branches/sawdust2/plugins/Tagger_DateNormalizer/creole.xml =================================================================== --- gate/branches/sawdust2/plugins/Tagger_DateNormalizer/creole.xml 2016-12-20 22:38:09 UTC (rev 19883) +++ gate/branches/sawdust2/plugins/Tagger_DateNormalizer/creole.xml 2016-12-20 23:15:07 UTC (rev 19884) @@ -1,6 +0,0 @@ -<CREOLE-DIRECTORY> - <CREOLE> - <JAR>lib/DateParser.jar</JAR> - <JAR scan="true">DateNormalizer.jar</JAR> - </CREOLE> -</CREOLE-DIRECTORY> Added: gate/branches/sawdust2/plugins/Tagger_DateNormalizer/pom.xml =================================================================== --- gate/branches/sawdust2/plugins/Tagger_DateNormalizer/pom.xml (rev 0) +++ gate/branches/sawdust2/plugins/Tagger_DateNormalizer/pom.xml 2016-12-20 23:15:07 UTC (rev 19884) @@ -0,0 +1,38 @@ + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>uk.ac.gate.plugins</groupId> + <artifactId>base-plugin</artifactId> + <!-- this should be the version of GATE you wish to build against --> + <version>9.0-SNAPSHOT</version> + <relativePath>../../Plugin_Base/pom.xml</relativePath> + </parent> + + <!-- this is the description of this plugin --> + <groupId>uk.ac.gate.plugins</groupId> + <artifactId>tagger-datenormalizer</artifactId> + <version>9.0-SNAPSHOT</version> + + <licenses> + <license> + <name>GNU Lesser General Public License (LGPL), Version 3</name> + <url>http://www.gnu.org/licenses/lgpl-3.0.txt</url> + <distribution>repo</distribution> + </license> + </licenses> + + <organization> + <name>GATE</name> + <url>http://gate.ac.uk</url> + </organization> + + <dependencies> + <!-- add any other libraries your plugin depends on. Any other GATE plugins + you depend on at compile time should use the provided scope --> + </dependencies> + +</project> Modified: gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/main/java/gate/creole/dates/DateAnnotationNormalizer.java =================================================================== --- gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/gate/creole/dates/DateAnnotationNormalizer.java 2016-12-20 22:38:09 UTC (rev 19883) +++ gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/main/java/gate/creole/dates/DateAnnotationNormalizer.java 2016-12-20 23:15:07 UTC (rev 19884) @@ -32,6 +32,8 @@ @CreoleResource(name = "Date Annotation Normalizer", icon = "date-normalizer.png", comment = "provides normalized values for all existing date annotations", helpURL = "http://gate.ac.uk/userguide/sec:misc-creole:datenormalizer") public class DateAnnotationNormalizer extends DateNormalizer { + private static final long serialVersionUID = -2007965558938967441L; + private String annotationFeature; private Boolean wholeMatchOnly; Added: gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/main/java/mark/util/DateParser.java =================================================================== --- gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/main/java/mark/util/DateParser.java (rev 0) +++ gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/main/java/mark/util/DateParser.java 2016-12-20 23:15:07 UTC (rev 19884) @@ -0,0 +1,900 @@ +/** + * Copyright (C) 2004-2010, Mark A. Greenwood + * + * This file is part of GATE (see http://gate.ac.uk/), and is free software, + * licenced under the GNU Library General Public License, Version 3, June 2007 + * (in the distribution as file licence.html, and also available at + * http://gate.ac.uk/gate/licence.html). + */ +package mark.util; + +import java.io.Serializable; +import java.text.DateFormat; +import java.text.DateFormatSymbols; +import java.text.ParsePosition; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * It is often useful to be able to convert a String representation of a date + * into an actual Date object. Unfortunately the standard methods for doing this + * are very restrictive (often requiring the String representation to be in a + * given format). This parser attempts to convert any date representation into a + * Date object and also provides support for parsing dates which are not fully + * specified (i.e. today) by normalising against a supplied Date object + * (defaults to today). + * @author Mark A. Greenwood + */ +public class DateParser implements Serializable +{ + + private static final long serialVersionUID = -5538057276306768673L; + + /** + * Symbolises that none of the three date fields were inferred but were all + * present in the date being parsed. + */ + public static final int NONE = 0; + + /** + * Symbolises that the day was not in the date being parsed and had + * to be inferred. + */ + public static final int DAY = 1; + + /** + * Symbolises that the month was not in the date being parsed and had + * to be inferred. + */ + public static final int MONTH = 2; + + /** + * Symbolises that the year was not in the date being parsed and had + * to be inferred. + */ + public static final int YEAR = 4; + + /** + * Symbolises that all three fields had to be inferred. + */ + public static final int ALL = DAY | MONTH | YEAR; + + private static final Pattern[] p = new Pattern[] { + + Pattern.compile("(?:(\\p{Alpha}+)(?:,|\\s+the)?\\s+)?(\\d{1,2})\\.?\\s*(?:st|nd|rd|th)?\\s+(?:of\\s+)?(\\p{Alpha}+),?\\s+(\\d{4}|\\d{2})(?=\\b)", Pattern.CASE_INSENSITIVE + | Pattern.MULTILINE), + Pattern.compile("(?:(\\p{Alpha}+)(?:,|\\s+the)?\\s+)?(\\d{1,2})\\.?\\s*(?:st|nd|rd|th)?\\s+(?:of\\s+)?(\\p{Alpha}+)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE), + Pattern.compile("(?:(\\p{Alpha}+)(?:,|\\s+the)?\\s+)?(\\p{Alpha}+)\\.?\\s+(?:the\\s+)?(\\d{1,2})\\s*(?:st|nd|rd|th)?,?\\s+(\\d{4}|\\d{2})(?=\\b)", Pattern.CASE_INSENSITIVE + | Pattern.MULTILINE), + Pattern.compile("(?:(\\p{Alpha}+)(?:,|\\s+the)?\\s+)?(\\p{Alpha}+)\\.?\\s+(?:the\\s+)?(\\d{1,2})(?:\\s*(st|nd|rd|th))?(?=\\b)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE), + Pattern.compile("(\\d{1,2})[-/\\.](\\d{1,2})[-/\\.](\\d{4}|\\d{2})(?=$|[^0-9])", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE), + Pattern.compile("(\\d{4})[-/\\.]\\s*(\\d{1,2})[-/\\.]\\s*(\\d{1,2})", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE), + Pattern.compile("(\\d{1,2})[-/\\.](\\p{Alpha}+)[-/\\.](\\d{4}|\\d{2})", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE), + Pattern.compile("last\\s+(\\p{Alpha}+)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE), Pattern.compile("next\\s+(\\p{Alpha}+)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE), + Pattern.compile("(\\p{Alpha}+)\\s+'?(\\d{4}|\\d{2})(?=\\b)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE), + Pattern.compile("(\\d{1,2})\\s+(\\p{Alpha}+)\\s+ago", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE), + Pattern.compile("(\\d{4})[-\\.]?\\s*(\\p{Alpha}+)[-\\.]?\\s*(\\d{1,2})(?:,?\\s+(\\p{Alpha}+))?", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE), + Pattern.compile("(\\p{Alpha}+)[-/\\.](\\d{1,2})[-/\\.](\\d{4})(?=$|[^0-9])", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE), + Pattern.compile("(\\p{Alpha}+)(?=\\b)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE)}; + + private List<String> weekdays = null; + private List<String> shortWeekdays = null; + + private List<String> months = null; + private List<String> shortMonths = null; + + private List<String> eras = null; + + private boolean monthFirst = true; + + private int century = 0; + private int yearIn = 0; + + private Locale locale; + + /** + * Construct a new date parser which takes the day/month ordering as well as + * month and day of week names from the current locale. + */ + public DateParser() + { + this(Locale.getDefault()); + } + + /** + * Construct a new date parser which takes the day/month ordering as well as + * month and day of week names from the specified locale. + * @param locale the locale used to configure the parser + */ + public DateParser(Locale locale) + { + this.locale = locale; + + if (this.locale == null) this.locale = Locale.getDefault(); + + Calendar cal = Calendar.getInstance(this.locale); + + // Should this be done on this year or on the relative parse date + yearIn = cal.get(Calendar.YEAR) % 100; + century = cal.get(Calendar.YEAR) - yearIn; + + DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, this.locale); + cal.set(2000, 2, 4); + String td = df.format(cal.getTime()); + monthFirst = td.indexOf("3") < td.indexOf("4"); + + DateFormatSymbols dfs = new DateFormatSymbols(this.locale); + + months = arrayToList(dfs.getMonths()); + shortMonths = arrayToList(dfs.getShortMonths()); + + weekdays = arrayToList(dfs.getWeekdays()); + shortWeekdays = arrayToList(dfs.getShortWeekdays()); + + // Is initialised even though it isn't used yet + eras = arrayToList(dfs.getEras()); + } + + /** + * Parses the given text starting at the specified position and using the + * current date + * to infer missing fields. + * @param text the text to parse + * @param pos the position within the text to start parsing + * @return null if the text doesn't represent a date otherwise a fully + * specified Date object + */ + public Date parse(String text, ParsePosition pos) + { + return parse(text, pos, new Date()); + } + + /** + * Parses the given text starting at the specified position using the + * provided date to infer missing fields. If the provided date is null then + * the current date will be used instead. + * @param text the text to parse + * @param pos the position within the text to start parsing + * @param date the date which should be used to infer missing fields + * @return null if the text doesn't represent a date otherwise a fully + * specified Date object + */ + public Date parse(String text, ParsePosition pos, Date date) + { + if (date == null) date = new Date(); + + Calendar parsed = internalParse(text, pos, date); + + if (parsed == null) return null; + + if (pos instanceof ParsePositionEx) + { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + + String relative = "present"; + + if (parsed.before(cal)) relative = "past"; + if (parsed.after(cal)) relative = "future"; + + ((ParsePositionEx) pos).getFeatures().put("relative", relative); + } + + return parsed.getTime(); + } + + private Calendar internalParse(String text, ParsePosition pos, Date date) + { + Calendar cal = Calendar.getInstance(locale); + cal.setLenient(false); + cal.setTime(date); + + String lcase = text.toLowerCase(); + + if (lcase.startsWith("today", pos.getIndex())) + { + pos.setIndex(pos.getIndex() + 5); + if (pos instanceof ParsePositionEx) + { + ((ParsePositionEx) pos).getFeatures().put("inferred", ALL); + ((ParsePositionEx) pos).getFeatures().put("accurate", ALL); + } + return cal; + } + else if (lcase.startsWith("tomorrow", pos.getIndex())) + { + pos.setIndex(pos.getIndex() + 8); + cal.add(Calendar.DATE, 1); + if (pos instanceof ParsePositionEx) + { + ((ParsePositionEx) pos).getFeatures().put("inferred", ALL); + ((ParsePositionEx) pos).getFeatures().put("accurate", ALL); + } + return cal; + } + else if (lcase.startsWith("yesterday", pos.getIndex())) + { + pos.setIndex(pos.getIndex() + 9); + cal.add(Calendar.DATE, -1); + if (pos instanceof ParsePositionEx) + { + ((ParsePositionEx) pos).getFeatures().put("inferred", ALL); + ((ParsePositionEx) pos).getFeatures().put("accurate", ALL); + } + return cal; + } + else if (lcase.startsWith("previous day", pos.getIndex())) + { + pos.setIndex(pos.getIndex() + 12); + cal.add(Calendar.DATE, -1); + if (pos instanceof ParsePositionEx) + { + ((ParsePositionEx) pos).getFeatures().put("inferred", ALL); + ((ParsePositionEx) pos).getFeatures().put("accurate", ALL); + } + return cal; + } + else if (lcase.startsWith("last week", pos.getIndex())) + { + pos.setIndex(pos.getIndex() + 9); + cal.add(Calendar.WEEK_OF_YEAR, -1); + cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek()); + if (pos instanceof ParsePositionEx) + { + ((ParsePositionEx) pos).getFeatures().put("inferred", ALL); + ((ParsePositionEx) pos).getFeatures().put("accurate", YEAR | MONTH); + } + return cal; + } + else if (lcase.startsWith("next week", pos.getIndex())) + { + pos.setIndex(pos.getIndex() + 9); + cal.add(Calendar.WEEK_OF_YEAR, 1); + cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek()); + if (pos instanceof ParsePositionEx) + { + ((ParsePositionEx) pos).getFeatures().put("inferred", ALL); + ((ParsePositionEx) pos).getFeatures().put("accurate", YEAR | MONTH); + } + return cal; + } + else if (lcase.startsWith("last month", pos.getIndex())) + { + pos.setIndex(pos.getIndex() + 10); + cal.add(Calendar.MONTH, -1); + cal.set(Calendar.DAY_OF_MONTH, 1); + if (pos instanceof ParsePositionEx) + { + ((ParsePositionEx) pos).getFeatures().put("inferred", ALL); + ((ParsePositionEx) pos).getFeatures().put("accurate", YEAR | MONTH); + } + return cal; + } + else if (lcase.startsWith("next month", pos.getIndex())) + { + pos.setIndex(pos.getIndex() + 10); + cal.add(Calendar.MONTH, 1); + cal.set(Calendar.DAY_OF_MONTH, 1); + if (pos instanceof ParsePositionEx) + { + ((ParsePositionEx) pos).getFeatures().put("inferred", ALL); + ((ParsePositionEx) pos).getFeatures().put("accurate", YEAR | MONTH); + } + return cal; + } + else if (lcase.startsWith("last year", pos.getIndex())) + { + pos.setIndex(pos.getIndex() + 9); + cal.add(Calendar.YEAR, -1); + cal.set(Calendar.DAY_OF_MONTH, 1); + cal.set(Calendar.MONTH, 0); + if (pos instanceof ParsePositionEx) + { + ((ParsePositionEx) pos).getFeatures().put("inferred", ALL); + ((ParsePositionEx) pos).getFeatures().put("accurate", YEAR); + } + return cal; + } + else if (lcase.startsWith("next year", pos.getIndex())) + { + pos.setIndex(pos.getIndex() + 9); + cal.add(Calendar.YEAR, 1); + cal.set(Calendar.DAY_OF_MONTH, 1); + cal.set(Calendar.MONTH, 0); + if (pos instanceof ParsePositionEx) + { + ((ParsePositionEx) pos).getFeatures().put("inferred", ALL); + ((ParsePositionEx) pos).getFeatures().put("accurate", YEAR); + } + return cal; + } + + // 31st August 1979 + Matcher m = p[0].matcher(text); + + if (m.find(pos.getIndex()) && checkPosition(m.start(), pos.getIndex())) + { + try + { + if (m.group(1) != null) parseWeekday(m.group(1)); + + int day = Integer.parseInt(m.group(2)); + int month = parseMonth(m.group(3)); + int year = checkYear(Integer.parseInt(m.group(4))); + + checkMonthAndDay(month, day); + + pos.setIndex(m.end()); + + cal.set(year, month, day); + if (pos instanceof ParsePositionEx) + { + ((ParsePositionEx) pos).getFeatures().put("inferred", NONE); + ((ParsePositionEx) pos).getFeatures().put("accurate", ALL); + } + return cal; + } + catch (Exception e) + {} + } + + // 31st August + m = p[1].matcher(text); + + if (m.find(pos.getIndex()) && checkPosition(m.start(), pos.getIndex())) + { + try + { + if (m.group(1) != null) parseWeekday(m.group(1)); + + int day = Integer.parseInt(m.group(2)); + int month = parseMonth(m.group(3)); + + checkMonthAndDay(month, day); + + pos.setIndex(m.end()); + + cal.set(cal.get(Calendar.YEAR), month, day); + if (pos instanceof ParsePositionEx) + { + ((ParsePositionEx) pos).getFeatures().put("inferred", YEAR); + ((ParsePositionEx) pos).getFeatures().put("accurate", ALL); + } + return cal; + } + catch (Exception e) + {} + } + + // August 31st 1979 + m = p[2].matcher(text); + + if (m.find(pos.getIndex()) && checkPosition(m.start(), pos.getIndex())) + { + try + { + if (m.group(1) != null) parseWeekday(m.group(1)); + + int day = Integer.parseInt(m.group(3)); + int month = parseMonth(m.group(2)); + int year = checkYear(Integer.parseInt(m.group(4))); + + checkMonthAndDay(month, day); + + pos.setIndex(m.end()); + + cal.set(year, month, day); + if (pos instanceof ParsePositionEx) + { + ((ParsePositionEx) pos).getFeatures().put("inferred", NONE); + ((ParsePositionEx) pos).getFeatures().put("accurate", ALL); + } + return cal; + } + catch (Exception e) + {} + } + + // August 31st + m = p[3].matcher(text); + + if (m.find(pos.getIndex()) && checkPosition(m.start(), pos.getIndex())) + { + try + { + if (m.group(1) != null) parseWeekday(m.group(1)); + + int day = Integer.parseInt(m.group(3)); + int month = parseMonth(m.group(2)); + + checkMonthAndDay(month, day); + + pos.setIndex(m.end()); + + cal.set(cal.get(Calendar.YEAR), month, day); + if (pos instanceof ParsePositionEx) + { + ((ParsePositionEx) pos).getFeatures().put("inferred", YEAR); + ((ParsePositionEx) pos).getFeatures().put("accurate", ALL); + } + return cal; + } + catch (Exception e) + {} + } + + // 08/31/1979 + m = p[4].matcher(text); + + if (m.find(pos.getIndex()) && checkPosition(m.start(), pos.getIndex())) + { + try + { + int day = (monthFirst ? Integer.parseInt(m.group(2)) : Integer.parseInt(m.group(1))); + int month = (monthFirst ? Integer.parseInt(m.group(1)) - 1 : Integer.parseInt(m.group(2)) - 1); + int year = checkYear(Integer.parseInt(m.group(3))); + + checkMonthAndDay(month, day); + + pos.setIndex(m.end()); + + cal.set(year, month, day); + if (pos instanceof ParsePositionEx) + { + ((ParsePositionEx) pos).getFeatures().put("inferred", NONE); + ((ParsePositionEx) pos).getFeatures().put("accurate", ALL); + } + return cal; + } + catch (Exception e) + {} + } + + // 1979-08-31 + m = p[5].matcher(text); + + if (m.find(pos.getIndex()) && checkPosition(m.start(), pos.getIndex())) + { + try + { + int day = Integer.parseInt(m.group(3)); + int month = Integer.parseInt(m.group(2)) - 1; + int year = Integer.parseInt(m.group(1)); + + checkMonthAndDay(month, day); + + pos.setIndex(m.end()); + + cal.set(year, month, day); + if (pos instanceof ParsePositionEx) + { + ((ParsePositionEx) pos).getFeatures().put("inferred", NONE); + ((ParsePositionEx) pos).getFeatures().put("accurate", ALL); + } + return cal; + } + catch (Exception e) + {} + } + + // 31-Aug-1979 + m = p[6].matcher(text); + + if (m.find(pos.getIndex()) && checkPosition(m.start(), pos.getIndex())) + { + try + { + int day = Integer.parseInt(m.group(1)); + int month = parseMonth(m.group(2)); + int year = checkYear(Integer.parseInt(m.group(3))); + + checkMonthAndDay(month, day); + + pos.setIndex(m.end()); + + cal.set(year, month, day); + if (pos instanceof ParsePositionEx) + { + ((ParsePositionEx) pos).getFeatures().put("inferred", NONE); + ((ParsePositionEx) pos).getFeatures().put("accurate", ALL); + } + return cal; + } + catch (Exception e) + {} + } + + // last Tuesday + m = p[7].matcher(text); + + if (m.find(pos.getIndex()) && checkPosition(m.start(), pos.getIndex())) + { + try + { + int weekday = parseWeekday(m.group(1)); + pos.setIndex(m.end()); + + cal.set(Calendar.DAY_OF_WEEK, weekday); + + // TODO should we always roll back or not? + // I guess this will depend on where in the week we are in + // relation to the day mentioned + cal.add(Calendar.WEEK_OF_MONTH, -1); + if (pos instanceof ParsePositionEx) + { + ((ParsePositionEx) pos).getFeatures().put("inferred", ALL); + ((ParsePositionEx) pos).getFeatures().put("accurate", ALL); + } + return cal; + } + catch (Exception e) + {} + } + + // next Wednesday + m = p[8].matcher(text); + + if (m.find(pos.getIndex()) && checkPosition(m.start(), pos.getIndex())) + { + try + { + int weekday = parseWeekday(m.group(1)); + pos.setIndex(m.end()); + + cal.set(Calendar.DAY_OF_WEEK, weekday); + + // TODO should we always roll forward or not? + // I guess this will depend on where in the week we are in + // relation to the day mentioned + cal.add(Calendar.WEEK_OF_MONTH, 1); + if (pos instanceof ParsePositionEx) + { + ((ParsePositionEx) pos).getFeatures().put("inferred", ALL); + ((ParsePositionEx) pos).getFeatures().put("accurate", ALL); + } + return cal; + } + catch (Exception e) + {} + } + + // July 2009 + // August '08 + m = p[9].matcher(text); + + if (m.find(pos.getIndex()) && checkPosition(m.start(), pos.getIndex())) + { + try + { + int month = parseMonth(m.group(1)); + int year = checkYear(Integer.parseInt(m.group(2))); + + checkMonthAndDay(month, 1); + + pos.setIndex(m.end()); + + cal.set(year, month, 1); + if (pos instanceof ParsePositionEx) + { + ((ParsePositionEx) pos).getFeatures().put("inferred", DAY); + ((ParsePositionEx) pos).getFeatures().put("accurate", YEAR | MONTH); + } + + return cal; + } + catch (Exception e) + {} + } + + m = p[10].matcher(text); + + if (m.find(pos.getIndex()) && checkPosition(m.start(), pos.getIndex())) + { + try + { + int goBack = Integer.parseInt(m.group(1)) * -1; + + String amount = m.group(2).toLowerCase(); + + boolean found = false; + + if (amount.equals("days") || amount.equals("day")) + { + cal.add(Calendar.DATE, goBack); + if (pos instanceof ParsePositionEx) ((ParsePositionEx) pos).getFeatures().put("accurate", ALL); + found = true; + } + else if (amount.equals("weeks") || amount.equals("week")) + { + cal.add(Calendar.WEEK_OF_YEAR, goBack); + cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek()); + if (pos instanceof ParsePositionEx) ((ParsePositionEx) pos).getFeatures().put("accurate", YEAR | MONTH); + found = true; + } + else if (amount.equals("months") || amount.equals("month")) + { + cal.add(Calendar.MONTH, goBack); + cal.set(Calendar.DAY_OF_MONTH, 1); + if (pos instanceof ParsePositionEx) ((ParsePositionEx) pos).getFeatures().put("accurate", YEAR | MONTH); + found = true; + } + else if (amount.equals("years") || amount.equals("year")) + { + cal.add(Calendar.YEAR, goBack); + cal.set(Calendar.DAY_OF_YEAR, 1); + if (pos instanceof ParsePositionEx) ((ParsePositionEx) pos).getFeatures().put("accurate", YEAR); + found = true; + } + + if (found) + { + if (pos instanceof ParsePositionEx) ((ParsePositionEx) pos).getFeatures().put("inferred", ALL); + pos.setIndex(m.end()); + return cal; + } + } + catch (RuntimeException e) + { + //none of this can throw a checked exception so only look for runtime problems + } + } + + m = p[11].matcher(text); + + if (m.find(pos.getIndex()) && checkPosition(m.start(), pos.getIndex())) + { + try + { + int day = Integer.parseInt(m.group(3)); + int month = parseMonth(m.group(2)); + int year = checkYear(Integer.parseInt(m.group(1))); + + if (m.group(4) != null) parseWeekday(m.group(4)); + + checkMonthAndDay(month, day); + + pos.setIndex(m.end()); + + cal.set(year, month, day); + if (pos instanceof ParsePositionEx) + { + ((ParsePositionEx) pos).getFeatures().put("inferred", NONE); + ((ParsePositionEx) pos).getFeatures().put("accurate", ALL); + } + return cal; + } + catch (Exception e) + { + + } + + try + { + int day = Integer.parseInt(m.group(3)); + int month = parseMonth(m.group(2)); + int year = checkYear(Integer.parseInt(m.group(1))); + + checkMonthAndDay(month, day); + + pos.setIndex(m.end(3)); + + cal.set(year, month, day); + if (pos instanceof ParsePositionEx) + { + ((ParsePositionEx) pos).getFeatures().put("inferred", NONE); + ((ParsePositionEx) pos).getFeatures().put("accurate", ALL); + } + return cal; + } + catch (Exception e) + { + + } + } + + m = p[12].matcher(text); + + if (m.find(pos.getIndex()) && checkPosition(m.start(), pos.getIndex())) + { + try + { + int day = Integer.parseInt(m.group(2)); + int month = parseMonth(m.group(1)); + int year = checkYear(Integer.parseInt(m.group(3))); + + checkMonthAndDay(month, day); + + pos.setIndex(m.end()); + + cal.set(year, month, day); + if (pos instanceof ParsePositionEx) + { + ((ParsePositionEx) pos).getFeatures().put("inferred", NONE); + ((ParsePositionEx) pos).getFeatures().put("accurate", ALL); + } + return cal; + } + catch (Exception e) + { + + } + } + + //TODO think about mentions of just a month or day of week -- have to be careful with "may" + m = p[13].matcher(text); + + if (m.find(pos.getIndex()) && checkPosition(m.start(), pos.getIndex())) + { + try + { + int weekday = parseWeekday(m.group(1)); + pos.setIndex(m.end()); + + cal.set(Calendar.DAY_OF_WEEK, weekday); + + if (pos instanceof ParsePositionEx) + { + ((ParsePositionEx) pos).getFeatures().put("inferred", ALL); + ((ParsePositionEx) pos).getFeatures().put("accurate", NONE); + } + + return cal; + } + catch (Exception e) + { + + } + + try + { + int month = parseMonth(m.group(1)); + if (!m.group(1).toLowerCase().equals(m.group(1))) + { + pos.setIndex(m.end()); + + cal.set(cal.get(Calendar.YEAR), month, 1); + + if (pos instanceof ParsePositionEx) + { + ((ParsePositionEx) pos).getFeatures().put("inferred", DAY | YEAR); + ((ParsePositionEx) pos).getFeatures().put("accurate", MONTH); + } + + return cal; + } + } + catch (Exception e) + { + + } + } + + return null; + } + + private int checkYear(int year) + { + if (year < 100) + { + if (year > yearIn) year -= 100; + + year += century; + } + + return year; + } + + private boolean checkPosition(int found, int requested) + { + return requested == found; + } + + private boolean checkMonthAndDay(int month, int day) throws Exception + { + if (month < 0 || month > 11) throw new Exception("month outside valid range"); + + if (day < 1 || day > 31) throw new Exception("day of month outside valid range"); + + return true; + } + + private static List<String> arrayToList(String[] array) + { + List<String> data = new ArrayList<String>(); + + for (int i = 0; i < array.length; ++i) + data.add(array[i].toLowerCase()); + + return data; + } + + private int parseMonth(String month) throws Exception + { + String lcm = month.toLowerCase(); + + if (months.contains(lcm)) return months.indexOf(lcm); + if (shortMonths.contains(lcm)) return shortMonths.indexOf(lcm); + + throw new Exception("Invalid Month String: " + month); + } + + private int parseWeekday(String weekday) throws Exception + { + String lcw = weekday.toLowerCase(); + + if (weekdays.contains(lcw)) return weekdays.indexOf(lcw); + if (shortWeekdays.contains(lcw)) return shortWeekdays.indexOf(lcw); + + throw new Exception("Invalid Weekday String: " + weekday); + } + + private int parseEra(String era) throws Exception + { + String lce = era.toLowerCase(); + + if (eras.contains(lce)) return eras.indexOf(lce); + + throw new Exception("Invalid Era String: " + era); + } + + public static Locale getLocale(String name) + { + if (name == null || name.trim().equals("")) return null; + + String[] parts = name.split("_"); + + Locale locale = null; + + if (parts.length == 1) + { + locale = new Locale(parts[0]); + } + else if (parts.length == 2) + { + locale = new Locale(parts[0], parts[1]); + } + else if (parts.length == 3) + { + locale = new Locale(parts[0], parts[1], parts[2]); + } + + if (locale == null) return null; + + return (locale.toString().equals(name) ? locale : null); + } + + /** + * Returns the set of words that can occur within dates. This includes the + * days of the week and months of the year as well as words such as today, + * tomorrow etc. This is provided in order to help users of this parser find + * the approximate location of dates within text in order to cut down on + * parsing time. + * @return the set of words which may occur within dates + */ + public Set<String> getWords() + { + Set<String> words = new HashSet<String>(); + + words.addAll(weekdays); + words.addAll(shortWeekdays); + words.addAll(months); + words.addAll(shortMonths); + + //THESE should be loaded from a resource bundle of some form + words.add("last"); + words.add("next"); + words.add("previous"); + words.add("today"); + words.add("tomorrow"); + words.add("yesterday"); + + return words; + } +} Added: gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/main/java/mark/util/ParsePositionEx.java =================================================================== --- gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/main/java/mark/util/ParsePositionEx.java (rev 0) +++ gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/main/java/mark/util/ParsePositionEx.java 2016-12-20 23:15:07 UTC (rev 19884) @@ -0,0 +1,118 @@ +/** + * Copyright (C) 2004-2010, Mark A. Greenwood + * + * This file is part of GATE (see http://gate.ac.uk/), and is free software, + * licenced under the GNU Library General Public License, Version 3, June 2007 + * (in the distribution as file licence.html, and also available at + * http://gate.ac.uk/gate/licence.html). + */ + +package mark.util; + +import java.text.ParsePosition; +import java.util.HashMap; +import java.util.Map; + +/** + * Extends the standard ParsePosition class to allow arbitrary key/value pairs + * to be associated with the current parse position. This is useful to allow the + * reporting of parse related information over and above the value that has + * actually been parsed and will be returned. + * @author Mark A. Greenwood + */ +public class ParsePositionEx extends ParsePosition +{ + /** + * A map to hold the key/value pairs that provide the extra + * functionallity not found in ParsePosition + */ + private Map<String, Object> features = new HashMap<String, Object>(); + + @Override + public int hashCode() + { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((features == null) ? 0 : features.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) return true; + if (!super.equals(obj)) return false; + if (getClass() != obj.getClass()) return false; + ParsePositionEx other = (ParsePositionEx) obj; + + if (features == null) + { + if (other.features != null) return false; + } + else if (!features.equals(other.features)) { return false; } + + return true; + } + + /** + * Create a new instance which starts parsing from 0 + */ + public ParsePositionEx() + { + super(0); + } + + /** + * Create a new instance with a given starting position + * @param index the index from which to start parsing + */ + public ParsePositionEx(int index) + { + super(index); + } + + /** + * Create a new instance with a given starting position and an initial + * set of features. + * @param index the index from which to start parsing + * @param features the initial features to associate with the parse + */ + public ParsePositionEx(int index, Map<String, Object> features) + { + super(index); + this.features.putAll(features); + } + + /** + * Returns the map of features associated with this point in the parse + * @return The map of features associated with this point in the parse + */ + public Map<String, Object> getFeatures() + { + return features; + } + + /** + * Resets this instance to have a zero index and no feature. Useful for + * allowing easy reuse of an instance when parsing multiple strings + * @param index the index at which to start parsing at next time + * @return the reset instance + */ + public ParsePositionEx reset(int index) + { + setIndex(index); + features.clear(); + + return this; + } + + /** + * Resets this instance to have a zero index and no feature. Useful for + * allowing easy reuse of an instance when parsing multiple strings + * @return the reset instance + */ + public ParsePositionEx reset() + { + return reset(0); + } +} Copied: gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/main/resources/creole.xml (from rev 19883, gate/branches/sawdust2/plugins/Tagger_DateNormalizer/creole.xml) =================================================================== --- gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/main/resources/creole.xml (rev 0) +++ gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/main/resources/creole.xml 2016-12-20 23:15:07 UTC (rev 19884) @@ -0,0 +1,3 @@ +<CREOLE-DIRECTORY> + +</CREOLE-DIRECTORY> Added: gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/test/java/mark/util/DateParserTest.java =================================================================== --- gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/test/java/mark/util/DateParserTest.java (rev 0) +++ gate/branches/sawdust2/plugins/Tagger_DateNormalizer/src/test/java/mark/util/DateParserTest.java 2016-12-20 23:15:07 UTC (rev 19884) @@ -0,0 +1,367 @@ +/** + * This file is part of DateParser. + * Copyright (C) 2004-2010, Mark A. Greenwood + * + * DateParser is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * DateParser is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with DateParser. If not, see <http://www.gnu.org/licenses/>. + **/ + +package mark.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * @author Mark A. Greenwood + */ +public class DateParserTest +{ + private static DateParser parser = null; + private static DateFormat df = null; + + @BeforeClass + public static void setUp() + { + parser = new DateParser(Locale.UK); + df = new SimpleDateFormat("dd/MM/yyyy"); + } + + @AfterClass + public static void tearDown() + { + parser = null; + df = null; + } + + @Test + public void testToday() + { + ParsePositionEx pp = new ParsePositionEx(0); + Date d = parser.parse("today", pp); + + assertNotNull(d); + + String formatted = df.format(d); + String today = df.format(new Date()); + + assertEquals(today, formatted); + assertEquals(pp.getIndex(), 5); + assertEquals(pp.getFeatures().get("relative"), "present"); + } + + @Test + public void testCapitalizedToday() + { + ParsePositionEx pp = new ParsePositionEx(0); + Date d = parser.parse("Today", pp); + + assertNotNull(d); + + String formatted = df.format(d); + String today = df.format(new Date()); + + assertEquals(today, formatted); + assertEquals(pp.getIndex(), 5); + assertEquals(pp.getFeatures().get("relative"), "present"); + } + + @Test + public void testTomorrow() + { + @SuppressWarnings("deprecation") Date today = new Date(2000 - 1900, 11, 31); + + ParsePositionEx pp = new ParsePositionEx(0); + + Date tomorrow = parser.parse("tomorrow", pp, today); + + assertNotNull(tomorrow); + + String sTomorrow = df.format(tomorrow); + + assertEquals(sTomorrow, "01/01/2001"); + assertEquals(pp.getIndex(), 8); + assertEquals(pp.getFeatures().get("relative"), "future"); + } + + @Test + public void testYesterday() + { + @SuppressWarnings("deprecation") Date today = new Date(2001 - 1900, 0, 1); + + ParsePositionEx pp = new ParsePositionEx(0); + + Date yesterday = parser.parse("yesterday", pp, today); + + assertNotNull(yesterday); + + String date = df.format(yesterday); + + assertEquals(date, "31/12/2000"); + assertEquals(pp.getIndex(), 9); + assertEquals(pp.getFeatures().get("relative"), "past"); + } + + @Test + public void testPreviousDay() + { + @SuppressWarnings("deprecation") Date today = new Date(2001 - 1900, 0, 1); + + ParsePositionEx pp = new ParsePositionEx(0); + + Date yesterday = parser.parse("previous day", pp, today); + + assertNotNull(yesterday); + + String date = df.format(yesterday); + + assertEquals(date, "31/12/2000"); + assertEquals(pp.getIndex(), 12); + assertEquals(pp.getFeatures().get("relative"), "past"); + } + + @Test + public void testLastYear() + { + @SuppressWarnings("deprecation") Date today = new Date(2001 - 1900, 7, 31); + + ParsePositionEx pp = new ParsePositionEx(0); + Date lastYear = parser.parse("last year", pp, today); + + assertNotNull(lastYear); + + String date = df.format(lastYear); + + assertEquals(pp.getIndex(), 9); + assertEquals(date, "01/01/2000"); + } + + @Test + public void testNextYear() + { + @SuppressWarnings("deprecation") Date today = new Date(2001 - 1900, 7, 31); + + ParsePositionEx pp = new ParsePositionEx(0); + Date nextYear = parser.parse("next year", pp, today); + + assertNotNull(nextYear); + + String date = df.format(nextYear); + + assertEquals(pp.getIndex(), 9); + assertEquals(date, "01/01/2002"); + } + + @Test + public void testLastMonth() + { + @SuppressWarnings("deprecation") Date today = new Date(2001 - 1900, 0, 7); + + ParsePositionEx pp = new ParsePositionEx(0); + Date lastMonth = parser.parse("last month", pp, today); + + assertNotNull(lastMonth); + + String date = df.format(lastMonth); + + assertEquals(pp.getIndex(), 10); + assertEquals(date, "01/12/2000"); + } + + @Test + public void testNextMonth() + { + @SuppressWarnings("deprecation") Date today = new Date(2001 - 1900, 11, 7); + + ParsePositionEx pp = new ParsePositionEx(0); + Date nextMonth = parser.parse("next month", pp, today); + + assertNotNull(nextMonth); + + String date = df.format(nextMonth); + + assertEquals(pp.getIndex(), 10); + assertEquals(date, "01/01/2002"); + } + + @Test + public void testMonthsAgo() + { + @SuppressWarnings("deprecation") Date today = new Date(2001 - 1900, 0, 1); + + ParsePositionEx pp = new ParsePositionEx(0); + Date before = parser.parse("3 months ago", pp, today); + + assertNotNull(before); + + String sTomorrow = df.format(before); + + assertEquals(pp.getIndex(), 12); + assertEquals(sTomorrow, "01/10/2000"); + } + + @Test + public void testFullDateSlash() + { + ParsePositionEx pp = new ParsePositionEx(0); + Date date = parser.parse("31/8/79", pp); + + assertNotNull(date); + + assertEquals(pp.getIndex(), 7); + assertEquals(df.format(date), "31/08/1979"); + } + + @Test + public void testFullDateDash() + { + ParsePositionEx pp = new ParsePositionEx(0); + Date date = parser.parse("31-8-79", pp); + + assertNotNull(date); + + assertEquals(pp.getIndex(), 7); + assertEquals(df.format(date), "31/08/1979"); + } + + @Test + public void testDayOfMonthYear() + { + ParsePositionEx pp = new ParsePositionEx(0); + Date date = parser.parse("31st of August 1979", pp); + + assertNotNull(date); + + assertEquals(pp.getIndex(), 19); + assertEquals(df.format(date), "31/08/1979"); + } + + @Test + public void testFullDateDot() + { + ParsePositionEx pp = new ParsePositionEx(0); + Date date = parser.parse("31.08.79", pp); + + assertNotNull(date); + + assertEquals(pp.getIndex(), 8); + assertEquals(df.format(date), "31/08/1979"); + } + + @Test + public void testInvlaidMonthAndDay() + { + Date date = parser.parse("27-34-55", new ParsePositionEx(0), null); + + assertNull(date); + } + + @Test + public void testMonthYear() + { + @SuppressWarnings("deprecation") Date today = new Date(2001 - 1900, 2, 7); + + ParsePositionEx pp = new ParsePositionEx(0); + Date date = parser.parse("January 2005", pp, today); + + assertNotNull(date); + + assertEquals(pp.getIndex(), 12); + assertEquals(df.format(date), "01/01/2005"); + } + + @Test + public void testBigEndian() + { + ParsePositionEx pp = new ParsePositionEx(0); + Date date = parser.parse("2003Nov9", pp, null); + + assertNotNull(date); + + assertEquals(pp.getIndex(), 8); + assertEquals(df.format(date), "09/11/2003"); + } + + @Test + public void testBigEndianWithWeekday() + { + ParsePositionEx pp = new ParsePositionEx(0); + Date date = parser.parse("2003-Nov-9, Sunday", pp, null); + + assertNotNull(date); + + assertEquals(pp.getIndex(), 18); + assertEquals(df.format(date), "09/11/2003"); + } + + @Test + public void testMiddleEndian() + { + ParsePositionEx pp = new ParsePositionEx(0); + Date date = parser.parse("Nov/9/2003", pp, null); + + assertNotNull(date); + + assertEquals(pp.getIndex(), 10); + assertEquals(df.format(date), "09/11/2003"); + } + + @Test + public void testMonthOnly() + { + @SuppressWarnings("deprecation") Date today = new Date(2001 - 1900, 2, 7); + + ParsePositionEx pp = new ParsePositionEx(0); + Date date = parser.parse("August", pp, today); + + assertNotNull(date); + + assertEquals(pp.getIndex(), 6); + assertEquals(df.format(date), "01/08/2001"); + } + + @Test + public void testWeekdayOnly() + { + @SuppressWarnings("deprecation") Date today = new Date(2001 - 1900, 2, 7); + + ParsePositionEx pp = new ParsePositionEx(0); + Date date = parser.parse("Sunday", pp, today); + + assertNotNull(date); + + assertEquals(pp.getIndex(), 6); + assertEquals(df.format(date), "11/03/2001"); + } + + @Test + public void testJDBCTimestamp() + { + ParsePositionEx pp = new ParsePositionEx(0); + Date date = parser.parse("2013-02-25 12:03:35.6", pp); + + assertNotNull(date); + + assertEquals(pp.getIndex(), 10); + assertEquals(df.format(date), "25/02/2013"); + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Developer Access Program for Intel Xeon Phi Processors Access to Intel Xeon Phi processor-based developer platforms. With one year of Intel Parallel Studio XE. Training and support from Colfax. Order your platform today.http://sdm.link/intel _______________________________________________ GATE-cvs mailing list GATE-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/gate-cvs