/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package test.endtoend; import org.das2.datum.Datum; import org.das2.datum.Units; import org.das2.datum.DatumRangeUtil; import org.das2.datum.DatumUtil; import org.das2.datum.DatumRange; import org.das2.datum.UnitsConverter; import static org.das2.datum.DatumRangeUtil.*; import org.das2.datum.TimeUtil; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.BufferedWriter; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Set; /** * Tests of time parsing. A little testing appears in Test019, but this provides * an comprehensive list that will be a good reference. * * @author jbf */ public class Test026 { private static final String filePath = "Examples.html"; private static BufferedWriter bw; private static boolean testTimeRange(String norm, String test) { DatumRange dr1 = DatumRangeUtil.parseTimeRangeValid(test); DatumRange dr2 = DatumRangeUtil.parseTimeRangeValid(norm); if (!dr1.equals(dr2)) { throw new IllegalStateException("fail after parsing test->" + dr1.toString() + " width=" + DatumUtil.asOrderOneUnits(dr1.width())); } else { String format = DatumRangeUtil.formatTimeRange(dr1); dr1 = DatumRangeUtil.parseTimeRangeValid(format); if (!dr1.equals(dr2)) { throw new IllegalStateException("fail after format: format=" + format + " width=" + DatumUtil.asOrderOneUnits(dr1.width())); } } return true; } /** * test against a list of time ranges. This may serve as a guide for how to * format time strings. Each test is a string to parse against an * easy-to-parse explicit range. * * commented entries are strings that fail in the parser but should handled. */ public static void testTimeRangeFormatParse() { // testTimeRange( easy-to-parse norm, test string ). testTimeRange("2001-11-03 23:00 to 2001-11-05 00:00", "2001-11-03 23:00 to 2001-11-04 24:00"); testTimeRange("2001-01-01 00:00 to 2002-01-01 00:00", "2001"); testTimeRange("2001-01-01 00:00 to 2004-01-01 00:00", "2001-2004"); // das2 "-" is exclusive testTimeRange("2001-01-01 00:00 to 2004-01-01 00:00", "2001 to 2004"); // das2 to is exclusive testTimeRange("2001-01-01 00:00 to 2004-01-01 00:00", "2001 through 2003"); // das2 through is inclusive testTimeRange("2001-06-01 00:00 to 2001-07-01 00:00", "2001 Jun"); testTimeRange("2001-06-01 00:00 to 2001-08-01 00:00", "2001 Jun through July"); testTimeRange("2001-06-01 00:00 to 2001-07-01 00:00", "2001 Jun to July"); testTimeRange("2001-06-08 00:00 to 2001-06-09 00:00", "2001 Jun 8"); testTimeRange("2001-06-01 00:00 to 2001-07-01 00:00", "2001 Jun to July"); testTimeRange("2001-06-08 00:00 to 2001-06-09 00:00", "2001 Jun 8 00:00 to 24:00"); testTimeRange("2001-01-01 00:00 to 2001-01-06 00:00", "2001 Jan 01 span 5 day"); testTimeRange("2001-01-01 05:00 to 2001-01-01 07:00", "2001 Jan 01 05:00 span 2 hr"); testTimeRange("2016-10-01 00:00 to 2016-11-01 00:00", "2016 October"); // bug https://sourceforge.net/p/autoplot/bugs/1774/ testTimeRange("2010-09-01 00:00 to 2010-09-02 00:00", "2010-244"); // day of year is three digits (001-366) testTimeRange("2010-03-01 00:00 to 2010-03-02 00:00", "2010-060"); // testTimeRange( "2001-07-01 00:00 to 2002-01-01 00:00", "July+through+Dec+2001" ); //TODO: should plus be a delimiter? minus is, so I don't think this would hurt anything... Autoplot often converts plus to space to make them continuous. //testTimeRange( "2012-04-07 0:00 to 2012-04-18", "2012-04-07 to 2012-04-18"); // this fails //testTimeRange( "2000 01 span 5 d", "2000-jan-01 to 2000-jan-06" ); } public static void doTest(int id, String test, String ref) throws Exception { doTest(id, test, ref, 0., false); } private static LinkedHashMap usedIds= new LinkedHashMap<>(); /** * * @param id the test identifier * @param test the string to parse * @param ref a string which will reliably parse, containing the same value. * @param diffMicros allowable difference. * @throws Exception */ private static void doTest(int id, String test, String ref, double diffMicros, boolean secondChance) throws Exception { String previousUsedId= usedIds.get(id); if ( previousUsedId!=null && !previousUsedId.equals(test) ) { throw new IllegalArgumentException("id "+id+" used twice, test code needs attention"); } usedIds.put(id,test); DatumRange dr = parseTimeRange(test); DatumRange drref = parseTimeRange(ref); if (drref.equals(dr)) { System.err.println(id + ": " + test + "\t" + drref.min() + "\t" + DatumUtil.asOrderOneUnits(drref.width())); } else { Datum d1 = dr.min().subtract(drref.min()).abs(); Datum d2 = dr.max().subtract(drref.max()).abs(); if (d1.lt(Units.microseconds.createDatum(diffMicros)) && d2.lt(Units.microseconds.createDatum(diffMicros))) { System.err.println(id + ": " + test + "\t" + drref + "\t within " + diffMicros + " micros (" + d1 + " " + d2 + ")"); } else { System.err.println(id + ": " + test + " != " + ref + "\n " + dr + " != " + drref + "\n not within " + diffMicros + " micros (" + d1 + " " + d2 + ")"); //dr= parseTimeRange(test); // for debugging //drref= parseTimeRange(ref); if ( secondChance ) { System.err.println("try again..."); doTest( id, test, ref, diffMicros, false ); //NOW has the problem that occasionally they will fail. } else { throw new IllegalArgumentException("no parse exception, but parsed incorrectly."); } } } writeToHTML(id, test, ref); // uncomment this for testing. } private static void doTestDR(int id, String test, DatumRange norm) throws Exception { DatumRange dr = DatumRangeUtil.parseDatumRange(test, norm.getUnits()); if (!norm.equals(dr)) { throw new IllegalArgumentException("test \"" + test + "\" is not equal to " + norm); } } public static void createHTMLHead() throws IOException { File f = new File(filePath); String htmlOpen = ""; String headerString = "Test 026"; String bodyString = ""; String headerOpen = "
" + "TEST COMPARISON TABLE (Test026.java)" + "
"; String tableOpen = "\n"; bw = new BufferedWriter(new FileWriter(f)); bw.write(htmlOpen); //opens html bw.write(headerString); //writes html header bw.write(bodyString); //opens body and gives style bw.write(headerOpen); //writes header of webpage bw.write(tableOpen); //opens table for doTest method to write to } public static void closeHTML() throws IOException { String htmlClose = "
"; bw.write(htmlClose); //closes html page bw.close(); //closes buffer } public static void writeToHTML(int id, String test, String ref) throws IOException { String table = "Test Number: " + id + "" + "Test: " + test + "" + "Ref: " + ref + "\n"; bw.write(table); } public static void main(String[] args) { try { createHTMLHead(); //doTests doTestDR(70, "0 to 35", DatumRange.newDatumRange(0, 35, Units.dimensionless)); doTestDR(71, "0to35", DatumRange.newDatumRange(0, 35, Units.dimensionless)); doTestDR(72, "0 to 35 apples", DatumRange.newDatumRange(0, 35, Units.lookupUnits("apples"))); doTestDR(73, "0 to 35 sector", DatumRange.newDatumRange(0, 35, Units.lookupUnits("sector"))); doTestDR(74, "0to35 sector", DatumRange.newDatumRange(0, 35, Units.lookupUnits("sector"))); doTestDR(75, "-50to-35", DatumRange.newDatumRange(-50, -35, Units.dimensionless)); doTestDR(76, "0 to 10 kHz", DatumRange.newDatumRange(0, 10000, Units.hertz)); doTestDR(77, "0 to .01 MHz", DatumRange.newDatumRange(0, 10000, Units.hertz)); Units cm = Units.lookupUnits("cm"); cm.registerConverter(Units.meters, new UnitsConverter.ScaleOffset(1. / 100, 0)); doTestDR(78, "0 to 10 cm", DatumRange.newDatumRange(0, .1, Units.meters)); Units mm = Units.lookupUnits("mm"); mm.registerConverter(Units.meters, new UnitsConverter.ScaleOffset(1. / 1000, 0)); doTestDR(79, "0 to 100 mm", DatumRange.newDatumRange(0, 10, cm)); doTestDR(80, "0 to 100 mm", DatumRange.newDatumRange(0, .1, Units.meters)); // These tests show two equivalent strings //das2 times. Note das2 likes to format things with through, not "to" as used in the tests. doTest(0, "2000-01-01T13:00Z to 2000-01-01T14:00", "2000-01-01T13:00Z to 2000-01-01T14:00"); doTest(1, "2000-01-01 13:00 to 14:00", "2000-01-01T13:00Z to 2000-01-01T14:00"); doTest(2, "2000-01-02", "2000-01-02T00:00Z to 2000-01-03T00:00"); doTest(3, "2000-002", "2000-01-02T00:00Z to 2000-01-03T00:00"); doTest(4, "2000-02", "2000-02-01T00:00Z to 2000-03-01T00:00"); doTest(5, "2000-feb", "2000-02-01T00:00Z to 2000-03-01T00:00"); doTest(6, "2000", "2000-01-01T00:00Z to 2001-01-01T00:00"); doTest(7, "2000-01-01 to 2000-01-05", "2000-01-01T00:00Z to 2000-01-05T00:00"); doTest(8, "2000-01-01 through 2000-01-05", "2000-01-01T00:00Z to 2000-01-06T00:00"); doTest(9, "2001-01-01 span 10 days", "2001-01-01T00:00Z to 2001-01-11T00:00"); //ISO8601 times doTest(10, "2000-01-01T13:00Z/PT1H", "2000-01-01T13:00Z/2000-01-01T14:00"); doTest(11, "20000101T1300Z/PT1H", "2000-01-01T13:00Z/2000-01-01T14:00"); doTest(12, "2000-01-01T00:00Z/P1D", "2000-01-01T00:00Z/2000-01-01T24:00"); doTest(13, "2007-03-01T13:00:00Z/P1Y2M10DT2H30M", "2007-03-01T13:00:00Z/2008-05-11T15:30:00Z"); doTest(14, "2007-03-01T13:00:00Z/2008-05-11T15:30:00Z", "2007-03-01T13:00:00Z/2008-05-11T15:30:00Z"); doTest(15, "P1Y2M10DT2H30M/2008-05-11T15:30:00Z", "2007-03-01T13:00:00Z/2008-05-11T15:30:00Z"); doTest(16, "2007-009/2007-021", "2007-01-09T00:00:00Z/2007-01-21T00:00:00Z"); doTest(17, "2007-05-15/2007-05-30", "2007-05-15T00:00:00Z/2007-05-30T00:00:00Z"); doTest(18, "2007-03-01/P5D", "2007-03-01T00:00:00Z/2007-03-06T00:00:00Z"); doTest(19, "P5D/2007-03-06", "2007-03-01T00:00:00Z/2007-03-06T00:00:00Z"); doTest(20, "2000-01-01T13:00/PT1H", "2000-01-01 13:00 to 14:00"); doTest(21, "20000101T13:00Z/14:00Z", "2000-01-01 13:00 to 14:00"); doTest(22, "20000101T1300Z/1400Z", "2000-01-01 13:00 to 14:00" ); doTest(23, "20000101/05", "2000-01-01 00:00 to 2000-01-05 00:00" ); //Extreme times doTest(30, "1000", "1000-01-01T00:00Z to 1001-01-01T00:00"); doTest(31, "9000", "9000-01-01T00:00Z to 9001-01-01T00:00"); doTest(32, "2000-01-01T00:00:00 span .000001 sec", "2000-01-01T00:00:00.000000 to 2000-01-01T00:00:00.000001"); doTest(33, "2000-01-01T00:00:00 span .000000001 sec", "2000-01-01T00:00:00.000000 to 2000-01-01T00:00:00.000000001"); doTest(34, "2002-01-01T10:10:10 span .000000001 sec", "2002-01-01T10:10:10.000000 to 2002-01-01T10:10:10.000000001"); //month boundaries crossing year boundary caused problems. doTest(35, "Aug 1969 through Sep 1970", "Aug 1 1969 to Oct 1 1970"); doTest(36, "2004-12-03T20:19:59.990/PT.02S", "2004-12-03 20:19:59.990 to 20:20:00.010", 30, false); doTest(37, "2004-12-03T20:19:56.2/PT.2S", "2004-12-03 20:19:56.200 to 20:19:56.400"); testTimeRangeFormatParse(); // these are tests that used to be in test009. Datum now = TimeUtil.now(); System.err.println("now= " + now); int micros = 60000000; doTest(40, "P1D", new DatumRange(now.subtract(1, Units.days), now).toString(), micros, true); doTest(41, "PT1H", new DatumRange(now.subtract(1, Units.hours), now).toString(), micros, true); doTest(42, "orbit:rbspa-pp:403", "2013-01-27T18:58:17.392Z to 2013-01-28T03:57:01.358Z", micros, false); doTest(43, "orbit:rbspa-pp:403-406", "2013-01-27T18:58:17.392Z to 2013-01-29T06:53:13.619Z", micros, false); doTest(44, "1972/now-P1D", "1972-01-01T00:00/" + now.subtract(1, Units.days), micros, true); doTest(45, "now-P10D/now-P1D", new DatumRange(now.subtract(10, Units.days), now.subtract(1, Units.days)).toString(), micros, true); // time zone support and pluses for spaces doTest(50, "2001-01-01T06:08-0600/P1D", "2001-01-01 12:08 to 2001-01-02 12:08" ); doTest(51, "2001-01-01T06:08+to+10:08", "2001-01-01 06:08 to 2001-01-01 10:08" ); doTest(52, "20010101T0608-0600/P1D", "2001-01-01 12:08 to 2001-01-02 12:08" ); doTest(53, "20010101T0608+0600/P1D", "2001-01-01 00:08 to 2001-01-02 00:08" ); // Note the plus here is interpretted as a space in some codes, so make sure this case is handled. int[] tt= TimeUtil.fromDatum(now); tt[2]=1; tt[3]=0; tt[4]=0; tt[5]=0; tt[6]=0; Datum t2= TimeUtil.toDatum(tt); tt[1]--; if ( tt[1]==0 ) { tt[0]--; tt[1]=12; } Datum t1= TimeUtil.toDatum(tt); doTest(46, "P1M/lastmonth", t1.toString()+"/"+t2.toString(), micros, false); // these things closeHTML(); //closes body and html System.exit(0); // TODO: something is firing up the event thread } catch (Exception ex) { ex.printStackTrace(); System.exit(1); } } }