/*
* 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<Integer,String> 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 = "<html>";
String headerString = "<head><title>Test 026</title></head>";
String bodyString = "<body style=\"background-color: #6B6B6B; margin=0;\">";
String headerOpen = "<div style=\"top: 0px; margin-right=0px; font-size:40px; background-color:black; color:white;height:100px;\">"
+ "TEST COMPARISON TABLE (Test026.java)" + "</div>";
String tableOpen = "<table border=\"1\" style=\"width:100%; color:white;\">\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 = "</table></body></html>";
bw.write(htmlClose); //closes html page
bw.close(); //closes buffer
}
public static void writeToHTML(int id, String test, String ref) throws IOException {
String table = "<tr><td><strong>Test Number:</strong> " + id + "</td>"
+ "<td><strong>Test: </strong> " + test + "</td>"
+ "<td><strong>Ref: </strong> " + ref + "</td></tr>\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);
}
}
}