package edu.stanford.nlp.time; import edu.stanford.nlp.ling.CoreAnnotations; import edu.stanford.nlp.pipeline.*; import edu.stanford.nlp.util.CoreMap; import org.junit.Assert; import junit.framework.TestCase; import java.io.IOException; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; public class SUTimeITest extends TestCase { private static AnnotationPipeline pipeline = null; private static final String TIME_ANNOTATOR_NAME = "sutime"; @Override public void setUp() throws Exception { synchronized(SUTimeITest.class) { if (pipeline == null) { pipeline = new AnnotationPipeline(); pipeline.addAnnotator(new TokenizerAnnotator(false, "en")); pipeline.addAnnotator(new WordsToSentencesAnnotator(false)); pipeline.addAnnotator(new POSTaggerAnnotator(DefaultPaths.DEFAULT_POS_MODEL, false)); //pipeline.addAnnotator(new NumberAnnotator(false)); //pipeline.addAnnotator(new QuantifiableEntityNormalizingAnnotator(false, false)); } } } protected static Properties getDefaultProperties() { Properties props = new Properties(); // props.setProperty(TIME_ANNOTATOR_NAME + ".verbose", "true"); return props; } private static TimeAnnotator getTimeAnnotator() { return new TimeAnnotator(TIME_ANNOTATOR_NAME, getDefaultProperties()); } private static TimeAnnotator getTimeAnnotator(Properties props) { return new TimeAnnotator(TIME_ANNOTATOR_NAME, props); } // TODO: better to have file of test text, and expected results? public void testSUTimeDurations() throws IOException { // Set up test text String testText = "It was a 3-year long drought.\n" + "The four-month old baby slept peacefully.\n" + "Over the past twenty four years, the number of crashes has decreased.\n" + // following the crash not included (TODO in perl) "In the 2 months following the crash, the investigators checked all the records.\n" + // before leaving not included (TODO in perl) "He was preoccupied for ten days before leaving.\n" + "Sales rose for the fifth straight year.\n" + "Business was slow for the third straight month in a row.\n" + "There are no more than 60 days.\n" + "In no more than 20 years, the city completely changed.\n" + "It has been more than 60 days.\n" + "Has it been more than 20 years?\n" + "There was at least sixty days.\n" + "The book was completed in four years.\n" + "That took a decade.\n" + "After a few decades, old memories faded.\n" + "After a few hundred decades, everything changed.\n" + "It has been warm in recent weeks.\n" + "Did it rain on the ninth day consecutively?\n" + "The meeting was two days ago.\n"; // set up expected results Iterator<Timex> expectedTimexes = Arrays.asList(Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"P3Y\" type=\"DURATION\">3-year</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"P4M\" type=\"DURATION\">four-month old</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"P24Y\" type=\"DURATION\" beginPoint=\"t3\" endPoint=\"t0\">the past twenty four years</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t5\" value=\"P2M\" type=\"DURATION\">the 2 months</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t6\" value=\"P10D\" type=\"DURATION\">ten days</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t8\" value=\"P5Y\" type=\"DURATION\" beginPoint=\"t7\" endPoint=\"t0\">the fifth straight year</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t10\" value=\"P3M\" type=\"DURATION\" beginPoint=\"t9\" endPoint=\"t0\">the third straight month in a row</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t11\" value=\"P60D\" type=\"DURATION\" mod=\"EQUAL_OR_LESS\">no more than 60 days</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t12\" value=\"P20Y\" type=\"DURATION\" mod=\"EQUAL_OR_LESS\">no more than 20 years</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t13\" value=\"P60D\" type=\"DURATION\" mod=\"MORE_THAN\">more than 60 days</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t14\" value=\"P20Y\" type=\"DURATION\" mod=\"MORE_THAN\">more than 20 years</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t15\" value=\"P60D\" type=\"DURATION\" mod=\"EQUAL_OR_MORE\">at least sixty days</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t16\" value=\"P4Y\" type=\"DURATION\">four years</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t17\" value=\"P10Y\" type=\"DURATION\">a decade</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t18\" value=\"PXY\" type=\"DURATION\">a few decades</TIMEX3>"), // TODO: Expect PX0Y? Timex.fromXml("<TIMEX3 tid=\"t19\" value=\"P1000Y\" type=\"DURATION\">hundred decades</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t20\" value=\"PXW\" type=\"DURATION\">recent weeks</TIMEX3>"), // TODO: Expect PXD? Timex.fromXml("<TIMEX3 tid=\"t22\" value=\"P9D\" type=\"DURATION\" beginPoint=\"t21\" endPoint=\"t0\">the ninth day consecutively</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t23\" alt_value=\"OFFSET P-2D\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf0\" anchorTimeID=\"t0\">two days ago</TIMEX3>") ).iterator(); Iterator<Timex> expectedTimexesResolved = Arrays.asList(Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"P3Y\" type=\"DURATION\">3-year</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"P4M\" type=\"DURATION\">four-month old</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"P24Y\" type=\"DURATION\" beginPoint=\"t3\" endPoint=\"t0\">the past twenty four years</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t5\" value=\"P2M\" type=\"DURATION\">the 2 months</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t6\" value=\"P10D\" type=\"DURATION\">ten days</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t8\" value=\"P5Y\" type=\"DURATION\" beginPoint=\"t7\" endPoint=\"t0\">the fifth straight year</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t10\" value=\"P3M\" type=\"DURATION\" beginPoint=\"t9\" endPoint=\"t0\">the third straight month in a row</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t11\" value=\"P60D\" type=\"DURATION\" mod=\"EQUAL_OR_LESS\">no more than 60 days</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t12\" value=\"P20Y\" type=\"DURATION\" mod=\"EQUAL_OR_LESS\">no more than 20 years</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t13\" value=\"P60D\" type=\"DURATION\" mod=\"MORE_THAN\">more than 60 days</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t14\" value=\"P20Y\" type=\"DURATION\" mod=\"MORE_THAN\">more than 20 years</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t15\" value=\"P60D\" type=\"DURATION\" mod=\"EQUAL_OR_MORE\">at least sixty days</TIMEX3>"), // Timex.fromXml("<TIMEX3 tid=\"t12\" value=\"P60D\" type=\"DURATION\" mod=\"EQUAL_OR_LESS\" beginPoint=\"t0\" endPoint=\"t11\">no more than 60 days</TIMEX3>"), // Timex.fromXml("<TIMEX3 tid=\"t14\" value=\"P20Y\" type=\"DURATION\" mod=\"EQUAL_OR_LESS\" beginPoint=\"t0\" endPoint=\"t13\">no more than 20 years</TIMEX3>"), // Timex.fromXml("<TIMEX3 tid=\"t16\" value=\"P60D\" type=\"DURATION\" mod=\"MORE_THAN\" beginPoint=\"t0\" endPoint=\"t15\">more than 60 days</TIMEX3>"), // Timex.fromXml("<TIMEX3 tid=\"t18\" value=\"P20Y\" type=\"DURATION\" mod=\"MORE_THAN\" beginPoint=\"t0\" endPoint=\"t17\">more than 20 years</TIMEX3>"), // Timex.fromXml("<TIMEX3 tid=\"t20\" value=\"P60D\" type=\"DURATION\" mod=\"EQUAL_OR_MORE\" beginPoint=\"t0\" endPoint=\"t19\">at least sixty days</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t16\" value=\"P4Y\" type=\"DURATION\">four years</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t17\" value=\"P10Y\" type=\"DURATION\">a decade</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t18\" value=\"PXY\" type=\"DURATION\">a few decades</TIMEX3>"), // TODO: Expect PX0Y? Timex.fromXml("<TIMEX3 tid=\"t19\" value=\"P1000Y\" type=\"DURATION\">hundred decades</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t20\" value=\"PXW\" type=\"DURATION\">recent weeks</TIMEX3>"), // TODO: Expect PXD? Timex.fromXml("<TIMEX3 tid=\"t22\" value=\"P9D\" type=\"DURATION\" beginPoint=\"t21\" endPoint=\"t0\">the ninth day consecutively</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t23\" value=\"2010-02-15\" type=\"DATE\">two days ago</TIMEX3>")).iterator(); // create document Annotation document = createDocument(testText); // Time annotate TimeAnnotator sutime = getTimeAnnotator(); sutime.annotate(document); // Check answers for (CoreMap timexAnn: document.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexes.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } Annotation documentWithRefTime = createDocument(testText, "20100217"); sutime.annotate(documentWithRefTime); for (CoreMap timexAnn: documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexesResolved.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } } public void testSUTimeDurations2() throws IOException { // Following should be improved... String testText = // of 1997 not included as part of duration... (TODO in perl) "He was away for the first 9 months of 1997.\n" + // Should be one duration, currently three durations "It has been three hours, twenty minutes and 5 seconds.\n" + // Should be one duration, currently two durations "He waited for two years and three months.\n" + "He waited for 6 and a half months.\n" + // TODO: What about this? "It was two to three months.\n" + "It was five hundred and twelve days.\n" + // TODO: five hundred and 12 is not recognized "It was six and three months.\n" + "Several days has already passed.\n" + "For five hours on Friday, the shop was closed.\n" + "For more than five hours on Friday, the shop was closed.\n"; // "Last two days was hot."; // TODO: Add this test case Iterator<Timex> expectedTimexes = Arrays.asList(Timex.fromXml("<TIMEX3 tid=\"t1\" alt_value=\"1997 INTERSECT P9M\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf0\" anchorTimeID=\"t2\">the first 9 months of 1997</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"PT3H\" type=\"DURATION\">three hours</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"PT20M\" type=\"DURATION\">twenty minutes</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t5\" value=\"PT5S\" type=\"DURATION\">5 seconds</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t6\" value=\"P2Y\" type=\"DURATION\">two years</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t7\" value=\"P3M\" type=\"DURATION\">three months</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t8\" value=\"PXM\" type=\"DURATION\">months</TIMEX3>"), // TODO: Should be 6 and a half months Timex.fromXml("<TIMEX3 tid=\"t9\" alt_value=\"P2M/P3M\" type=\"DURATION\">two to three months</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t10\" value=\"P512D\" type=\"DURATION\">five hundred and twelve days</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t11\" value=\"P3M\" type=\"DURATION\">three months</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t12\" value=\"PXD\" type=\"DURATION\">Several days</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t13\" alt_value=\"XXXX-WXX-5 INTERSECT PT5H\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf1\" anchorTimeID=\"t14\">five hours on Friday</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t15\" alt_value=\"XXXX-WXX-5 INTERSECT >PT5H\" type=\"DATE\" mod=\"MORE_THAN\" temporalFunction=\"true\" valueFromFunction=\"tf2\" anchorTimeID=\"t14\">more than five hours on Friday</TIMEX3>") //Timex.fromXml("<TIMEX3 alt_value=\"THIS P2D OFFSET P-2D\" anchorTimeID=\"t17\" temporalFunction=\"true\" tid=\"t16\" type=\"DATE\" valueFromFunction=\"tf3\">Last two days</TIMEX3>") ).iterator(); Iterator<Timex> expectedTimexesResolved = Arrays.asList(Timex.fromXml("<TIMEX3 tid=\"t1\" alt_value=\"1997 INTERSECT P9M\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf0\" anchorTimeID=\"t2\">the first 9 months of 1997</TIMEX3>"), // TODO: of 1997 Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"PT3H\" type=\"DURATION\">three hours</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"PT20M\" type=\"DURATION\">twenty minutes</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t5\" value=\"PT5S\" type=\"DURATION\">5 seconds</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t6\" value=\"P2Y\" type=\"DURATION\">two years</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t7\" value=\"P3M\" type=\"DURATION\">three months</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t8\" value=\"PXM\" type=\"DURATION\">months</TIMEX3>"), // TODO: Should be 6 and a half months Timex.fromXml("<TIMEX3 tid=\"t9\" alt_value=\"P2M/P3M\" type=\"DURATION\">two to three months</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t10\" value=\"P512D\" type=\"DURATION\">five hundred and twelve days</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t11\" value=\"P3M\" type=\"DURATION\">three months</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t12\" value=\"PXD\" type=\"DURATION\">Several days</TIMEX3>"), // Friday past tense Timex.fromXml("<TIMEX3 tid=\"t13\" alt_value=\"2010-02-19-WXX-5 INTERSECT PT5H\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf1\" anchorTimeID=\"t14\">five hours on Friday</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t15\" alt_value=\"2010-02-19-WXX-5 INTERSECT >PT5H\" type=\"DATE\" mod=\"MORE_THAN\" temporalFunction=\"true\" valueFromFunction=\"tf2\" anchorTimeID=\"t16\">more than five hours on Friday</TIMEX3>") //Timex.fromXml("<TIMEX3 alt_value=\"THIS P2D OFFSET P-2D\" anchorTimeID=\"t17\" temporalFunction=\"true\" tid=\"t16\" type=\"DATE\" valueFromFunction=\"tf3\">Last two days</TIMEX3>") ).iterator(); Annotation document = createDocument(testText); TimeAnnotator sutime = getTimeAnnotator(); sutime.annotate(document); // Check answers for (CoreMap timexAnn: document.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexes.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); Annotation documentWithRefTime = createDocument(testText, "20100217"); sutime.annotate(documentWithRefTime); for (CoreMap timexAnn: documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexesResolved.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); } public void testSUTimeDurations3() throws IOException { String testText = "Claudia had ruled the duchy well in her regency from 1632 to 1646, and was successful in keeping Tyrol out of the Thirty Years War.\n" + "The focus of today's Daily Eye Candy is the 22-year old fashion supermodel Chad White who is a native of Portland , Oregon.\n"; Iterator<Timex> expectedTimexes = // TODO: Better range duration Arrays.asList(Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"PT122736H\" type=\"DURATION\" beginPoint=\"t1\" endPoint=\"t2\">from 1632 to 1646</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"P30Y\" type=\"DURATION\">the Thirty Years</TIMEX3>"), // TODO: Should just be "Thirty Years" Timex.fromXml("<TIMEX3 tid=\"t5\" alt_value=\"THIS P1D INTERSECT P1D\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf0\" anchorTimeID=\"t6\">today's Daily</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t7\" value=\"P22Y\" type=\"DURATION\">22-year old</TIMEX3>") ).iterator(); Iterator<Timex> expectedTimexesResolved = // TODO: Better range duration Arrays.asList(Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"PT122736H\" type=\"DURATION\" beginPoint=\"t1\" endPoint=\"t2\">from 1632 to 1646</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"P30Y\" type=\"DURATION\">the Thirty Years</TIMEX3>"), // TODO: Should just be "Thirty Years" Timex.fromXml("<TIMEX3 tid=\"t5\" value=\"2010-02-17\" type=\"SET\" quant=\"EVERY\" freq=\"P1X\" periodicity=\"P1D\">today's Daily</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t6\" value=\"P22Y\" type=\"DURATION\">22-year old</TIMEX3>") ).iterator(); Annotation document = createDocument(testText); Properties props = getDefaultProperties(); props.setProperty(TIME_ANNOTATOR_NAME + ".markTimeRanges", "true"); TimeAnnotator sutime = getTimeAnnotator(props); sutime.annotate(document); // Check answers for (CoreMap timexAnn: document.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexes.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); Annotation documentWithRefTime = createDocument(testText, "20100217"); sutime.annotate(documentWithRefTime); for (CoreMap timexAnn: documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexesResolved.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); } public void testSUTimeIso() throws IOException { // Set up test text String testText = "ISO datetime is 2004-03-04T18:32:56+1600.\n" + "ISO datetime is 2004-03-04T18:32:56.\n" + "ISO date is 19880217.\n" + // not recognized ? "ISO date is 1988-02-17.\n" + "Euro date is 19.02.10.\n" + "Euro date is 19.02.2010.\n" + "ISO time is T13:23:42.\n" + "It is 8:43 on 6/12/2008.\n" + "It is 6:53:32 on 7-16-2010.\n" + "The date is 12-03-2007.\n" + "ISO date without day is 2008-04.\n" + "ISO partial datetime 2008-05-16T09.\n" + "It is 2:14:12\n"; // set up expected results Iterator<Timex> expectedTimexes = Arrays.asList( Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"2004-03-04T18:32:56+1600\" type=\"TIME\">2004-03-04T18:32:56+1600</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"2004-03-04T18:32:56\" type=\"TIME\">2004-03-04T18:32:56</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"1988-02-17\" type=\"DATE\">1988-02-17</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"XX10-02-19\" type=\"DATE\">19.02.10</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t5\" value=\"2010-02-19\" type=\"DATE\">19.02.2010</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t6\" value=\"T13:23:42\" type=\"TIME\">T13:23:42</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t7\" value=\"2008-06-12T08:43\" type=\"TIME\">8:43 on 6/12/2008</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t8\" value=\"2010-07-16T06:53:32\" type=\"TIME\">6:53:32 on 7-16-2010</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t9\" value=\"2007-12-03\" type=\"DATE\">12-03-2007</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t10\" value=\"P1D\" type=\"DURATION\">day</TIMEX3>"), // TODO: Fix to PXD, remove Timex.fromXml("<TIMEX3 tid=\"t11\" value=\"2008-04\" type=\"DATE\">2008-04</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t12\" value=\"2008-05-16T09\" type=\"TIME\">2008-05-16T09</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t13\" value=\"T02:14:12\" type=\"TIME\">2:14:12</TIMEX3>")).iterator(); Iterator<Timex> expectedTimexesResolved = Arrays.asList( Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"2004-03-04T18:32:56+1600\" type=\"TIME\">2004-03-04T18:32:56+1600</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"2004-03-04T18:32:56\" type=\"TIME\">2004-03-04T18:32:56</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"1988-02-17\" type=\"DATE\">1988-02-17</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"2010-02-19\" type=\"DATE\">19.02.10</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t5\" value=\"2010-02-19\" type=\"DATE\">19.02.2010</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t6\" value=\"2010-02-17T13:23:42\" type=\"TIME\">T13:23:42</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t7\" value=\"2008-06-12T08:43\" type=\"TIME\">8:43 on 6/12/2008</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t8\" value=\"2010-07-16T06:53:32\" type=\"TIME\">6:53:32 on 7-16-2010</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t9\" value=\"2007-12-03\" type=\"DATE\">12-03-2007</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t10\" value=\"P1D\" type=\"DURATION\">day</TIMEX3>"), // TODO: Fix to PXD, remove Timex.fromXml("<TIMEX3 tid=\"t11\" value=\"2008-04\" type=\"DATE\">2008-04</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t12\" value=\"2008-05-16T09\" type=\"TIME\">2008-05-16T09</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t13\" value=\"2010-02-17T02:14:12\" type=\"TIME\">2:14:12</TIMEX3>")).iterator(); // create document Annotation document = createDocument(testText); // Time annotate TimeAnnotator sutime = getTimeAnnotator(); sutime.annotate(document); // Check answers for (CoreMap timexAnn: document.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexes.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); Annotation documentWithRefTime = createDocument(testText, "20100217"); sutime.annotate(documentWithRefTime); for (CoreMap timexAnn: documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexesResolved.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); } // Re-enable me public void testSUIsoWithTimezone() throws IOException { String testText = "ISO datetime is 2004-03-04T18:32:56 Pacific Standard Time.\n" + "ISO datetime is 2004-03-04T18:32:56 Eastern Standard Time.\n" + "Time is 4:30pm Mountain Time.\n" + // not recognized ? "Time is 9:30 am Pacific Time.\n" + "ISO time is T13:23:42 MDT.\n" + "It is 8:43 PST on 6/12/2008.\n" + "It is 6:53:32 PDT on 7-16-2010.\n" + "ISO partial datetime 2008-05-16T09 Beijing Time.\n" + "It is 2:14:12 MSK\n"; // "ISO datetime is 11 Feb 2005 17:13:41-0800 (PST).\n" + // "ISO datetime is Fri, 11 Feb 2005 17:13:41 -0800 (PST).\n" + // "ISO datetime is 2004-03-04T18:32:56-0800 (PST).\n" + // "ISO datetime is 2004-03-05T18:32:56 (PST).\n" + // "ISO datetime is 2004-03-06T18:32:56+0800.\n" + // "ISO datetime is 2004-03-06T18:32:56-0800.\n"; // "The time is 1400D\n"; // set up expected results Iterator<Timex> expectedTimexes = Arrays.asList( Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"2004-03-04T18:32:56-0800\" type=\"TIME\">2004-03-04T18:32:56 Pacific Standard Time</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"2004-03-04T18:32:56-0500\" type=\"TIME\">2004-03-04T18:32:56 Eastern Standard Time</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"T16:30\" type=\"TIME\">4:30pm</TIMEX3>"), // TODO: Mountain Time Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"T09:30\" type=\"TIME\">9:30 am</TIMEX3>"),// TODO: Pacific Time Timex.fromXml("<TIMEX3 tid=\"t5\" value=\"T13:23:42-0700\" type=\"TIME\">T13:23:42 MDT</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t6\" value=\"2008-06-12T08:43-0800\" type=\"TIME\">8:43 PST on 6/12/2008</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t7\" value=\"2010-07-16T06:53:32-0800\" type=\"TIME\">6:53:32 PDT on 7-16-2010</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t8\" value=\"2008-05-16T09\" type=\"TIME\">2008-05-16T09</TIMEX3>"), // TODO: Beijing Time Timex.fromXml("<TIMEX3 tid=\"t9\" value=\"T02:14:12+0300\" type=\"TIME\">2:14:12 MSK</TIMEX3>") // Timex.fromXml("<TIMEX3 tid=\"t10\" value=\"2005-02-11T17:13:41-0800\" type=\"TIME\">11 Feb 2005 17:13:41-0800 (PST)</TIMEX3>"), // Timex.fromXml("<TIMEX3 tid=\"t11\" value=\"2005-02-11T17:13:41-0800\" type=\"TIME\">Fri, 11 Feb 2005 17:13:41-0800 (PST)</TIMEX3>"), // Timex.fromXml("<TIMEX3 tid=\"t11\" value=\"2004-03-04T18:32:56-0800\" type=\"TIME\">2004-03-04T18:32:56-0800 (PST)</TIMEX3>"), // Timex.fromXml("<TIMEX3 tid=\"t12\" value=\"2004-03-05T18:32:56-0800\" type=\"TIME\">2004-03-05T18:32:56 (PST)</TIMEX3>"), // Timex.fromXml("<TIMEX3 tid=\"t13\" value=\"2004-03-06T18:32:56+0800\" type=\"TIME\">2004-03-06T18:32:56+0800</TIMEX3>"), // Timex.fromXml("<TIMEX3 tid=\"t14\" value=\"2004-03-06T18:32:56-0800\" type=\"TIME\">2004-03-06T18:32:56-0800</TIMEX3>") // Timex.fromXml("<TIMEX3 tid=\"t10\" value=\"T14:00+0400\" type=\"TIME\">1400D</TIMEX3>") ).iterator(); Iterator<Timex> expectedTimexesResolved = Arrays.asList( Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"2004-03-04T18:32:56-0800\" type=\"TIME\">2004-03-04T18:32:56 Pacific Standard Time</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"2004-03-04T18:32:56-0500\" type=\"TIME\">2004-03-04T18:32:56 Eastern Standard Time</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"2010-02-17T16:30\" type=\"TIME\">4:30pm</TIMEX3>"), // TODO: Mountain Time Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"2010-02-17T09:30\" type=\"TIME\">9:30 am</TIMEX3>"),// TODO: Pacific Time Timex.fromXml("<TIMEX3 tid=\"t5\" value=\"2010-02-17T13:23:42-0700\" type=\"TIME\">T13:23:42 MDT</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t6\" value=\"2008-06-12T08:43-0800\" type=\"TIME\">8:43 PST on 6/12/2008</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t7\" value=\"2010-07-16T06:53:32-0800\" type=\"TIME\">6:53:32 PDT on 7-16-2010</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t8\" value=\"2008-05-16T09\" type=\"TIME\">2008-05-16T09</TIMEX3>"), // TODO: Beijing Time Timex.fromXml("<TIMEX3 tid=\"t9\" value=\"2010-02-17T02:14:12+0300\" type=\"TIME\">2:14:12 MSK</TIMEX3>") // Timex.fromXml("<TIMEX3 tid=\"t10\" value=\"2005-02-11T17:13:41-0800\" type=\"TIME\">11 Feb 2005 17:13:41-0800 (PST)</TIMEX3>"), // Timex.fromXml("<TIMEX3 tid=\"t11\" value=\"2005-02-11T17:13:41-0800\" type=\"TIME\">Fri, 11 Feb 2005 17:13:41-0800 (PST)</TIMEX3>"), // Timex.fromXml("<TIMEX3 tid=\"t11\" value=\"2004-03-04T18:32:56-0800\" type=\"TIME\">2004-03-04T18:32:56-0800 (PST)</TIMEX3>"), // Timex.fromXml("<TIMEX3 tid=\"t12\" value=\"2004-03-05T18:32:56-0800\" type=\"TIME\">2004-03-05T18:32:56 (PST)</TIMEX3>"), // Timex.fromXml("<TIMEX3 tid=\"t13\" value=\"2004-03-06T18:32:56+0800\" type=\"TIME\">2004-03-06T18:32:56+0800</TIMEX3>"), // Timex.fromXml("<TIMEX3 tid=\"t14\" value=\"2004-03-06T18:32:56-0800\" type=\"TIME\">2004-03-06T18:32:56-0800</TIMEX3>") // Timex.fromXml("<TIMEX3 tid=\"t10\" value=\"2010-02-17T14:00+0400\" type=\"TIME\">1400D</TIMEX3>") ).iterator(); Annotation document = createDocument(testText); Properties props = getDefaultProperties(); TimeAnnotator sutime = getTimeAnnotator(props); sutime.annotate(document); // Check answers for (CoreMap timexAnn: document.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexes.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); Annotation documentWithRefTime = createDocument(testText, "20100217"); sutime.annotate(documentWithRefTime); for (CoreMap timexAnn: documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexesResolved.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); } public void testSUTime2() throws IOException { String testText = "I'm leaving on vacation two weeks from next Tuesday.\n" + "John left 2 days before yesterday.\n" + "It's almost Thursday.\n" + "I tutored an English student some Thursdays in 1994.\n" + "The meeting is scheduled for every Monday from 3 to 4 p.m.\n" + "The concert is at 8:00 pm on Friday.\n" + "The concert is Friday at 8:00 pm.\n" + "Did you get up before 7:00 am today?\n" + "The company had its third best second quarter ever.\n" + "Mr. Smith left Friday, October 1, 1999.\n" + "Mr. Smith arrived on the second of December.\n" + "Mr. Smith arrived on the second of June.\n" + "Mr. Smith arrived on the second of July.\n" + "Mr. Smith arrived on the second of August.\n" + "In October of 1963, there was a big snow storm.\n" + "Yesterday, it was raining.\n" + "She arrived Saturday night.\n" + "She spent one dollar ($1) yesterday afternoon.\n" + "The book was published in nineteen ninety-one.\n"; // set up expected results Iterator<Timex> expectedTimexes = Arrays.asList(Timex.fromXml("<TIMEX3 tid=\"t1\" alt_value=\"XXXX-WXX-2 OFFSET P3W\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf0\" anchorTimeID=\"t2\">two weeks from next Tuesday</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" alt_value=\"OFFSET P-3D\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf1\" anchorTimeID=\"t0\">2 days before yesterday</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"XXXX-WXX-4\" type=\"DATE\">Thursday</TIMEX3>"), // TODO: Should almost be included? Timex.fromXml("<TIMEX3 tid=\"t5\" value=\"1994-WXX-4\" type=\"SET\" periodicity=\"P1W\">Thursdays in 1994</TIMEX3>"), // TODO: include phrase some Thursdays in 1994 Timex.fromXml("<TIMEX3 tid=\"t6\" value=\"XXXX-WXX-1\" type=\"SET\" quant=\"every\" periodicity=\"P1W\">every Monday</TIMEX3>"), // TODO: phrase from 3 to 4 p.m. Timex.fromXml("<TIMEX3 tid=\"t7\" value=\"T15:57\" type=\"TIME\">3 to 4 p.m</TIMEX3>"), // TODO: Set , phrase from 3 to 4 p.m. (range) // Was "p.m." but now just "p.m" because although TextAnnotation is "p.m.", the OriginalTextAnnotation, which is used here, is just "p.m", because the other period is treated as a sentence final period. Timex.fromXml("<TIMEX3 tid=\"t8\" value=\"XXXX-WXX-5T20:00\" type=\"TIME\">8:00 pm on Friday</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t9\" value=\"XXXX-WXX-5T20:00\" type=\"TIME\">Friday at 8:00 pm</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t10\" alt_value=\"THIS P1D INTERSECT T07:00\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf2\" anchorTimeID=\"t11\">7:00 am today</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t12\" value=\"XXXX-Q2\" type=\"DATE\">second quarter</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t13\" value=\"1999-10-01\" type=\"DATE\">Friday, October 1, 1999</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t14\" value=\"XXXX-12-02\" type=\"DATE\">the second of December</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t15\" value=\"XXXX-06-02\" type=\"DATE\">the second of June</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t16\" value=\"XXXX-07-02\" type=\"DATE\">the second of July</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t17\" value=\"XXXX-08-02\" type=\"DATE\">the second of August</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t18\" value=\"1963-10\" type=\"DATE\">October of 1963</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t19\" alt_value=\"OFFSET P-1D\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf3\" anchorTimeID=\"t0\">Yesterday</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t20\" value=\"XXXX-WXX-6TNI\" type=\"TIME\">Saturday night</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t21\" alt_value=\"OFFSET P-1D INTERSECT AF\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf4\" anchorTimeID=\"t19\">yesterday afternoon</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t22\" value=\"1991\" type=\"DATE\">nineteen ninety-one</TIMEX3>")).iterator(); Iterator<Timex> expectedTimexesResolved = Arrays.asList(Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"1995-08-08\" type=\"DATE\">two weeks from next Tuesday</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"1995-07-17\" type=\"DATE\">2 days before yesterday</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"1995-07-20\" type=\"DATE\">Thursday</TIMEX3>"), // TODO: Should almost be included? Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"1994-WXX-4\" type=\"SET\" periodicity=\"P1W\">Thursdays in 1994</TIMEX3>"), // TODO: include phrase some Thursdays in 1998 Timex.fromXml("<TIMEX3 tid=\"t5\" value=\"XXXX-WXX-1\" type=\"SET\" quant=\"every\" periodicity=\"P1W\">every Monday</TIMEX3>"), // TODO: phrase from 3 to 4 p.m. Timex.fromXml("<TIMEX3 tid=\"t6\" value=\"1995-07-20T15:57\" type=\"TIME\">3 to 4 p.m</TIMEX3>"), // TODO: Set , phrase from 3 to 4 p.m. (range) // Was "p.m." but now just "p.m" because although TextAnnotation is "p.m.", the OriginalTextAnnotation, which is used here, is just "p.m", because the other period is treated as a sentence final period. Timex.fromXml("<TIMEX3 tid=\"t7\" value=\"1995-07-21T20:00\" type=\"TIME\">8:00 pm on Friday</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t8\" value=\"1995-07-21T20:00\" type=\"TIME\">Friday at 8:00 pm</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t9\" value=\"1995-07-20T07:00\" type=\"TIME\">7:00 am today</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t10\" value=\"1995-Q2\" type=\"DATE\">second quarter</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t11\" value=\"1999-10-01\" type=\"DATE\">Friday, October 1, 1999</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t12\" value=\"1994-12-02\" type=\"DATE\">the second of December</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t13\" value=\"1995-06-02\" type=\"DATE\">the second of June</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t14\" value=\"1995-07-02\" type=\"DATE\">the second of July</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t15\" value=\"1994-08-02\" type=\"DATE\">the second of August</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t16\" value=\"1963-10\" type=\"DATE\">October of 1963</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t17\" value=\"1995-07-19\" type=\"DATE\">Yesterday</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t18\" value=\"1995-07-22TNI\" type=\"TIME\">Saturday night</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t19\" value=\"1995-07-19TAF\" type=\"TIME\">yesterday afternoon</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t20\" value=\"1991\" type=\"DATE\">nineteen ninety-one</TIMEX3>")).iterator(); // create document Annotation document = createDocument(testText); // Time annotate TimeAnnotator sutime = getTimeAnnotator(); sutime.annotate(document); // Check answers for (CoreMap timexAnn: document.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexes.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); Annotation documentWithRefTime = createDocument(testText, "19950720"); sutime.annotate(documentWithRefTime); for (CoreMap timexAnn: documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexesResolved.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); } public void testSUTimeDate() throws IOException { String testText = "Mr Smith left in the summer of 1964.\n" + "He started working on Tuesday the 14th.\n" + "This year's summer was very hot.\n" + "In November 1943, it was very cold.\n" + "Are we meeting two weeks from next Tuesday?\n" + "The accident happened last week.\n" + "The year two thousand.\n" + "The 1997 second quarter and 1998 first quarter were very good.\n" + "Mr. Smith moved in nineteen ninety six.\n" + "The accident was Saturday last week.\n" + "He went to Japan August last year.\n" + "He died in 567 bc.\n" + "The temple was built in the late 5th century B.C. and collapsed in the 3rd century A.D.\n" + "I think 1000 BC was a long time ago\n"; Iterator<Timex> expectedTimexes = Arrays.asList( Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"1964-SU\" type=\"DATE\">the summer of 1964</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"XXXX-WXX-2\" type=\"DATE\">Tuesday the 14th</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" alt_value=\"THIS P1Y INTERSECT SU\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf0\" anchorTimeID=\"t4\">This year's summer</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t5\" value=\"1943-11\" type=\"DATE\">November 1943</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t6\" alt_value=\"XXXX-WXX-2 OFFSET P3W\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf1\" anchorTimeID=\"t7\">two weeks from next Tuesday</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t8\" alt_value=\"THIS P1W OFFSET P-1W\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf2\" anchorTimeID=\"t9\">last week</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t10\" value=\"2000\" type=\"DATE\">The year two thousand</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t11\" value=\"1997-Q2\" type=\"DATE\">The 1997 second quarter</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t12\" value=\"1998-Q1\" type=\"DATE\">1998 first quarter</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t13\" value=\"1996\" type=\"DATE\">nineteen ninety six</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t14\" alt_value=\"THIS P1W OFFSET P-1W INTERSECT XXXX-WXX-6\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf3\" anchorTimeID=\"t15\">Saturday last week</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t16\" alt_value=\"THIS P1Y OFFSET P-1Y INTERSECT XXXX-08\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf4\" anchorTimeID=\"t17\">August last year</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t18\" value=\"-0566\" type=\"DATE\">567 bc</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t19\" value=\"-04XX\" type=\"DATE\" mod=\"LATE\">the late 5th century B.C.</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t20\" value=\"02XX\" type=\"DATE\">the 3rd century A.D.</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t21\" value=\"-0999\" type=\"DATE\">1000 BC</TIMEX3>") ).iterator(); Iterator<Timex> expectedTimexesResolved = Arrays.asList(Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"1964-SU\" type=\"DATE\">the summer of 1964</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"1999-12-14\" type=\"DATE\">Tuesday the 14th</TIMEX3>"), // TODO: Fix resolving Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"1999-SU\" type=\"DATE\">This year's summer</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"1943-11\" type=\"DATE\">November 1943</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t5\" value=\"2000-01-18\" type=\"DATE\">two weeks from next Tuesday</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t6\" value=\"1999-W51\" type=\"DATE\">last week</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t7\" value=\"2000\" type=\"DATE\">The year two thousand</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t8\" value=\"1997-Q2\" type=\"DATE\">The 1997 second quarter</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t9\" value=\"1998-Q1\" type=\"DATE\">1998 first quarter</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t10\" value=\"1996\" type=\"DATE\">nineteen ninety six</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t11\" value=\"1999-12-25\" type=\"DATE\">Saturday last week</TIMEX3>"), // Timex.fromXml("<TIMEX3 tid=\"t11\" value=\"1999-W51-6\" type=\"DATE\">Saturday last week</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t12\" value=\"1998-08\" type=\"DATE\">August last year</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t13\" value=\"-0566\" type=\"DATE\">567 bc</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t14\" value=\"-04XX\" type=\"DATE\" mod=\"LATE\">the late 5th century B.C.</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t15\" value=\"02XX\" type=\"DATE\">the 3rd century A.D.</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t16\" value=\"-0999\" type=\"DATE\">1000 BC</TIMEX3>") ).iterator(); // create document Annotation document = createDocument(testText); // Time annotate TimeAnnotator sutime = getTimeAnnotator(); sutime.annotate(document); for (CoreMap timexAnn: document.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexes.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); Annotation documentWithRefTime = createDocument(testText, "1999-12-30"); sutime.annotate(documentWithRefTime); for (CoreMap timexAnn: documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexesResolved.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); } public void testSUTimeTime() throws IOException { String testText = "Mr Smith left ten minutes to three.\n" + // "He started working at five to eight.\n" + "He went for lunch at twenty after twelve.\n" + "He arrived at half past noon.\n" + "It happened at eleven in the morning.\n" + "The meeting is scheduled for 9 a.m. Friday, October 1, 1999.\n" + "He arrived at a quarter past 6.\n"; Iterator<Timex> expectedTimexes = Arrays.asList(Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"T02:50\" type=\"TIME\">ten minutes to three</TIMEX3>"), // Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"T07:55\" type=\"TIME\">five to eight</TIMEX3>"), // TODO: Fix. For now, expression too vague, err on side of caution Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"T12:20\" type=\"TIME\">twenty after twelve</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"T12:30\" type=\"TIME\">half past noon</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"T11:00\" type=\"TIME\">eleven in the morning</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t5\" value=\"1999-10-01T09:00\" type=\"TIME\">9 a.m. Friday, October 1, 1999</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t6\" value=\"T06:15\" type=\"TIME\">a quarter past 6</TIMEX3>")).iterator(); Iterator<Timex> expectedTimexesResolved = Arrays.asList(Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"1998-04-17T02:50\" type=\"TIME\">ten minutes to three</TIMEX3>"), // Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"1998-04-17T07:55\" type=\"TIME\">five to eight</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"1998-04-17T12:20\" type=\"TIME\">twenty after twelve</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"1998-04-17T12:30\" type=\"TIME\">half past noon</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"1998-04-17T11:00\" type=\"TIME\">eleven in the morning</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t5\" value=\"1999-10-01T09:00\" type=\"TIME\">9 a.m. Friday, October 1, 1999</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t6\" value=\"1998-04-17T06:15\" type=\"TIME\">a quarter past 6</TIMEX3>")).iterator(); // create document Annotation document = createDocument(testText); // Time annotate TimeAnnotator sutime = getTimeAnnotator(); sutime.annotate(document); // Check answers for (CoreMap timexAnn: document.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexes.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); Annotation documentWithRefTime = createDocument(testText, "19980417"); sutime.annotate(documentWithRefTime); for (CoreMap timexAnn: documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexesResolved.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); } public void testSUTimeResolveTime() throws IOException { String testText = "Mr Smith left ten minutes to three.\n" + // "He started working at five to eight.\n" + "He went for lunch at twenty after twelve today.\n" + "He arrived at half past noon Saturday.\n" + "He is arriving at half past noon Saturday.\n" + "It happened at eleven in the morning on Tuesday.\n" + "The meeting is scheduled for 9 a.m. tomorrow.\n" + "He arrived at a quarter past 6 yesterday.\n"; Iterator<Timex> expectedTimexes = Arrays.asList(Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"T02:50\" type=\"TIME\">ten minutes to three</TIMEX3>"), // Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"T07:55\" type=\"TIME\">five to eight</TIMEX3>"), // TODO: Fix. For now, expression too vague, err on side of caution Timex.fromXml("<TIMEX3 alt_value=\"THIS P1D INTERSECT T12:20\" anchorTimeID=\"t3\" temporalFunction=\"true\" tid=\"t2\" type=\"DATE\" valueFromFunction=\"tf0\">twenty after twelve today</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t4\" type=\"TIME\" value=\"XXXX-WXX-6T12:30\">half past noon Saturday</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t5\" type=\"TIME\" value=\"XXXX-WXX-6T12:30\">half past noon Saturday</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t6\" type=\"TIME\" value=\"XXXX-WXX-2T11:00\">eleven in the morning on Tuesday</TIMEX3>"), Timex.fromXml("<TIMEX3 alt_value=\"T09:00 OFFSET P1D\" anchorTimeID=\"t8\" temporalFunction=\"true\" tid=\"t7\" type=\"DATE\" valueFromFunction=\"tf1\">9 a.m. tomorrow</TIMEX3>"), Timex.fromXml("<TIMEX3 alt_value=\"T06:15 OFFSET P-1D\" anchorTimeID=\"t10\" temporalFunction=\"true\" tid=\"t9\" type=\"DATE\" valueFromFunction=\"tf2\">a quarter past 6 yesterday</TIMEX3>")).iterator(); Iterator<Timex> expectedTimexesResolved1 = Arrays.asList(Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"1998-04-17T02:50\" type=\"TIME\">ten minutes to three</TIMEX3>"), // Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"1998-04-17T07:55\" type=\"TIME\">five to eight</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"1998-04-17T12:20\" type=\"TIME\">twenty after twelve today</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"1998-04-18T12:30\" type=\"TIME\">half past noon Saturday</TIMEX3>"), // TODO: Should favor 04-11 Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"1998-04-18T12:30\" type=\"TIME\">half past noon Saturday</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t5\" value=\"1998-04-14T11:00\" type=\"TIME\">eleven in the morning on Tuesday</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t6\" value=\"1998-04-18T09:00\" type=\"TIME\">9 a.m. tomorrow</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t7\" value=\"1998-04-16T06:15\" type=\"TIME\">a quarter past 6 yesterday</TIMEX3>")).iterator(); Iterator<Timex> expectedTimexesResolved2 = Arrays.asList(Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"1998-04-17T02:50\" type=\"TIME\">ten minutes to three</TIMEX3>"), // Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"1998-04-17T07:55\" type=\"TIME\">five to eight</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"1998-04-17T12:20\" type=\"TIME\">twenty after twelve today</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"1998-04-11T12:30\" type=\"TIME\">half past noon Saturday</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"1998-04-18T12:30\" type=\"TIME\">half past noon Saturday</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t5\" value=\"1998-04-14T11:00\" type=\"TIME\">eleven in the morning on Tuesday</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t6\" value=\"1998-04-18T09:00\" type=\"TIME\">9 a.m. tomorrow</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t7\" value=\"1998-04-16T06:15\" type=\"TIME\">a quarter past 6 yesterday</TIMEX3>")).iterator(); Iterator<Timex> expectedTimexesResolved3 = Arrays.asList(Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"1998-04T02:50\" type=\"TIME\">ten minutes to three</TIMEX3>"), // Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"1998-04T07:55\" type=\"TIME\">five to eight</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"1998-04T12:20\" type=\"TIME\">twenty after twelve today</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"1998-WXX-6T12:30\" type=\"TIME\">half past noon Saturday</TIMEX3>"), // TODO: The month is lost Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"1998-WXX-6T12:30\" type=\"TIME\">half past noon Saturday</TIMEX3>"), // TODO: The month is lost Timex.fromXml("<TIMEX3 tid=\"t5\" value=\"1998-WXX-2T11:00\" type=\"TIME\">eleven in the morning on Tuesday</TIMEX3>"), // TODO: The month is lost Timex.fromXml("<TIMEX3 alt_value=\"1998-04T09:00 OFFSET P1D\" anchorTimeID=\"t7\" temporalFunction=\"true\" tid=\"t6\" type=\"DATE\" valueFromFunction=\"tf0\">9 a.m. tomorrow</TIMEX3>"), Timex.fromXml("<TIMEX3 alt_value=\"1998-04T06:15 OFFSET P-1D\" anchorTimeID=\"t9\" temporalFunction=\"true\" tid=\"t8\" type=\"DATE\" valueFromFunction=\"tf1\">a quarter past 6 yesterday</TIMEX3>")).iterator(); // Timex.fromXml("<TIMEX3 tid=\"t6\" value=\"1998-04T09:00\" type=\"TIME\">9 a.m. tomorrow</TIMEX3>"), // Timex.fromXml("<TIMEX3 tid=\"t7\" value=\"1998-04T06:15\" type=\"TIME\">a quarter past 6 yesterday</TIMEX3>")).iterator(); // create document Annotation document = createDocument(testText); // Time annotate TimeAnnotator sutime = getTimeAnnotator(); sutime.annotate(document); // Check answers for (CoreMap timexAnn: document.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexes.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); Annotation documentWithRefTime = createDocument(testText, "19980417"); sutime.annotate(documentWithRefTime); for (CoreMap timexAnn: documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexesResolved1.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); documentWithRefTime = createDocument(testText, "19980417T11:00"); sutime.annotate(documentWithRefTime); for (CoreMap timexAnn: documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexesResolved2.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); documentWithRefTime = createDocument(testText, "199804XX"); sutime.annotate(documentWithRefTime); for (CoreMap timexAnn: documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexesResolved3.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); } public void testSUTimeRangeWithoutRange() throws IOException { String testText = "Archduchess Maria Magdalena ( 17 August 1656 - 21 January 1669 )\n"; Iterator<Timex> expectedTimexes = Arrays.asList(Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"1656-08-17\" type=\"DATE\">17 August 1656</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"1669-01-21\" type=\"DATE\">21 January 1669</TIMEX3>")).iterator(); Iterator<Timex> expectedTimexesResolved = Arrays.asList(Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"1656-08-17\" type=\"DATE\">17 August 1656</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"1669-01-21\" type=\"DATE\">21 January 1669</TIMEX3>")).iterator(); // create document Annotation document = createDocument(testText); // Time annotate TimeAnnotator sutime = getTimeAnnotator(); sutime.annotate(document); // Check answers for (CoreMap timexAnn: document.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexes.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); Annotation documentWithRefTime = createDocument(testText, "20030414"); sutime.annotate(documentWithRefTime); for (CoreMap timexAnn: documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexesResolved.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); } public void testSUTimeRangeWithRange() throws IOException { String testText = "Archduchess Maria Magdalena ( 17 August 1656 - 21 January 1669 )\n"; Iterator<Timex> expectedTimexes = Arrays.asList( Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"1656-08-17\" type=\"DATE\">17 August 1656</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"1669-01-21\" type=\"DATE\">21 January 1669</TIMEX3>"), // TODO: better range duration Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"PT108960H\" type=\"DURATION\" beginPoint=\"t1\" endPoint=\"t2\">17 August 1656 - 21 January 1669</TIMEX3>")).iterator(); Iterator<Timex> expectedTimexesResolved = Arrays.asList( Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"1656-08-17\" type=\"DATE\">17 August 1656</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"1669-01-21\" type=\"DATE\">21 January 1669</TIMEX3>"), // TODO: better range duration Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"PT108960H\" type=\"DURATION\" beginPoint=\"t1\" endPoint=\"t2\">17 August 1656 - 21 January 1669</TIMEX3>")).iterator(); // create document Annotation document = createDocument(testText); // Time annotate Properties props = getDefaultProperties(); props.setProperty(TIME_ANNOTATOR_NAME + ".markTimeRanges", "true"); props.setProperty(TIME_ANNOTATOR_NAME + ".includeNested", "true"); TimeAnnotator sutime = getTimeAnnotator(props); sutime.annotate(document); // Check answers for (CoreMap timexAnn: document.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexes.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); Annotation documentWithRefTime = createDocument(testText, "20030414"); sutime.annotate(documentWithRefTime); for (CoreMap timexAnn: documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexesResolved.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); } public void testSUTimeRangeConversion() throws IOException { String testText = "The morning of January 31 was very cold.\n" + "December of 2002.\n" + "This winter was not as cold.\n" + "The 1960s.\n" + "He returned in 1971.\n" + "Meeting in madrid this week.\n" + "They watched a movie over the weekend.\n" + // TODO: semi-annual "But publicity-shy Gabriel Garcia Marquez , who turned 80 this month, did finally appear Monday at the semi-annual meeting of the Inter American Press Association as it ended with a luncheon\n" + "The event happens tomorrow night, not Wednesday afternoon.\n" + "What is last week, or last month, or even the last 3 months, or just last 3 months?"; Iterator<Timex> expectedTimexes = Arrays.asList(Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"XXXX-01-31TMO\" type=\"TIME\" range=\"(XXXX-01-31T06:00:00.000,XXXX-01-31T12:00,PT6H)\">The morning of January 31</TIMEX3>"), // TODO: noon.... Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"2002-12\" type=\"DATE\" range=\"(2002-12-01,2002-12-31,P1M)\">December of 2002</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" alt_value=\"THIS WI\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf0\" anchorTimeID=\"t0\" range=\"(THIS WI,THIS WI,)\">This winter</TIMEX3>"), // TODO: range Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"196X\" type=\"DATE\" range=\"(1960-01-01,1969-12-31,P10Y)\">The 1960s</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t5\" value=\"1971\" type=\"DATE\" range=\"(1971-01-01,1971-12-31,P1Y)\">1971</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t6\" alt_value=\"THIS P1W\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf1\" anchorTimeID=\"t0\" range=\"(THIS P1W,THIS P1W,)\">this week</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t7\" value=\"XXXX-WE\" type=\"DATE\" range=\"(XXXX-WXX-6,XXXX-WXX-7,P2D)\">the weekend</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t8\" alt_value=\"THIS P1M\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf2\" anchorTimeID=\"t0\" range=\"(THIS P1M,THIS P1M,)\">this month</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t9\" value=\"XXXX-WXX-1\" type=\"DATE\" range=\"(XXXX-WXX-1,XXXX-WXX-1,P1D)\">Monday</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t10\" value=\"P6M\" type=\"SET\" quant=\"EVERY\" freq=\"P1X\" periodicity=\"P6M\">semi-annual</TIMEX3>"), Timex.fromXml("<TIMEX3 alt_value=\"OFFSET P1D INTERSECT NI\" anchorTimeID=\"t12\" range=\"(OFFSET P1D INTERSECT NI,OFFSET P1D INTERSECT NI,)\" temporalFunction=\"true\" tid=\"t11\" type=\"DATE\" valueFromFunction=\"tf3\">tomorrow night</TIMEX3>"), Timex.fromXml("<TIMEX3 range=\"(XXXX-WXX-3T12:00:00.000,XXXX-WXX-3T18,PT6H)\" tid=\"t13\" type=\"TIME\" value=\"XXXX-WXX-3TAF\">Wednesday afternoon</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t14\" alt_value=\"THIS P1W OFFSET P-1W\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf4\" anchorTimeID=\"t15\" range=\"(THIS P1W OFFSET P-1W,THIS P1W OFFSET P-1W,)\">last week</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t16\" alt_value=\"THIS P1M OFFSET P-1M\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf5\" anchorTimeID=\"t17\" range=\"(THIS P1M OFFSET P-1M,THIS P1M OFFSET P-1M,)\">last month</TIMEX3>"), Timex.fromXml("<TIMEX3 beginPoint=\"t18\" endPoint=\"t0\" range=\"(UNKNOWN,REF,P3M)\" tid=\"t19\" type=\"DURATION\" value=\"P3M\">the last 3 months</TIMEX3>"), // TODO: Fix this treatment of "the xxx" as duration (but that's what tempeval wants) Timex.fromXml("<TIMEX3 alt_value=\"THIS P3M OFFSET P-3M\" anchorTimeID=\"t21\" range=\"(THIS P3M OFFSET P-3M,THIS P3M OFFSET P-3M,)\" temporalFunction=\"true\" tid=\"t20\" type=\"DATE\" valueFromFunction=\"tf6\">last 3 months</TIMEX3>") ).iterator(); Iterator<Timex> expectedTimexesResolved = Arrays.asList(Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"2003-01-31TMO\" type=\"TIME\" range=\"(2003-01-31T06:00:00.000,2003-01-31T12:00,PT6H)\">The morning of January 31</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"2002-12\" type=\"DATE\" range=\"(2002-12-01,2002-12-31,P1M)\">December of 2002</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"2003-WI\" type=\"DATE\" range=\"(2003-12-01,2003-03,P3M)\">This winter</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"196X\" type=\"DATE\" range=\"(1960-01-01,1969-12-31,P10Y)\">The 1960s</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t5\" value=\"1971\" type=\"DATE\" range=\"(1971-01-01,1971-12-31,P1Y)\">1971</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t6\" value=\"2003-W16\" type=\"DATE\" range=\"(2003-04-14,2003-04-20,P1W)\">this week</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t7\" value=\"2003-W16-WE\" type=\"DATE\" range=\"(2003-04-19,2003-04-20,P2D)\">the weekend</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t8\" value=\"2003-04\" type=\"DATE\" range=\"(2003-04-01,2003-04-30,P1M)\">this month</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t9\" value=\"2003-04-14\" type=\"DATE\" range=\"(2003-04-14-WXX-1,2003-04-14-WXX-1,P1D)\">Monday</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t10\" value=\"P6M\" type=\"SET\" quant=\"EVERY\" freq=\"P1X\" periodicity=\"P6M\">semi-annual</TIMEX3>"), Timex.fromXml("<TIMEX3 range=\"(2003-04-15T19:00:00.000,2003-04-16T05:00:00.000,PT10H)\" tid=\"t11\" type=\"TIME\" value=\"2003-04-15TNI\">tomorrow night</TIMEX3>"), Timex.fromXml("<TIMEX3 range=\"(2003-04-16-WXX-3T12:00:00.000,2003-04-16-WXX-3T18,PT6H)\" tid=\"t12\" type=\"TIME\" value=\"2003-04-16TAF\">Wednesday afternoon</TIMEX3>"), Timex.fromXml("<TIMEX3 range=\"(2003-04-07,2003-04-13,P1W)\" tid=\"t13\" type=\"DATE\" value=\"2003-W15\">last week</TIMEX3>"), Timex.fromXml("<TIMEX3 range=\"(2003-03-01,2003-03-31,P1M)\" tid=\"t14\" type=\"DATE\" value=\"2003-03\">last month</TIMEX3>"), Timex.fromXml("<TIMEX3 beginPoint=\"t15\" endPoint=\"t0\" range=\"(UNKNOWN,REF,P3M)\" tid=\"t16\" type=\"DURATION\" value=\"P3M\">the last 3 months</TIMEX3>"), // TODO: Fix this Timex.fromXml("<TIMEX3 range=\"(2003-01-14,2003-04-14,P3M)\" tid=\"t17\" type=\"DATE\" value=\"2003-01-14/2003-04-14\">last 3 months</TIMEX3>") ).iterator(); // create document Annotation document = createDocument(testText); // Time annotate Properties props = getDefaultProperties(); props.setProperty("sutime.includeRange", "true"); TimeAnnotator sutime = new TimeAnnotator("sutime", props); sutime.annotate(document); // Check answers for (CoreMap timexAnn: document.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexes.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); Annotation documentWithRefTime = createDocument(testText, "20030414"); sutime.annotate(documentWithRefTime); for (CoreMap timexAnn: documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexesResolved.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); } public void testSUTimeEmptySentence() throws IOException { String testText = "."; // create document Annotation document = createDocument(testText); // Time annotate Properties props = getDefaultProperties(); props.setProperty(TIME_ANNOTATOR_NAME + ".includeRange", "true"); TimeAnnotator sutime = getTimeAnnotator(props); sutime.annotate(document); // Check answers List<CoreMap> timexes = document.get(TimeAnnotations.TimexAnnotations.class); assertEquals(0, timexes.size()); Annotation documentWithRefTime = createDocument(testText, "2007-05-14"); sutime.annotate(documentWithRefTime); timexes = document.get(TimeAnnotations.TimexAnnotations.class); assertEquals(0, timexes.size()); } public void testSUTimeInexactTime() throws IOException { String testText = "The morning of January 31 was very cold.\n" + "He arrived late last night.\n" + "He arrived last night.\n"; Iterator<Timex> expectedTimexes = Arrays.asList(Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"XXXX-01-31TMO\" type=\"TIME\">The morning of January 31</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" alt_value=\"TNI OFFSET P-1D\" type=\"DATE\" mod=\"LATE\" temporalFunction=\"true\" valueFromFunction=\"tf0\" anchorTimeID=\"t3\">late last night</TIMEX3>"), // TODO: time Timex.fromXml("<TIMEX3 tid=\"t4\" alt_value=\"TNI OFFSET P-1D\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf1\" anchorTimeID=\"t5\">last night</TIMEX3>")).iterator(); // TODO: time Iterator<Timex> expectedTimexesResolved = Arrays.asList(Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"2003-01-31TMO\" type=\"TIME\">The morning of January 31</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"2003-04-13TNI\" type=\"TIME\" mod=\"LATE\">late last night</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"2003-04-13TNI\" type=\"TIME\">last night</TIMEX3>")).iterator(); // create document Annotation document = createDocument(testText); // Time annotate TimeAnnotator sutime = getTimeAnnotator(); sutime.annotate(document); // Check answers for (CoreMap timexAnn: document.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexes.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); Annotation documentWithRefTime = createDocument(testText, "20030414"); sutime.annotate(documentWithRefTime); for (CoreMap timexAnn: documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexesResolved.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); } public void testSUTimeSet() throws IOException { String testText = "John swims twice a week.\n" + "Every 2 days, he goes jogging.\n" + "Every third week of October, he goes to the lake.\n" + "On alternate Fridays, he drives to the park.\n"; Iterator<Timex> expectedTimexes = Arrays.asList(Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"P1W\" type=\"DURATION\">a week</TIMEX3>"), //TODO: twice a week Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"P2D\" type=\"SET\" quant=\"every\" periodicity=\"P2D\">Every 2 days</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" alt_value=\"XXXX-10 INTERSECT P1W-#3\" type=\"SET\" quant=\"every\">Every third week of October</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"XXXX-WXX-5\" type=\"SET\" quant=\"alternate\" periodicity=\"P2W\">alternate Fridays</TIMEX3>")).iterator(); Iterator<Timex> expectedTimexesResolved = Arrays.asList(Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"P1W\" type=\"DURATION\">a week</TIMEX3>"), //TODO: twice a week Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"P2D\" type=\"SET\" quant=\"every\" periodicity=\"P2D\">Every 2 days</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" alt_value=\"XXXX-10 INTERSECT P1W-#3\" type=\"SET\" quant=\"every\">Every third week of October</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"XXXX-WXX-5\" type=\"SET\" quant=\"alternate\" periodicity=\"P2W\">alternate Fridays</TIMEX3>")).iterator(); // create document Annotation document = createDocument(testText); // Time annotate TimeAnnotator sutime = getTimeAnnotator(); sutime.annotate(document); // Check answers for (CoreMap timexAnn: document.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexes.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); Annotation documentWithRefTime = createDocument(testText, "20030414"); sutime.annotate(documentWithRefTime); for (CoreMap timexAnn: documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexesResolved.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); } public void testSUTimeDateTime() throws IOException { // Set up test text String testText = "The vase of 14 fell early Friday evening.\n" + "The bus is not coming until 8:00 pm.\n" + "They were to have lunch at 12:15 on Thursday.\n" + "Or was it quarter to twelve on Wed?\n" + "He got home at twelve o'clock midnight.\n" + "Next Tuesday is Tuesday the 18th.\n" + "It happened early yesterday morning.\n" + "It happened late afternoon.\n" + "It happened late this afternoon.\n" + "It happened at 1800 hours.\n" + "The early nineteen fifties.\n" + "The story broke in the last week of October.\n" + "It was 7pm and then 7:20pm."; // set up expected results Iterator<Timex> expectedTimexes = Arrays.asList(Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"XXXX-WXX-5TEV\" type=\"TIME\" mod=\"EARLY\">early Friday evening</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"T20:00\" type=\"TIME\">8:00 pm</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"XXXX-WXX-4T12:15\" type=\"TIME\">12:15 on Thursday</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"XXXX-WXX-3T11:45\" type=\"TIME\">quarter to twelve on Wed</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t5\" value=\"T00:00\" type=\"TIME\">twelve o'clock midnight</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t6\" alt_value=\"XXXX-WXX-2 OFFSET P1W\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf0\" anchorTimeID=\"t7\">Next Tuesday</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t8\" value=\"XXXX-WXX-2\" type=\"DATE\">Tuesday the 18th</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t9\" alt_value=\"OFFSET P-1D INTERSECT MO\" type=\"DATE\" mod=\"EARLY\" temporalFunction=\"true\" valueFromFunction=\"tf1\" anchorTimeID=\"t10\">early yesterday morning</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t11\" value=\"TAF\" type=\"TIME\" mod=\"LATE\">late afternoon</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t12\" alt_value=\"THIS AF\" type=\"DATE\" mod=\"LATE\" temporalFunction=\"true\" valueFromFunction=\"tf2\" anchorTimeID=\"t0\">late this afternoon</TIMEX3>"), // TODO: time Timex.fromXml("<TIMEX3 tid=\"t13\" value=\"T18:00\" type=\"TIME\">1800 hours</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t14\" value=\"195X\" type=\"DATE\" mod=\"EARLY\">The early nineteen fifties</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t15\" alt_value=\"PREV_IMMEDIATE P1W INTERSECT XXXX-10\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf3\" anchorTimeID=\"t16\">the last week of October</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t17\" value=\"T19:00\" type=\"TIME\">7pm</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t18\" value=\"T19:20\" type=\"TIME\">7:20pm.</TIMEX3>") // TODO: the period should be dropped ).iterator(); Iterator<Timex> expectedTimexesResolved = Arrays.asList(Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"2005-08-12TEV\" type=\"TIME\" mod=\"EARLY\">early Friday evening</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"2005-08-12T20:00\" type=\"TIME\">8:00 pm</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"2005-08-11T12:15\" type=\"TIME\">12:15 on Thursday</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"2005-08-10T11:45\" type=\"TIME\">quarter to twelve on Wed</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t5\" value=\"2005-08-12T00:00\" type=\"TIME\">twelve o'clock midnight</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t6\" value=\"2005-08-16\" type=\"DATE\">Next Tuesday</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t7\" value=\"2005-08-18\" type=\"DATE\">Tuesday the 18th</TIMEX3>"), // TODO: Tuesday, the 18th flag inconsistency (18th is thursday) Timex.fromXml("<TIMEX3 tid=\"t8\" value=\"2005-08-11TMO\" type=\"TIME\" mod=\"EARLY\">early yesterday morning</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t9\" value=\"2005-08-12TAF\" type=\"TIME\" mod=\"LATE\">late afternoon</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t10\" value=\"2005-08-12TAF\" type=\"TIME\" mod=\"LATE\">late this afternoon</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t11\" value=\"2005-08-12T18:00\" type=\"TIME\">1800 hours</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t12\" value=\"195X\" type=\"DATE\" mod=\"EARLY\">The early nineteen fifties</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t13\" alt_value=\"PREV_IMMEDIATE P1W INTERSECT XXXX-10\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf0\" anchorTimeID=\"t14\">the last week of October</TIMEX3>"), // TODO: Resolve Timex.fromXml("<TIMEX3 tid=\"t15\" value=\"2005-08-12T19:00\" type=\"TIME\">7pm</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t16\" value=\"2005-08-12T19:20\" type=\"TIME\">7:20pm.</TIMEX3>") // TODO: the period should be dropped ).iterator(); // create document Annotation document = createDocument(testText); // Time annotate TimeAnnotator sutime = getTimeAnnotator(); sutime.annotate(document); // Check answers for (CoreMap timexAnn: document.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexes.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); Annotation documentWithRefTime = createDocument(testText, "20050812"); sutime.annotate(documentWithRefTime); for (CoreMap timexAnn: documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexesResolved.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); } // TODO: Re-enable me public void testSUTimeDateTime2() throws IOException { // Set up test text String testText = "The meeting is scheduled for 09/18/05 or 18 Sep '05.\n" + "1 year ago tomorrow.\n" + "3 months ago saturday at 5:00 pm.\n" + "7 hours before tomorrow at noon.\n" + "3rd wednesday in november.\n" + "3rd month next year.\n" + "3rd thursday this september.\n" + "4th day last week.\n" + "fourteenth of june 2010 at eleven o'clock in the evening.\n" + "may seventh '97 at three in the morning.\n" + "The third week of april was very hot.\n"; // set up expected results Iterator<Timex> expectedTimexes = Arrays.asList( Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"XX05-09-18\" type=\"DATE\">09/18/05</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"XX05-09-18\" type=\"DATE\">18 Sep '05</TIMEX3>"), Timex.fromXml("<TIMEX3 alt_value=\"OFFSET P-1Y INTERSECT OFFSET P1D\" anchorTimeID=\"t4\" temporalFunction=\"true\" tid=\"t3\" type=\"DATE\" valueFromFunction=\"tf0\">1 year ago tomorrow</TIMEX3>"), Timex.fromXml("<TIMEX3 alt_value=\"OFFSET P-3M INTERSECT XXXX-WXX-6T17:00\" anchorTimeID=\"t6\" temporalFunction=\"true\" tid=\"t5\" type=\"DATE\" valueFromFunction=\"tf1\">3 months ago saturday at 5:00 pm</TIMEX3>"), Timex.fromXml("<TIMEX3 alt_value=\"OFFSET P1DT-7H INTERSECT T12:00\" anchorTimeID=\"t8\" temporalFunction=\"true\" tid=\"t7\" type=\"DATE\" valueFromFunction=\"tf2\">7 hours before tomorrow at noon</TIMEX3>"), Timex.fromXml("<TIMEX3 alt_value=\"XXXX-11-WXX-3-#3\" tid=\"t9\" type=\"DATE\">3rd wednesday in november</TIMEX3>"), Timex.fromXml("<TIMEX3 alt_value=\"THIS P1Y OFFSET P1Y INTERSECT P1M-#3\" anchorTimeID=\"t11\" temporalFunction=\"true\" tid=\"t10\" type=\"DATE\" valueFromFunction=\"tf3\">3rd month next year</TIMEX3>"), Timex.fromXml("<TIMEX3 alt_value=\"THIS XXXX-09 INTERSECT XXXX-WXX-4-#3\" anchorTimeID=\"t13\" temporalFunction=\"true\" tid=\"t12\" type=\"DATE\" valueFromFunction=\"tf4\">3rd thursday this september</TIMEX3>"), Timex.fromXml("<TIMEX3 alt_value=\"THIS P1W OFFSET P-1W INTERSECT P1D-#4\" anchorTimeID=\"t15\" temporalFunction=\"true\" tid=\"t14\" type=\"DATE\" valueFromFunction=\"tf5\">4th day last week</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t16\" type=\"TIME\" value=\"2010-06-14T23:00\">fourteenth of june 2010 at eleven o'clock in the evening</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t17\" type=\"TIME\" value=\"XX97-05-07T03:00\">may seventh '97 at three in the morning</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t18\" alt_value=\"XXXX-04 INTERSECT P1W-#3\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf6\" anchorTimeID=\"t19\">The third week of april</TIMEX3>") ).iterator(); Iterator<Timex> expectedTimexesResolved = Arrays.asList( Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"2005-09-18\" type=\"DATE\">09/18/05</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"2005-09-18\" type=\"DATE\">18 Sep '05</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"2008-08-13\" type=\"DATE\">1 year ago tomorrow</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"2009-05-12T17:00\" type=\"TIME\">3 months ago saturday at 5:00 pm</TIMEX3>"), // TODO: Should be 05-10 Timex.fromXml("<TIMEX3 tid=\"t5\" value=\"2009-08-13T12:00\" type=\"TIME\">7 hours before tomorrow at noon</TIMEX3>"), // TODO: Should be T05:00 Timex.fromXml("<TIMEX3 tid=\"t6\" value=\"2009-11-18\" type=\"DATE\">3rd wednesday in november</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t7\" value=\"2010-03\" type=\"DATE\">3rd month next year</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t8\" value=\"2009-09-17\" type=\"DATE\">3rd thursday this september</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t9\" value=\"2009-08-06\" type=\"DATE\">4th day last week</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t10\" value=\"2010-06-14T23:00\" type=\"TIME\">fourteenth of june 2010 at eleven o'clock in the evening</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t11\" value=\"1997-05-07T03:00\" type=\"TIME\">may seventh '97 at three in the morning</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t12\" type=\"DATE\" value=\"2009-W16\">The third week of april</TIMEX3>") // TODO: check week number ).iterator(); // create document Annotation document = createDocument(testText); // Time annotate TimeAnnotator sutime = getTimeAnnotator(); sutime.annotate(document); // Check answers for (CoreMap timexAnn: document.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexes.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); Annotation documentWithRefTime = createDocument(testText, "20090812"); sutime.annotate(documentWithRefTime); for (CoreMap timexAnn: documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexesResolved.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); } public void testSUTimeIso2() throws IOException { // Set up test text String testText = "ISO date is 6/12/2008, 1988-02-17.\n"; // set up expected results Iterator<Timex> expectedTimexes = Arrays.asList( Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"2008-06-12\" type=\"DATE\">6/12/2008</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"1988-02-17\" type=\"DATE\">1988-02-17</TIMEX3>")).iterator(); Iterator<Timex> expectedTimexesResolved = Arrays.asList( Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"2008-06-12\" type=\"DATE\">6/12/2008</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"1988-02-17\" type=\"DATE\">1988-02-17</TIMEX3>")).iterator(); // create document Annotation document = createDocument(testText); // Time annotate TimeAnnotator sutime = getTimeAnnotator(); sutime.annotate(document); // Check answers for (CoreMap timexAnn: document.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexes.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); Annotation documentWithRefTime = createDocument(testText, "20100217"); sutime.annotate(documentWithRefTime); for (CoreMap timexAnn: documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexesResolved.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); } public void testSUTimeDate2() throws IOException { // Set up test text String testText = "The date is October 15, 2003.\n" + "The fires started on the first of August 2010.\n" + "It snowed in November 2004.\n" + "The year twenty ten is here.\n" + "I was born in 1879\n"/* + "They met every Tuesday afternoon this March." */; // set up expected results Iterator<Timex> expectedTimexes = Arrays.asList( Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"2003-10-15\" type=\"DATE\">October 15, 2003</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"2010-08-01\" type=\"DATE\">the first of August 2010</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"2004-11\" type=\"DATE\">November 2004</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"2010\" type=\"DATE\">The year twenty ten</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t5\" value=\"1879\" type=\"DATE\">1879</TIMEX3>") ).iterator(); Iterator<Timex> expectedTimexesResolved = Arrays.asList( Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"2003-10-15\" type=\"DATE\">October 15, 2003</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"2010-08-01\" type=\"DATE\">the first of August 2010</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"2004-11\" type=\"DATE\">November 2004</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"2010\" type=\"DATE\">The year twenty ten</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t5\" value=\"1879\" type=\"DATE\">1879</TIMEX3>") ).iterator(); // create document Annotation document = createDocument(testText); // Time annotate TimeAnnotator sutime = getTimeAnnotator(); sutime.annotate(document); // Check answers for (CoreMap timexAnn: document.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexes.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); Annotation documentWithRefTime = createDocument(testText, "20100217"); sutime.annotate(documentWithRefTime); for (CoreMap timexAnn: documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexesResolved.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); } public void testSUTimeHolidays() throws IOException { // Set up test text String testText = "When is mother's day 2012?\n" + "When is Christmas 2010?\n" + "When is Easter 2011?\n"; // set up expected results Iterator<Timex> expectedTimexes = Arrays.asList( Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"2012-05-13\" type=\"DATE\">mother's day 2012</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"2010-12-25\" type=\"DATE\">Christmas 2010</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"2011-04-24\" type=\"DATE\">Easter 2011</TIMEX3>")).iterator(); Iterator<Timex> expectedTimexesResolved = Arrays.asList( Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"2012-05-13\" type=\"DATE\">mother's day 2012</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"2010-12-25\" type=\"DATE\">Christmas 2010</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"2011-04-24\" type=\"DATE\">Easter 2011</TIMEX3>")).iterator(); // create document Annotation document = createDocument(testText); // Time annotate TimeAnnotator sutime = getTimeAnnotator(); sutime.annotate(document); // Check answers for (CoreMap timexAnn: document.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexes.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); Annotation documentWithRefTime = createDocument(testText, "20100217"); sutime.annotate(documentWithRefTime); for (CoreMap timexAnn: documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexesResolved.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); } public void testSUTime12AmPm() throws IOException { // Set up test text String testText = "The hour of 12 in the morning.\n" + "It is 12 in the morning. It is 12:00 or is it 12 am.\n" + "It is 12 in the afternoon. It is 12 in the evening.\n" + "It is 12 at night. It is 12 pm, in 12 hours it will be 24 o'clock (24:00).\n" + "It is 12:34 p.m."; // set up expected results Iterator<Timex> expectedTimexes = Arrays.asList( Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"T00:00\" type=\"TIME\">The hour of 12 in the morning</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"T00:00\" type=\"TIME\">12 in the morning</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"T12:00\" type=\"TIME\">12:00</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"T00:00\" type=\"TIME\">12 am</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t5\" value=\"T12:00\" type=\"TIME\">12 in the afternoon</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t6\" alt_value=\"T00:00 OFFSET P1D\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf0\" anchorTimeID=\"t7\">12 in the evening</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t8\" alt_value=\"T00:00 OFFSET P1D\" type=\"DATE\" temporalFunction=\"true\" valueFromFunction=\"tf1\" anchorTimeID=\"t9\">12 at night</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t10\" value=\"T12:00\" type=\"TIME\">12 pm</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t11\" value=\"PT12H\" type=\"DURATION\">12 hours</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t12\" value=\"T24:00\" type=\"TIME\">24 o'clock</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t13\" value=\"T24:00\" type=\"TIME\">24:00</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t14\" value=\"T12:34\" type=\"TIME\">12:34 p.m.</TIMEX3>")).iterator(); Iterator<Timex> expectedTimexesResolved = Arrays.asList( Timex.fromXml("<TIMEX3 tid=\"t1\" value=\"2010-02-17T00:00\" type=\"TIME\">The hour of 12 in the morning</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" value=\"2010-02-17T00:00\" type=\"TIME\">12 in the morning</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" value=\"2010-02-17T12:00\" type=\"TIME\">12:00</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t4\" value=\"2010-02-17T00:00\" type=\"TIME\">12 am</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t5\" value=\"2010-02-17T12:00\" type=\"TIME\">12 in the afternoon</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t6\" value=\"2010-02-18T00:00\" type=\"TIME\">12 in the evening</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t7\" value=\"2010-02-18T00:00\" type=\"TIME\">12 at night</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t8\" value=\"2010-02-17T12:00\" type=\"TIME\">12 pm</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t9\" value=\"PT12H\" type=\"DURATION\">12 hours</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t10\" value=\"2010-02-17T24:00\" type=\"TIME\">24 o'clock</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t11\" value=\"2010-02-17T24:00\" type=\"TIME\">24:00</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t12\" value=\"2010-02-17T12:34\" type=\"TIME\">12:34 p.m.</TIMEX3>")).iterator(); // create document Annotation document = createDocument(testText); // Time annotate TimeAnnotator sutime = getTimeAnnotator(); sutime.annotate(document); // Check answers for (CoreMap timexAnn: document.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexes.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); Annotation documentWithRefTime = createDocument(testText, "20100217"); sutime.annotate(documentWithRefTime); for (CoreMap timexAnn: documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexesResolved.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); } public void testOverlaps() throws IOException { String testText = "Sun Apr 21\n" + "Wed Apr 24\n" + "Fri Apr 26\n" + "Wed May 1\n" + "Fri May 3\n" + "Sun May 5\n" + "Fri May 10\n" + "Sat May 11\n" + "Wed May 15\n" + "Sat May 18\n" + "Wed May 22\n" + "Mon May 27\n" + "Fri May 31\n" + "Mon June 3\n" + " June 8\n" + "Tue Jun 18\n" + "Wed Jun 19\n"; // set up expected results Iterator<Timex> expectedTimexes = Arrays.asList( Timex.fromXml("<TIMEX3 tid=\"t1\" type=\"DATE\" value=\"XXXX-04-21\">Sun Apr 21</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" type=\"DATE\" value=\"XXXX-04-24\">Wed Apr 24</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" type=\"DATE\" value=\"XXXX-04-26\">Fri Apr 26</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t4\" type=\"DATE\" value=\"XXXX-05-01\">Wed May 1</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t5\" type=\"DATE\" value=\"XXXX-05-03\">Fri May 3</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t6\" type=\"DATE\" value=\"XXXX-05-05\">Sun May 5</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t7\" type=\"DATE\" value=\"XXXX-05-10\">Fri May 10</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t8\" type=\"DATE\" value=\"XXXX-05-11\">Sat May 11</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t9\" type=\"DATE\" value=\"XXXX-05-15\">Wed May 15</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t10\" type=\"DATE\" value=\"XXXX-05-18\">Sat May 18</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t11\" type=\"DATE\" value=\"XXXX-05-22\">Wed May 22</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t12\" type=\"DATE\" value=\"XXXX-05-27\">Mon May 27</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t13\" type=\"DATE\" value=\"XXXX-05-31\">Fri May 31</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t14\" type=\"DATE\" value=\"XXXX-06-03\">Mon June 3</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t15\" type=\"DATE\" value=\"XXXX-06-08\">June 8\nTue</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t16\" type=\"DATE\" value=\"XXXX-06-18\">Jun 18\nWed</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t17\" type=\"DATE\" value=\"XXXX-06-19\">Jun 19</TIMEX3>")).iterator(); Iterator<Timex> expectedTimexesResolved = Arrays.asList( Timex.fromXml("<TIMEX3 tid=\"t1\" type=\"DATE\" value=\"2010-04-21\">Sun Apr 21</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t2\" type=\"DATE\" value=\"2010-04-24\">Wed Apr 24</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t3\" type=\"DATE\" value=\"2010-04-26\">Fri Apr 26</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t4\" type=\"DATE\" value=\"2010-05-01\">Wed May 1</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t5\" type=\"DATE\" value=\"2010-05-03\">Fri May 3</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t6\" type=\"DATE\" value=\"2010-05-05\">Sun May 5</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t7\" type=\"DATE\" value=\"2010-05-10\">Fri May 10</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t8\" type=\"DATE\" value=\"2010-05-11\">Sat May 11</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t9\" type=\"DATE\" value=\"2010-05-15\">Wed May 15</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t10\" type=\"DATE\" value=\"2010-05-18\">Sat May 18</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t11\" type=\"DATE\" value=\"2010-05-22\">Wed May 22</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t12\" type=\"DATE\" value=\"2010-05-27\">Mon May 27</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t13\" type=\"DATE\" value=\"2010-05-31\">Fri May 31</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t14\" type=\"DATE\" value=\"2010-06-03\">Mon June 3</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t15\" type=\"DATE\" value=\"2010-06-08\">June 8\nTue</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t16\" type=\"DATE\" value=\"2010-06-18\">Jun 18\nWed</TIMEX3>"), Timex.fromXml("<TIMEX3 tid=\"t17\" type=\"DATE\" value=\"2010-06-19\">Jun 19</TIMEX3>")).iterator(); // create document Annotation document = createDocument(testText); // Time annotate TimeAnnotator sutime = getTimeAnnotator(); sutime.annotate(document); // Check answers for (CoreMap timexAnn: document.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexes.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); Annotation documentWithRefTime = createDocument(testText, "20100217"); sutime.annotate(documentWithRefTime); for (CoreMap timexAnn: documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexesResolved.next(); checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); } assertFalse(expectedTimexes.hasNext()); } // Early summer morning // A morning in early summer public void testResolve1() { String[] refTimes = { "2011-06-03", "2010-06-03", "2010-05-03", "2011-05-03", "1988-01-03" }; String[] expectedTimexStrsResolved = { "<TIMEX3 tid=\"t1\" value=\"2011-05-23\" type=\"DATE\">last Monday</TIMEX3>", "<TIMEX3 tid=\"t1\" value=\"2010-05-24\" type=\"DATE\">last Monday</TIMEX3>", "<TIMEX3 tid=\"t1\" value=\"2010-04-26\" type=\"DATE\">last Monday</TIMEX3>", "<TIMEX3 tid=\"t1\" value=\"2011-04-25\" type=\"DATE\">last Monday</TIMEX3>", "<TIMEX3 tid=\"t1\" value=\"1987-12-21\" type=\"DATE\">last Monday</TIMEX3>" }; String testText = "last Monday"; for (int i = 0; i < refTimes.length; i++) { String refTime = refTimes[i]; String expectedTimexStr = expectedTimexStrsResolved[i]; Timex expectedTimex = Timex.fromXml(expectedTimexStr); // create document Annotation documentWithRefTime = createDocument(testText, refTime); // Time annotate TimeAnnotator sutime = getTimeAnnotator(); sutime.annotate(documentWithRefTime); List<CoreMap> timexes = documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class); assertEquals(1, timexes.size()); checkTimex(testText, expectedTimex.text(), expectedTimex, timexes.get(0)); } } public void testResolve2() { String[] refTimes = { "2011-06-03", "2010-11-23", "1988-01-16" }; String[] refModifiers = { "last", "this", "next", "this coming"/*, "this past"*/}; String[] refExprs = { "week", "weekend", "fortnight", "month", "quarter", // "season", "year", "decade", "century", "spring", "summer", "autumn", "fall", "winter", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday", "january", "february", "march", "april", "May", // hmmm "june", "july", "august", "september", "october", "november", "december", "easter", "mother's day" }; String[][] expectedValuesPrev = { /* 2011-06-03 */ { "2011-W21", "2011-W21-WE", "2011-05-20/2011-06-03", "2011-05", "2011-Q1", "2010", "200X", "19XX", "2010-SP", "2010-SU", "2010-FA", "2010-FA", "2010-WI", "2011-05-23", "2011-05-24", "2011-05-25", "2011-05-26", "2011-05-27", "2011-05-28", "2011-05-29", //"2011-05-WE?", "2010-01", "2010-02", "2010-03", "2010-04", "2010-05", "2010-06", "2010-07", "2010-08", "2010-09", "2010-10", "2010-11", "2010-12", "2010-04-04", "2010-05-09" }, /* 2010-11-23 */ { "2010-W46", "2010-W46-WE", "2010-11-09/2010-11-23", "2010-10", "2010-Q3", "2009", "200X", "19XX", "2009-SP", "2009-SU", "2009-FA", "2009-FA", "2009-WI", "2010-11-15", "2010-11-16", "2010-11-17", "2010-11-18", "2010-11-19", "2010-11-20", "2010-11-21",// "2010-11-23", "2009-01", "2009-02", "2009-03", "2009-04", "2009-05", "2009-06", "2009-07", "2009-08", "2009-09", "2009-10", "2009-11", "2009-12", "2009-04-12", "2009-05-10" }, /* 1988-01-16 */ { "1988-W01", "1988-W01-WE", "1988-01-02/1988-01-16", "1987-12", "1987-Q4", "1987", "197X", "18XX", "1987-SP", "1987-SU", "1987-FA", "1987-FA", "1987-WI", "1988-01-04", "1988-01-05", "1988-01-06", "1988-01-07", "1988-01-08", "1988-01-09", "1988-01-10",// "2010-11-23", "1987-01", "1987-02", "1987-03", "1987-04", "1987-05", "1987-06", "1987-07", "1987-08", "1987-09", "1987-10", "1987-11", "1987-12", "1987-04-19", "1987-05-10" }, }; String[][] expectedValuesThis = { /* 2011-06-03 */ { "2011-W22", "2011-W22-WE", "2011-05-27/2011-06-10", "2011-06", "2011-Q2", "2011", "201X", "20XX", "2011-SP", "2011-SU", "2011-FA", "2011-FA", "2011-WI", "2011-05-30", "2011-05-31", "2011-06-01", "2011-06-02", "2011-06-03", "2011-06-04", "2011-06-05",// "2011-06-WE?", "2011-01", "2011-02", "2011-03", "2011-04", "2011-05", "2011-06", "2011-07", "2011-08", "2011-09", "2011-10", "2011-11", "2011-12", "2011-04-24", "2011-05-08" }, /* 2010-11-23 */ { "2010-W47", "2010-W47-WE", "2010-11-16/2010-11-30", "2010-11", "2010-Q4", "2010", "201X", "20XX", "2010-SP", "2010-SU", "2010-FA", "2010-FA", "2010-WI", "2010-11-22", "2010-11-23", "2010-11-24", "2010-11-25", "2010-11-26", "2010-11-27", "2010-11-28",// "2010-11-23", "2010-01", "2010-02", "2010-03", "2010-04", "2010-05", "2010-06", "2010-07", "2010-08", "2010-09", "2010-10", "2010-11", "2010-12", "2010-04-04", "2010-05-09" }, /* 1988-01-16 */ { "1988-W02", "1988-W02-WE", "1988-01-09/1988-01-23", "1988-01", "1988-Q1", "1988", "198X", "19XX", "1988-SP", "1988-SU", "1988-FA", "1988-FA", "1988-WI", "1988-01-11", "1988-01-12", "1988-01-13", "1988-01-14", "1988-01-15", "1988-01-16", "1988-01-17",// "2010-11-23", "1988-01", "1988-02", "1988-03", "1988-04", "1988-05", "1988-06", "1988-07", "1988-08", "1988-09", "1988-10", "1988-11", "1988-12", "1988-04-03", "1988-05-08" }, }; String[][] expectedValuesNext = { /* 2011-06-03 */ { "2011-W23", "2011-W23-WE", "2011-06-03/2011-06-17", "2011-07", "2011-Q3", "2012", "202X", "21XX", "2012-SP", "2012-SU", "2012-FA", "2012-FA", "2012-WI", "2011-06-06", "2011-06-07", "2011-06-08", "2011-06-09", "2011-06-10", "2011-06-11", "2011-06-12",// "2011-06-WE?", "2012-01", "2012-02", "2012-03", "2012-04", "2012-05", "2012-06", "2012-07", "2012-08", "2012-09", "2012-10", "2012-11", "2012-12", "2012-04-08", "2012-05-13" }, /* 2010-11-23 */ { "2010-W48", "2010-W48-WE", "2010-11-23/2010-12-07", "2010-12", "2011-Q1", "2011", "202X", "21XX", "2011-SP", "2011-SU", "2011-FA", "2011-FA", "2011-WI", "2010-11-29", "2010-11-30", "2010-12-01", "2010-12-02", "2010-12-03", "2010-12-04", "2010-12-05",// "2010-11-23", "2011-01", "2011-02", "2011-03", "2011-04", "2011-05", "2011-06", "2011-07", "2011-08", "2011-09", "2011-10", "2011-11", "2011-12", "2011-04-24", "2011-05-08" }, /* 1988-01-16 */ { "1988-W03", "1988-W03-WE", "1988-01-16/1988-01-30", "1988-02", "1988-Q2", "1989", "199X", "20XX", "1989-SP", "1989-SU", "1989-FA", "1989-FA", "1989-WI", "1988-01-18", "1988-01-19", "1988-01-20", "1988-01-21", "1988-01-22", "1988-01-23", "1988-01-24",// "2010-11-23", "1989-01", "1989-02", "1989-03", "1989-04", "1989-05", "1989-06", "1989-07", "1989-08", "1989-09", "1989-10", "1989-11", "1989-12", "1989-03-26", "1989-05-14" }, }; String[][] expectedValuesNextImme = { /* 2011-06-03 */ { "2011-W23", "2011-W23-WE", "2011-06-03/2011-06-17", "2011-07", "2011-Q3", "2012", "202X", "21XX", "2012-SP", "2011-SU", "2011-FA", "2011-FA", "2011-WI", "2011-06-06", "2011-06-07", "2011-06-08", "2011-06-09", "2011-06-10", "2011-06-04", "2011-06-05",// "2011-06-WE?", "2012-01", "2012-02", "2012-03", "2012-04", "2012-05", "2012-06", "2011-07", "2011-08", "2011-09", "2011-10", "2011-11", "2011-12", "2012-04-08", "2012-05-13" }, /* 2010-11-23 */ { "2010-W48", "2010-W48-WE", "2010-11-23/2010-12-07", "2010-12", "2011-Q1", "2011", "202X", "21XX", "2011-SP", "2011-SU", "2011-FA", "2011-FA", "2010-WI", "2010-11-29", "2010-11-30", "2010-11-24", "2010-11-25", "2010-11-26", "2010-11-27", "2010-11-28",// "2010-11-23", "2011-01", "2011-02", "2011-03", "2011-04", "2011-05", "2011-06", "2011-07", "2011-08", "2011-09", "2011-10", "2011-11", "2010-12", "2011-04-24", "2011-05-08" }, /* 1988-01-16 */ { "1988-W03", "1988-W03-WE", "1988-01-16/1988-01-30", "1988-02", "1988-Q2", "1989", "199X", "20XX", "1988-SP", "1988-SU", "1988-FA", "1988-FA", "1988-WI", // TODO: Should be 1988-WI or 1989-WI? "1988-01-18", "1988-01-19", "1988-01-20", "1988-01-21", "1988-01-22", "1988-01-23", "1988-01-17",// "2010-11-23", "1989-01", "1988-02", "1988-03", "1988-04", "1988-05", "1988-06", "1988-07", "1988-08", "1988-09", "1988-10", "1988-11", "1988-12", "1988-04-03", "1988-05-08" }, }; // TODO: Add to test String[][] expectedValuesPrevImme = { /* 2011-06-03 */ { "2011-W21", "2011-W21-WE", "2011-05-20/2011-06-03", // TODO: should be W22 or W21? "2011-05", "2011-Q1", "2010", "200X", "19XX", // TODO: should be 2011-Q1 or 2011-Q2 "2010-SP", "2010-SU", "2010-FA", "2010-FA", "2010-WI", "2011-05-30", "2011-05-31", "2011-06-01", "2011-06-02", "2011-05-27", "2011-05-28", "2011-05-29", //"2011-05-WE?", "2011-01", "2011-02", "2011-03", "2011-04", "2011-05", "2010-06", "2010-07", "2010-08", "2010-09", "2010-10", "2010-11", "2010-12", "", "" }, /* 2010-11-23 */ { "2010-W46", "2010-W46-WE", "2010-11-09/2010-11-23", "2010-10", "2010-Q3", "2009", "200X", "19XX", "2010-SP", "2010-SU", "2010-FA", "2010-FA", "2009-WI", "2010-11-22", "2010-11-16", "2010-11-17", "2010-11-18", "2010-11-19", "2010-11-20", "2010-11-21",// "2010-11-23", "2010-01", "2010-02", "2010-03", "2010-04", "2010-05", "2010-06", "2010-07", "2010-08", "2010-09", "2010-10", "2009-11", "2009-12", "", "" }, /* 1988-01-16 */ { "1988-W01", "1988-W01-WE", "1988-01-02/1988-01-16,P2W", "1987-12", "1987-Q4", "1987", "197X", "18XX", "1987-SP", "1987-SU", "1987-FA", "1987-FA", "1987-WI", "1988-01-11", "1988-01-12", "1988-01-13", "1988-01-14", "1988-01-15", "1988-01-09", "1988-01-10",// "2010-11-23", "1987-01", "1987-02", "1987-03", "1987-04", "1987-05", "1987-06", "1987-07", "1987-08", "1987-09", "1987-10", "1987-11", "1987-12", "", "" }, }; String[][][] expectedValuesAll = { expectedValuesPrev, expectedValuesThis, expectedValuesNext, expectedValuesNextImme/*, expectedValuesPrevImme */ }; for (int i = 0; i < refTimes.length; i++) { for (int j = 0; j < refModifiers.length; j++) { String refTime = refTimes[i]; String refMod = refModifiers[j]; StringBuilder sb = new StringBuilder(); for (String s:refExprs) { sb.append("It happened " + refMod + " " + s + ". "); } String testText = sb.toString(); String[] expectedValues = expectedValuesAll[j][i]; Timex[] expectedTimexes = new Timex[refExprs.length]; for (int k = 0; k < refExprs.length; k++) { String v = expectedValues[k]; String expr = refMod + " " + refExprs[k]; if (v.contains("=")) { expectedTimexes[k] = Timex.fromXml( "<TIMEX3 tid=\"t" + (k+1) + "\" " + v + " type=\"DATE\">" + expr + "</TIMEX3>"); } else { expectedTimexes[k] = Timex.fromXml( "<TIMEX3 tid=\"t" + (k+1) + "\" value=\"" + v + "\" type=\"DATE\">" + expr + "</TIMEX3>"); } } // create document Annotation documentWithRefTime = createDocument(testText, refTime); // Time annotate TimeAnnotator sutime = getTimeAnnotator(); sutime.annotate(documentWithRefTime); int k = 0; for (CoreMap timexAnn: documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexes[k]; checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); k++; } assertEquals(expectedTimexes.length, k); } } } public void testResolve3() { String[] refTimes = { "2011-06-03", "2010-11-23", "1988-01-16" }; String[] refModifiers = { "", "last", "this", "next", "this coming"}; String[] todExprs = { "at 8 p.m.", "at 8 in the morning", "at 8 in the evening", "1:00 pm", "morning", "noon", "afternoon", "evening", "night", "midnight" }; String[] expectedTodValues = { "T20:00", "T08:00", "T20:00", "T13:00", "TMO", "T12:00", "TAF", "TEV", "TNI", "T00:00" }; String[] refExprs = { "monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday", }; String[][] expectedValuesPrev = { /* 2011-06-03 */ { "2011-05-23", "2011-05-24", "2011-05-25", "2011-05-26", "2011-05-27", "2011-05-28", "2011-05-29" }, /* 2010-11-23 */ { "2010-11-15", "2010-11-16", "2010-11-17", "2010-11-18", "2010-11-19", "2010-11-20", "2010-11-21" }, /* 1988-01-16 */ { "1988-01-04", "1988-01-05", "1988-01-06", "1988-01-07", "1988-01-08", "1988-01-09", "1988-01-10" }, }; String[][] expectedValuesThis = { /* 2011-06-03 */ { "2011-05-30", "2011-05-31", "2011-06-01", "2011-06-02", "2011-06-03", "2011-06-04", "2011-06-05" }, /* 2010-11-23 */ { "2010-11-22", "2010-11-23", "2010-11-24", "2010-11-25", "2010-11-26", "2010-11-27", "2010-11-28" }, /* 1988-01-16 */ { "1988-01-11", "1988-01-12", "1988-01-13", "1988-01-14", "1988-01-15", "1988-01-16", "1988-01-17" }, }; String[][] expectedValuesNext = { /* 2011-06-03 */ { "2011-06-06", "2011-06-07", "2011-06-08", "2011-06-09", "2011-06-10", "2011-06-11", "2011-06-12" }, /* 2010-11-23 */ { "2010-11-29", "2010-11-30", "2010-12-01", "2010-12-02", "2010-12-03", "2010-12-04", "2010-12-05" }, /* 1988-01-16 */ { "1988-01-18", "1988-01-19", "1988-01-20", "1988-01-21", "1988-01-22", "1988-01-23", "1988-01-24" }, }; String[][] expectedValuesNextImme = { /* 2011-06-03 */ { "2011-06-06", "2011-06-07", "2011-06-08", "2011-06-09", "2011-06-10", "2011-06-04", "2011-06-05" }, /* 2010-11-23 */ { "2010-11-29", "2010-11-30", "2010-11-24", "2010-11-25", "2010-11-26", "2010-11-27", "2010-11-28" }, /* 1988-01-16 */ { "1988-01-18", "1988-01-19", "1988-01-20", "1988-01-21", "1988-01-22", "1988-01-23", "1988-01-17" }, }; String[][][] expectedValuesAll = { expectedValuesThis, expectedValuesPrev, expectedValuesThis, expectedValuesNext, expectedValuesNextImme }; for (int i = 0; i < refTimes.length; i++) { for (int j = 0; j < refModifiers.length; j++) { String refTime = refTimes[i]; String refMod = refModifiers[j]; StringBuilder sb = new StringBuilder(); for (String s:refExprs) { for (String tod:todExprs) { sb.append("It happened " + refMod + " " + s + " " + tod + ". "); } } String testText = sb.toString(); String[] expectedValues = expectedValuesAll[j][i]; Timex[] expectedTimexes = new Timex[refExprs.length * todExprs.length]; int k = 0; for (int k1 = 0; k1 < refExprs.length; k1++) { for (int k2 = 0; k2 < todExprs.length; k2++) { String v = expectedValues[k1] + expectedTodValues[k2]; String expr = (refMod.length() > 0)? (refMod + " "):""; expr = expr + refExprs[k1] + " " + todExprs[k2]; if (v.contains("=")) { expectedTimexes[k] = Timex.fromXml( "<TIMEX3 tid=\"t" + (k+1) + "\" " + v + " type=\"TIME\">" + expr + "</TIMEX3>"); } else { expectedTimexes[k] = Timex.fromXml( "<TIMEX3 tid=\"t" + (k+1) + "\" value=\"" + v + "\" type=\"TIME\">" + expr + "</TIMEX3>"); } k++; } } // create document Annotation documentWithRefTime = createDocument(testText, refTime); // Time annotate TimeAnnotator sutime = getTimeAnnotator(); sutime.annotate(documentWithRefTime); k = 0; for (CoreMap timexAnn: documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexes[k]; checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); k++; } assertEquals(expectedTimexes.length, k); } } } public void testSet() { String[] refModifiers = { "every", "every other", "each", "alternate", "every 3rd", "every fourth"}; String[] refExprs = { "week", "weekend", "fortnight", "month", // "quarter", // "season", "year", "decade", "century", "millenium", "spring", "summer", "autumn", "fall", "winter", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday", "january", "february", "march", "april", "May", // hmmm "june", "july", "august", "september", "october", "november", "december" }; String[][] expectedValuesEvery = { { "P1W", "P1W" }, { /*"XXXX-WXX-WE" */ "XXXX-WE" /*"WE"*/, "P1W" }, { "P2W", "P2W" }, { "P1M", "P1M" }, /*{ "P3M", "P3M" } ,*/ { "P1Y", "P1Y" }, { "P10Y", "P10Y" }, { "P100Y", "P100Y" }, { "P1000Y", "P1000Y" }, { "XXXX-SP", "P1Y" }, { "XXXX-SU", "P1Y" }, { "XXXX-FA", "P1Y" }, { "XXXX-FA", "P1Y" }, { "XXXX-WI", "P1Y" }, { "XXXX-WXX-1", "P1W" }, { "XXXX-WXX-2", "P1W" }, { "XXXX-WXX-3", "P1W" }, { "XXXX-WXX-4", "P1W" }, { "XXXX-WXX-5", "P1W" }, { "XXXX-WXX-6", "P1W" }, { "XXXX-WXX-7", "P1W" }, { "XXXX-01", "P1Y" }, { "XXXX-02", "P1Y" }, { "XXXX-03", "P1Y" }, { "XXXX-04", "P1Y" }, { "XXXX-05", "P1Y" }, { "XXXX-06", "P1Y" }, { "XXXX-07", "P1Y" }, { "XXXX-08", "P1Y" }, { "XXXX-09", "P1Y" }, { "XXXX-10", "P1Y" }, { "XXXX-11", "P1Y" }, { "XXXX-12", "P1Y" }, }; int[] expectedMultiples = { 1, 2, 1, 2, 3, 4 }; final Pattern p = Pattern.compile("(\\D+)(\\d+)(\\D+)"); for (int j = 0; j < refModifiers.length; j++) { String refTime = null; String refMod = refModifiers[j]; StringBuilder sb = new StringBuilder(); for (String s:refExprs) { sb.append("It happens " + refMod + " " + s + ". "); } String testText = sb.toString(); Timex[] expectedTimexes = new Timex[refExprs.length]; int m = expectedMultiples[j]; for (int k = 0; k < refExprs.length; k++) { String v = expectedValuesEvery[k][0]; String g = expectedValuesEvery[k][1]; Matcher matcher = p.matcher(g); if (matcher.matches()) { int mg = Integer.parseInt(matcher.group(2)); mg = mg*m; g = matcher.group(1) + mg + matcher.group(3); } String expr = refMod + ' ' + refExprs[k]; expectedTimexes[k] = Timex.fromXml( "<TIMEX3 tid=\"t" + (k+1) + "\" value=\"" + v + "\" type=\"SET\" quant=\"" + refMod + "\" periodicity=\"" + g + "\">" + expr + "</TIMEX3>"); } // create document Annotation documentWithRefTime = createDocument(testText, refTime); // Time annotate TimeAnnotator sutime = getTimeAnnotator(); sutime.annotate(documentWithRefTime); int k = 0; for (CoreMap timexAnn: documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexes[k]; checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); k++; } assertEquals(expectedTimexes.length, k); } } public void testSet2() { String[] refModifiers = { "", "bi", "bi-", "bi - "/*, "semi", "semi-" */}; String[] refExprs = { "annually", "yearly", "annual", "quarterly", "monthly", "weekly", "daily", "nightly", "hourly" }; String[][] expectedValuesEvery = { { "P1Y", "P1Y" }, { "P1Y", "P1Y" }, { "P1Y", "P1Y" }, { "P3M", "P3M" }, { "P1M", "P1M" }, { "P1W", "P1W" }, { "P1D", "P1D" }, { "TNI", "P1D" }, { "PT1H", "PT1H" }, }; int[] expectedMultiples = { 1, 2, 2, 2 /*, 1, 1 */ }; final Pattern p = Pattern.compile("(\\D+)(\\d+)(\\D+)"); for (int j = 0; j < refModifiers.length; j++) { String refTime = null; String refMod = refModifiers[j]; StringBuilder sb = new StringBuilder(); for (String s:refExprs) { sb.append("It happens " + refMod + s + ". "); } String testText = sb.toString(); Timex[] expectedTimexes = new Timex[refExprs.length]; int m = expectedMultiples[j]; for (int k = 0; k < refExprs.length; k++) { String v = expectedValuesEvery[k][0]; String g = expectedValuesEvery[k][1]; boolean updateV = v.equals(g); Matcher matcher = p.matcher(g); if (matcher.matches()) { int mg = Integer.parseInt(matcher.group(2)); mg = mg*m; g = matcher.group(1) + mg + matcher.group(3); } if (updateV) { v = g; } String expr = refMod + refExprs[k]; expectedTimexes[k] = Timex.fromXml( "<TIMEX3 tid=\"t" + (k+1) + "\" value=\"" + v + "\" type=\"SET\" quant=\"" + "EVERY" + "\" freq=\"P1X\" periodicity=\"" + g + "\">" + expr + "</TIMEX3>"); } // create document Annotation documentWithRefTime = createDocument(testText, refTime); // Time annotate TimeAnnotator sutime = getTimeAnnotator(); sutime.annotate(documentWithRefTime); int k = 0; for (CoreMap timexAnn: documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexes[k]; checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); k++; } assertEquals(expectedTimexes.length, k); } } public void testSeasons() { String[] refModifiers = { "", "the "}; String[] refExprs1 = { "summer", "winter", "autumn", "fall", "spring" }; String[] refExprs2 = { "nineteen ninety five", "2005" }; String[] expected1 = { "SU", "WI", "FA", "FA", "SP"}; String[] expected2 = { "1995", "2005" }; for (String refModifier : refModifiers) { String refTime = null; StringBuilder sb = new StringBuilder(); for (String s : refExprs1) { for (String y : refExprs2) { sb.append("It happens " + refModifier + s + " " + y + ". "); sb.append("It happens " + refModifier + s + " of " + y + ". "); sb.append("It happens " + refModifier + y + " " + s + ". "); } } String testText = sb.toString(); Timex[] expectedTimexes = new Timex[refExprs1.length * refExprs2.length * 3]; int i = 0; for (int k = 0; k < refExprs1.length; k++) { for (int m = 0; m < refExprs2.length; m++) { String s = expected1[k]; String y = expected2[m]; String v = y + "-" + s; String expr = refModifier + refExprs1[k] + " " + refExprs2[m]; expectedTimexes[i++] = Timex.fromXml("<TIMEX3 tid=\"t" + (i) + "\" value=\"" + v + "\" type=\"DATE\">" + expr + "</TIMEX3>"); expr = refModifier + refExprs1[k] + " of " + refExprs2[m]; expectedTimexes[i++] = Timex.fromXml("<TIMEX3 tid=\"t" + (i) + "\" value=\"" + v + "\" type=\"DATE\">" + expr + "</TIMEX3>"); expr = refModifier + refExprs2[m] + " " + refExprs1[k]; expectedTimexes[i++] = Timex.fromXml("<TIMEX3 tid=\"t" + (i) + "\" value=\"" + v + "\" type=\"DATE\">" + expr + "</TIMEX3>"); } } // create document Annotation documentWithRefTime = createDocument(testText, refTime); // Time annotate TimeAnnotator sutime = getTimeAnnotator(); sutime.annotate(documentWithRefTime); i = 0; for (CoreMap timexAnn : documentWithRefTime.get(TimeAnnotations.TimexAnnotations.class)) { Timex expectedTimex = expectedTimexes[i]; checkTimex(testText, expectedTimex.text(), expectedTimex, timexAnn); i++; } assertEquals(expectedTimexes.length, i); } } private static void checkTimex(String documentText, String expectedText, Timex expectedTimex, CoreMap timexAnn) { String actualText = timexAnn.get(CoreAnnotations.TextAnnotation.class); Assert.assertEquals(expectedText, actualText); int begin = timexAnn.get(CoreAnnotations.CharacterOffsetBeginAnnotation.class); int end = timexAnn.get(CoreAnnotations.CharacterOffsetEndAnnotation.class); Assert.assertEquals(expectedText, documentText.substring(begin, end)); Timex actualTimex = timexAnn.get(TimeAnnotations.TimexAnnotation.class); Assert.assertEquals("Expected \"" + expectedTimex + "\" but got \"" + actualTimex + '"', expectedTimex.toString(), actualTimex.toString()); } protected static Annotation createDocument(String text) { Annotation annotation = new Annotation(text); pipeline.annotate(annotation); return annotation; } protected static Annotation createDocument(String text, String date) { Annotation annotation = new Annotation(text); annotation.set(CoreAnnotations.DocDateAnnotation.class, date); pipeline.annotate(annotation); return annotation; } }