use correct timezone

git-svn-id: https://public-transport-enabler.googlecode.com/svn/trunk@536 0924bc21-9374-b0fa-ee44-9ff1593b38f0
This commit is contained in:
andreas.schildbach@gmail.com 2011-03-26 13:46:26 +00:00
parent 2524ad72b3
commit acdec06e61
15 changed files with 417 additions and 351 deletions

View file

@ -322,7 +322,8 @@ public abstract class AbstractEfaProvider implements NetworkProvider
if (parsedMapName != null)
{
final int parsedLocationId = XmlPullUtil.intAttr(pp, "stopID");
final String parsedLongName = normalizeLocationName(XmlPullUtil.attr(pp, "nameWithPlace"));
// final String parsedLongName = normalizeLocationName(XmlPullUtil.attr(pp,
// "nameWithPlace"));
final String parsedPlace = normalizeLocationName(XmlPullUtil.attr(pp, "place"));
final int parsedLon = XmlPullUtil.intAttr(pp, "x");
final int parsedLat = XmlPullUtil.intAttr(pp, "y");
@ -755,6 +756,8 @@ public abstract class AbstractEfaProvider implements NetworkProvider
return 'R' + name;
if ("CAPITOL".equals(name)) // San Francisco
return 'R' + name;
if ("Train".equals(noTrainName)) // San Francisco
return "R" + name;
if ("Regional Train :".equals(longName))
return "R";
if ("Regional Train".equals(noTrainName)) // Melbourne
@ -940,10 +943,8 @@ public abstract class AbstractEfaProvider implements NetworkProvider
if (XmlPullUtil.test(pp, "itdMessage"))
XmlPullUtil.next(pp);
final Calendar plannedDepartureTime = new GregorianCalendar();
plannedDepartureTime.setTimeZone(timeZone());
final Calendar predictedDepartureTime = new GregorianCalendar();
predictedDepartureTime.setTimeZone(timeZone());
final Calendar plannedDepartureTime = new GregorianCalendar(timeZone());
final Calendar predictedDepartureTime = new GregorianCalendar(timeZone());
XmlPullUtil.require(pp, "itdServingLines");
if (!pp.isEmptyElementTag())
@ -1072,6 +1073,7 @@ public abstract class AbstractEfaProvider implements NetworkProvider
private void processItdDateTime(final XmlPullParser pp, final Calendar calendar) throws XmlPullParserException, IOException
{
XmlPullUtil.enter(pp);
calendar.clear();
processItdDate(pp, calendar);
processItdTime(pp, calendar);
XmlPullUtil.exit(pp);
@ -1264,9 +1266,9 @@ public abstract class AbstractEfaProvider implements NetworkProvider
}
XmlPullUtil.exit(pp, "itdDateTime");
final Calendar departureTime = new GregorianCalendar(), arrivalTime = new GregorianCalendar(), stopTime = new GregorianCalendar();
departureTime.setTimeZone(timeZone());
arrivalTime.setTimeZone(timeZone());
final Calendar departureTime = new GregorianCalendar(timeZone());
final Calendar arrivalTime = new GregorianCalendar(timeZone());
final Calendar stopTime = new GregorianCalendar(timeZone());
final List<Connection> connections = new ArrayList<Connection>();
if (XmlPullUtil.jumpToStartTag(pp, null, "itdRouteList"))

View file

@ -20,7 +20,6 @@ package de.schildbach.pte;
import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
@ -29,6 +28,7 @@ import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -65,6 +65,11 @@ public abstract class AbstractHafasProvider implements NetworkProvider
this.accessId = accessId;
}
protected TimeZone timeZone()
{
return TimeZone.getTimeZone("CET");
}
protected String[] splitNameAndPlace(final String name)
{
return new String[] { null, name };
@ -252,8 +257,6 @@ public abstract class AbstractHafasProvider implements NetworkProvider
// System.out.println(request);
// ParserUtils.printXml(ParserUtils.scrape(apiUri, true, wrap(request), null, false));
final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMdd");
InputStream is = null;
try
@ -314,8 +317,9 @@ public abstract class AbstractHafasProvider implements NetworkProvider
XmlPullUtil.enter(pp, "Overview");
XmlPullUtil.require(pp, "Date");
final Calendar currentDate = new GregorianCalendar();
currentDate.setTime(DATE_FORMAT.parse(XmlPullUtil.text(pp)));
final Calendar currentDate = new GregorianCalendar(timeZone());
currentDate.clear();
parseDate(currentDate, XmlPullUtil.text(pp));
XmlPullUtil.enter(pp, "Departure");
XmlPullUtil.enter(pp, "BasicStop");
while (pp.getName().equals("StAttrList"))
@ -352,7 +356,9 @@ public abstract class AbstractHafasProvider implements NetworkProvider
final Location sectionDeparture = parseLocation(pp);
XmlPullUtil.enter(pp, "Dep");
XmlPullUtil.require(pp, "Time");
final Date departureTime = parseTime(currentDate, XmlPullUtil.text(pp));
final Calendar departureTime = new GregorianCalendar(timeZone());
departureTime.setTimeInMillis(currentDate.getTimeInMillis());
parseTime(departureTime, XmlPullUtil.text(pp));
XmlPullUtil.enter(pp, "Platform");
XmlPullUtil.require(pp, "Text");
String departurePos = XmlPullUtil.text(pp).trim();
@ -434,7 +440,9 @@ public abstract class AbstractHafasProvider implements NetworkProvider
final Location sectionArrival = parseLocation(pp);
XmlPullUtil.enter(pp, "Arr");
XmlPullUtil.require(pp, "Time");
final Date arrivalTime = parseTime(currentDate, XmlPullUtil.text(pp));
final Calendar arrivalTime = new GregorianCalendar(timeZone());
arrivalTime.setTimeInMillis(currentDate.getTimeInMillis());
parseTime(arrivalTime, XmlPullUtil.text(pp));
XmlPullUtil.enter(pp, "Platform");
XmlPullUtil.require(pp, "Text");
String arrivalPos = XmlPullUtil.text(pp).trim();
@ -451,8 +459,8 @@ public abstract class AbstractHafasProvider implements NetworkProvider
if (min == 0 || line != null)
{
parts.add(new Connection.Trip(line, destination, departureTime, departurePos, sectionDeparture, arrivalTime, arrivalPos,
sectionArrival, null, null));
parts.add(new Connection.Trip(line, destination, departureTime.getTime(), departurePos, sectionDeparture, arrivalTime
.getTime(), arrivalPos, sectionArrival, null, null));
}
else
{
@ -468,8 +476,8 @@ public abstract class AbstractHafasProvider implements NetworkProvider
}
if (firstDepartureTime == null)
firstDepartureTime = departureTime;
lastArrivalTime = arrivalTime;
firstDepartureTime = departureTime.getTime();
lastArrivalTime = arrivalTime.getTime();
}
XmlPullUtil.exit(pp);
@ -487,10 +495,6 @@ public abstract class AbstractHafasProvider implements NetworkProvider
{
throw new RuntimeException(x);
}
catch (final ParseException x)
{
throw new RuntimeException(x);
}
finally
{
if (is != null)
@ -531,39 +535,43 @@ public abstract class AbstractHafasProvider implements NetworkProvider
return attributeVariants;
}
private static final Pattern P_DATE = Pattern.compile("(\\d{4})(\\d{2})(\\d{2})");
private static final void parseDate(final Calendar calendar, final CharSequence str)
{
final Matcher m = P_DATE.matcher(str);
if (!m.matches())
throw new RuntimeException("cannot parse: '" + str + "'");
calendar.set(Calendar.YEAR, Integer.parseInt(m.group(1)));
calendar.set(Calendar.MONTH, Integer.parseInt(m.group(2)) - 1);
calendar.set(Calendar.DAY_OF_MONTH, Integer.parseInt(m.group(3)));
}
private static final Pattern P_TIME = Pattern.compile("(\\d+)d(\\d+):(\\d{2}):(\\d{2})");
private Date parseTime(final Calendar currentDate, final String str)
private static void parseTime(final Calendar calendar, final CharSequence str)
{
final Matcher m = P_TIME.matcher(str);
if (m.matches())
{
final Calendar c = new GregorianCalendar();
c.set(Calendar.YEAR, currentDate.get(Calendar.YEAR));
c.set(Calendar.MONTH, currentDate.get(Calendar.MONTH));
c.set(Calendar.DAY_OF_MONTH, currentDate.get(Calendar.DAY_OF_MONTH));
c.set(Calendar.HOUR_OF_DAY, Integer.parseInt(m.group(2)));
c.set(Calendar.MINUTE, Integer.parseInt(m.group(3)));
c.set(Calendar.SECOND, Integer.parseInt(m.group(4)));
c.set(Calendar.MILLISECOND, 0);
c.add(Calendar.DAY_OF_MONTH, Integer.parseInt(m.group(1)));
return c.getTime();
}
else
{
throw new IllegalArgumentException("cannot parse duration: " + str);
}
if (!m.matches())
throw new IllegalArgumentException("cannot parse: '" + str + "'");
calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(m.group(2)));
calendar.set(Calendar.MINUTE, Integer.parseInt(m.group(3)));
calendar.set(Calendar.SECOND, Integer.parseInt(m.group(4)));
calendar.set(Calendar.MILLISECOND, 0);
calendar.add(Calendar.DAY_OF_MONTH, Integer.parseInt(m.group(1)));
}
private static final Pattern P_DURATION = Pattern.compile("(\\d+):(\\d{2})");
private final int parseDuration(final String str)
private static final int parseDuration(final CharSequence str)
{
final Matcher m = P_DURATION.matcher(str);
if (m.matches())
return Integer.parseInt(m.group(1)) * 60 + Integer.parseInt(m.group(2));
else
throw new IllegalArgumentException("cannot parse duration: " + str);
throw new IllegalArgumentException("cannot parse duration: '" + str + "'");
}
private static final String location(final Location location)

View file

@ -242,8 +242,10 @@ public final class BahnProvider extends AbstractHafasProvider
{
final Location from = new Location(LocationType.ANY, 0, null, ParserUtils.resolveEntities(mHead.group(1)));
final Location to = new Location(LocationType.ANY, 0, null, ParserUtils.resolveEntities(mHead.group(2)));
final Date currentDate = ParserUtils.parseDate(mHead.group(3));
final String linkEarlier = mHead.group(4) != null ? ParserUtils.resolveEntities(mHead.group(4)) : null;
final Calendar currentDate = new GregorianCalendar(timeZone());
currentDate.clear();
ParserUtils.parseGermanDate(currentDate, mHead.group(3));
// final String linkEarlier = mHead.group(4) != null ? ParserUtils.resolveEntities(mHead.group(4)) : null;
final String linkLater = mHead.group(5) != null ? ParserUtils.resolveEntities(mHead.group(5)) : null;
final List<Connection> connections = new ArrayList<Connection>();
@ -254,20 +256,24 @@ public final class BahnProvider extends AbstractHafasProvider
if (mConFine.matches())
{
final String link = ParserUtils.resolveEntities(mConFine.group(1));
Date departureTime = ParserUtils.joinDateTime(currentDate, ParserUtils.parseTime(mConFine.group(2)));
final Calendar departureTime = new GregorianCalendar(timeZone());
departureTime.setTimeInMillis(currentDate.getTimeInMillis());
ParserUtils.parseEuropeanTime(departureTime, mConFine.group(2));
if (!connections.isEmpty())
{
final long diff = ParserUtils.timeDiff(departureTime, connections.get(connections.size() - 1).departureTime);
final long diff = departureTime.getTimeInMillis() - connections.get(connections.size() - 1).departureTime.getTime();
if (diff > PARSER_DAY_ROLLOVER_THRESHOLD_MS)
departureTime = ParserUtils.addDays(departureTime, -1);
departureTime.add(Calendar.DAY_OF_YEAR, -1);
else if (diff < -PARSER_DAY_ROLLOVER_THRESHOLD_MS)
departureTime = ParserUtils.addDays(departureTime, 1);
departureTime.add(Calendar.DAY_OF_YEAR, 1);
}
Date arrivalTime = ParserUtils.joinDateTime(currentDate, ParserUtils.parseTime(mConFine.group(3)));
final Calendar arrivalTime = new GregorianCalendar(timeZone());
arrivalTime.setTimeInMillis(currentDate.getTimeInMillis());
ParserUtils.parseEuropeanTime(arrivalTime, mConFine.group(3));
if (departureTime.after(arrivalTime))
arrivalTime = ParserUtils.addDays(arrivalTime, 1);
final Connection connection = new Connection(AbstractHafasProvider.extractConnectionId(link), link, departureTime, arrivalTime,
from, to, null, null);
arrivalTime.add(Calendar.DAY_OF_YEAR, 1);
final Connection connection = new Connection(AbstractHafasProvider.extractConnectionId(link), link, departureTime.getTime(),
arrivalTime.getTime(), from, to, null, null);
connections.add(connection);
}
else
@ -353,31 +359,31 @@ public final class BahnProvider extends AbstractHafasProvider
final String lineStr = normalizeLine(ParserUtils.resolveEntities(mDetFine.group(2)));
final Line line = new Line(lineStr, lineColors(lineStr));
final Date departureTime = ParserUtils.parseTime(mDetFine.group(3));
final Calendar departureTime = new GregorianCalendar(timeZone());
departureTime.clear();
ParserUtils.parseEuropeanTime(departureTime, mDetFine.group(3));
ParserUtils.parseGermanDate(departureTime, mDetFine.group(5));
final String departurePosition = ParserUtils.resolveEntities(mDetFine.group(4));
final Date departureDate = ParserUtils.parseDate(mDetFine.group(5));
final Location arrival = new Location(LocationType.ANY, 0, null, ParserUtils.resolveEntities(mDetFine.group(6)));
final Date arrivalTime = ParserUtils.parseTime(mDetFine.group(7));
final Calendar arrivalTime = new GregorianCalendar(timeZone());
arrivalTime.clear();
ParserUtils.parseEuropeanTime(arrivalTime, mDetFine.group(7));
ParserUtils.parseGermanDate(arrivalTime, mDetFine.group(9));
final String arrivalPosition = ParserUtils.resolveEntities(mDetFine.group(8));
final Date arrivalDate = ParserUtils.parseDate(mDetFine.group(9));
final Date departureDateTime = ParserUtils.joinDateTime(departureDate, departureTime);
final Date arrivalDateTime = ParserUtils.joinDateTime(arrivalDate, arrivalTime);
lastTrip = new Connection.Trip(line, null, departureDateTime, departurePosition, departure, arrivalDateTime,
lastTrip = new Connection.Trip(line, null, departureTime.getTime(), departurePosition, departure, arrivalTime.getTime(),
arrivalPosition, arrival, null, null);
parts.add(lastTrip);
if (firstDepartureTime == null)
firstDepartureTime = departureDateTime;
firstDepartureTime = departureTime.getTime();
lastArrival = arrival;
lastArrivalTime = arrivalDateTime;
lastArrivalTime = arrivalTime.getTime();
}
else if (mDetFine.group(10) != null)
{
@ -415,8 +421,9 @@ public final class BahnProvider extends AbstractHafasProvider
if (firstDepartureTime == null || lastArrivalTime == null)
throw new IllegalStateException("could not parse all parts of:\n" + mHead.group(1) + "\n" + parts);
return new GetConnectionDetailsResult(new Date(), new Connection(AbstractHafasProvider.extractConnectionId(uri), uri, firstDepartureTime,
lastArrivalTime, firstDeparture, lastArrival, parts, null));
return new GetConnectionDetailsResult(new GregorianCalendar(timeZone()).getTime(), new Connection(
AbstractHafasProvider.extractConnectionId(uri), uri, firstDepartureTime, lastArrivalTime, firstDeparture, lastArrival, parts,
null));
}
else
{
@ -479,7 +486,6 @@ public final class BahnProvider extends AbstractHafasProvider
}
final List<Departure> departures = new ArrayList<Departure>(8);
final Calendar calendar = new GregorianCalendar();
final Matcher mDepCoarse = P_DEPARTURES_COARSE.matcher(page);
while (mDepCoarse.find())
@ -489,15 +495,21 @@ public final class BahnProvider extends AbstractHafasProvider
{
if (mDepFine.group(8) == null)
{
final Date plannedTime = ParserUtils.joinDateTime(ParserUtils.parseDate(mDepFine.group(2)),
ParserUtils.parseTime(mDepFine.group(1)));
final Calendar plannedTime = new GregorianCalendar(timeZone());
plannedTime.clear();
ParserUtils.parseEuropeanTime(plannedTime, mDepFine.group(1));
ParserUtils.parseGermanDate(plannedTime, mDepFine.group(2));
Date predictedTime = null;
final Calendar predictedTime;
if (mDepFine.group(3) != null)
{
calendar.setTime(plannedTime);
calendar.add(Calendar.MINUTE, Integer.parseInt(mDepFine.group(3)));
predictedTime = calendar.getTime();
predictedTime = new GregorianCalendar(timeZone());
predictedTime.setTimeInMillis(plannedTime.getTimeInMillis());
predictedTime.add(Calendar.MINUTE, Integer.parseInt(mDepFine.group(3)));
}
else
{
predictedTime = null;
}
final String position = mDepFine.group(4) != null ? "Gl. " + ParserUtils.resolveEntities(mDepFine.group(4)) : null;
@ -508,8 +520,8 @@ public final class BahnProvider extends AbstractHafasProvider
final String message = ParserUtils.resolveEntities(mDepFine.group(9));
departures.add(new Departure(plannedTime, predictedTime, line, line != null ? lineColors(line) : null, null, position, 0,
destination, message));
departures.add(new Departure(plannedTime.getTime(), predictedTime != null ? predictedTime.getTime() : null, line,
line != null ? lineColors(line) : null, null, position, 0, destination, message));
}
}
else

View file

@ -27,7 +27,6 @@ import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -53,7 +52,6 @@ public final class BvgProvider extends AbstractHafasProvider
{
public static final NetworkId NETWORK_ID = NetworkId.BVG;
public static final String OLD_NETWORK_ID = "mobil.bvg.de";
private static final TimeZone TIME_ZONE = TimeZone.getTimeZone("Europe/Berlin");
private static final long PARSER_DAY_ROLLOVER_THRESHOLD_MS = 12 * 60 * 60 * 1000;
private static final long PARSER_DAY_ROLLDOWN_THRESHOLD_MS = 6 * 60 * 60 * 1000;
@ -384,10 +382,11 @@ public final class BvgProvider extends AbstractHafasProvider
{
final Location from = location(ParserUtils.resolveEntities(mHead.group(1)), originalFrom);
final Location to = location(ParserUtils.resolveEntities(mHead.group(2)), originalTo);
final Calendar currentDate = new GregorianCalendar(TIME_ZONE);
final Calendar currentDate = new GregorianCalendar(timeZone());
currentDate.clear();
ParserUtils.parseGermanDate(currentDate, mHead.group(3));
final String linkEarlier = mHead.group(4) != null ? BVG_BASE_URL + ParserUtils.resolveEntities(mHead.group(4)) : null;
// final String linkEarlier = mHead.group(4) != null ? BVG_BASE_URL +
// ParserUtils.resolveEntities(mHead.group(4)) : null;
final String linkLater = mHead.group(5) != null ? BVG_BASE_URL + ParserUtils.resolveEntities(mHead.group(5)) : null;
final List<Connection> connections = new ArrayList<Connection>();
@ -398,7 +397,7 @@ public final class BvgProvider extends AbstractHafasProvider
if (mConFine.matches())
{
final String link = BVG_BASE_URL + ParserUtils.resolveEntities(mConFine.group(1));
final Calendar departureTime = new GregorianCalendar(TIME_ZONE);
final Calendar departureTime = new GregorianCalendar(timeZone());
departureTime.setTimeInMillis(currentDate.getTimeInMillis());
ParserUtils.parseEuropeanTime(departureTime, mConFine.group(2));
if (!connections.isEmpty())
@ -409,7 +408,7 @@ public final class BvgProvider extends AbstractHafasProvider
else if (diff < -PARSER_DAY_ROLLDOWN_THRESHOLD_MS)
departureTime.add(Calendar.DAY_OF_YEAR, 1);
}
final Calendar arrivalTime = new GregorianCalendar(TIME_ZONE);
final Calendar arrivalTime = new GregorianCalendar(timeZone());
arrivalTime.setTimeInMillis(currentDate.getTimeInMillis());
ParserUtils.parseEuropeanTime(arrivalTime, mConFine.group(3));
if (departureTime.after(arrivalTime))
@ -466,7 +465,7 @@ public final class BvgProvider extends AbstractHafasProvider
final Matcher mHead = P_CONNECTION_DETAILS_HEAD.matcher(page);
if (mHead.matches())
{
final Calendar currentDate = new GregorianCalendar(TIME_ZONE);
final Calendar currentDate = new GregorianCalendar(timeZone());
currentDate.clear();
ParserUtils.parseGermanDate(currentDate, mHead.group(1));
final List<Connection.Part> parts = new ArrayList<Connection.Part>(4);
@ -506,7 +505,7 @@ public final class BvgProvider extends AbstractHafasProvider
final String min = mDetFine.group(14);
if (min == null)
{
final Calendar departureTime = new GregorianCalendar(TIME_ZONE);
final Calendar departureTime = new GregorianCalendar(timeZone());
departureTime.setTimeInMillis(currentDate.getTimeInMillis());
ParserUtils.parseEuropeanTime(departureTime, mDetFine.group(6));
if (lastArrivalTime != null && departureTime.getTime().before(lastArrivalTime))
@ -521,7 +520,7 @@ public final class BvgProvider extends AbstractHafasProvider
final Location destination = new Location(LocationType.ANY, 0, destinationPlaceAndName[0], destinationPlaceAndName[1]);
final Calendar arrivalTime = new GregorianCalendar(TIME_ZONE);
final Calendar arrivalTime = new GregorianCalendar(timeZone());
arrivalTime.setTimeInMillis(currentDate.getTimeInMillis());
ParserUtils.parseEuropeanTime(arrivalTime, mDetFine.group(10));
if (departureTime.after(arrivalTime))
@ -659,7 +658,7 @@ public final class BvgProvider extends AbstractHafasProvider
if (mHead.matches())
{
final String location = ParserUtils.resolveEntities(mHead.group(1));
final Calendar currentTime = new GregorianCalendar(TIME_ZONE);
final Calendar currentTime = new GregorianCalendar(timeZone());
currentTime.clear();
parseDateTime(currentTime, mHead.group(2));
final List<Departure> departures = new ArrayList<Departure>(8);
@ -671,7 +670,7 @@ public final class BvgProvider extends AbstractHafasProvider
final Matcher mDepFine = P_DEPARTURES_LIVE_FINE.matcher(mDepCoarse.group(1));
if (mDepFine.matches())
{
final Calendar parsedTime = new GregorianCalendar(TIME_ZONE);
final Calendar parsedTime = new GregorianCalendar(timeZone());
parsedTime.setTimeInMillis(currentTime.getTimeInMillis());
ParserUtils.parseEuropeanTime(parsedTime, mDepFine.group(1));
@ -737,7 +736,7 @@ public final class BvgProvider extends AbstractHafasProvider
if (mHead.matches())
{
final String location = ParserUtils.resolveEntities(mHead.group(1));
final Calendar currentTime = new GregorianCalendar(TIME_ZONE);
final Calendar currentTime = new GregorianCalendar(timeZone());
currentTime.clear();
ParserUtils.parseGermanDate(currentTime, mHead.group(2));
final List<Departure> departures = new ArrayList<Departure>(8);
@ -749,7 +748,7 @@ public final class BvgProvider extends AbstractHafasProvider
final Matcher mDepFine = P_DEPARTURES_PLAN_FINE.matcher(mDepCoarse.group(1));
if (mDepFine.matches())
{
final Calendar parsedTime = new GregorianCalendar(TIME_ZONE);
final Calendar parsedTime = new GregorianCalendar(timeZone());
parsedTime.setTimeInMillis(currentTime.getTimeInMillis());
ParserUtils.parseEuropeanTime(parsedTime, mDepFine.group(1));

View file

@ -215,8 +215,10 @@ public class InvgProvider extends AbstractHafasProvider
if (mHeadFine.matches())
{
final String location = ParserUtils.resolveEntities(mHeadFine.group(1));
final Date currentTime = ParserUtils.joinDateTime(ParserUtils.parseDate(mHeadFine.group(2)),
ParserUtils.parseTime(mHeadFine.group(3)));
final Calendar currentTime = new GregorianCalendar(timeZone());
currentTime.clear();
ParserUtils.parseGermanDate(currentTime, mHeadFine.group(2));
ParserUtils.parseEuropeanTime(currentTime, mHeadFine.group(3));
final List<Departure> departures = new ArrayList<Departure>(8);
String oldZebra = null;
@ -232,26 +234,31 @@ public class InvgProvider extends AbstractHafasProvider
final Matcher mDepFine = P_DEPARTURES_FINE.matcher(mDepCoarse.group(2));
if (mDepFine.matches())
{
final Calendar current = new GregorianCalendar();
current.setTime(currentTime);
final Calendar parsed = new GregorianCalendar();
parsed.setTime(ParserUtils.parseTime(mDepFine.group(1)));
parsed.set(Calendar.YEAR, current.get(Calendar.YEAR));
parsed.set(Calendar.MONTH, current.get(Calendar.MONTH));
parsed.set(Calendar.DAY_OF_MONTH, current.get(Calendar.DAY_OF_MONTH));
if (ParserUtils.timeDiff(parsed.getTime(), currentTime) < -PARSER_DAY_ROLLOVER_THRESHOLD_MS)
parsed.add(Calendar.DAY_OF_MONTH, 1);
final Calendar plannedTime = new GregorianCalendar(timeZone());
plannedTime.setTimeInMillis(currentTime.getTimeInMillis());
ParserUtils.parseEuropeanTime(plannedTime, mDepFine.group(1));
final Date plannedTime = parsed.getTime();
if (plannedTime.getTimeInMillis() - currentTime.getTimeInMillis() < -PARSER_DAY_ROLLOVER_THRESHOLD_MS)
plannedTime.add(Calendar.DAY_OF_MONTH, 1);
Date predictedTime = null;
final Calendar predictedTime;
final String prognosis = ParserUtils.resolveEntities(mDepFine.group(2));
if (prognosis != null)
{
predictedTime = new GregorianCalendar(timeZone());
if (prognosis.equals("pünktlich"))
predictedTime = plannedTime;
{
predictedTime.setTimeInMillis(plannedTime.getTimeInMillis());
}
else
predictedTime = ParserUtils.joinDateTime(currentTime, ParserUtils.parseTime(prognosis));
{
predictedTime.setTimeInMillis(currentTime.getTimeInMillis());
ParserUtils.parseEuropeanTime(predictedTime, prognosis);
}
}
else
{
predictedTime = null;
}
final String lineType = mDepFine.group(3);
@ -264,8 +271,8 @@ public class InvgProvider extends AbstractHafasProvider
final String position = mDepFine.group(7) != null ? "Gl. " + ParserUtils.resolveEntities(mDepFine.group(7)) : null;
final Departure dep = new Departure(plannedTime, predictedTime, line, line != null ? lineColors(line) : null, null, position,
destinationId, destination, null);
final Departure dep = new Departure(plannedTime.getTime(), predictedTime != null ? predictedTime.getTime() : null, line,
line != null ? lineColors(line) : null, null, position, destinationId, destination, null);
if (!departures.contains(dep))
departures.add(dep);

View file

@ -161,8 +161,10 @@ public class NasaProvider extends AbstractHafasProvider
if (mHeadFine.matches())
{
final String location = ParserUtils.resolveEntities(mHeadFine.group(1));
final Date currentTime = ParserUtils.joinDateTime(ParserUtils.parseDate(mHeadFine.group(2)),
ParserUtils.parseTime(mHeadFine.group(3)));
final Calendar currentTime = new GregorianCalendar(timeZone());
currentTime.clear();
ParserUtils.parseGermanDate(currentTime, mHeadFine.group(2));
ParserUtils.parseEuropeanTime(currentTime, mHeadFine.group(3));
final List<Departure> departures = new ArrayList<Departure>(8);
String oldZebra = null;
@ -178,26 +180,31 @@ public class NasaProvider extends AbstractHafasProvider
final Matcher mDepFine = P_DEPARTURES_FINE.matcher(mDepCoarse.group(2));
if (mDepFine.matches())
{
final Calendar current = new GregorianCalendar();
current.setTime(currentTime);
final Calendar parsed = new GregorianCalendar();
parsed.setTime(ParserUtils.parseTime(mDepFine.group(1)));
parsed.set(Calendar.YEAR, current.get(Calendar.YEAR));
parsed.set(Calendar.MONTH, current.get(Calendar.MONTH));
parsed.set(Calendar.DAY_OF_MONTH, current.get(Calendar.DAY_OF_MONTH));
if (ParserUtils.timeDiff(parsed.getTime(), currentTime) < -PARSER_DAY_ROLLOVER_THRESHOLD_MS)
parsed.add(Calendar.DAY_OF_MONTH, 1);
final Calendar plannedTime = new GregorianCalendar(timeZone());
plannedTime.setTimeInMillis(currentTime.getTimeInMillis());
ParserUtils.parseEuropeanTime(plannedTime, mDepFine.group(1));
final Date plannedTime = parsed.getTime();
if (plannedTime.getTimeInMillis() - currentTime.getTimeInMillis() < -PARSER_DAY_ROLLOVER_THRESHOLD_MS)
plannedTime.add(Calendar.DAY_OF_MONTH, 1);
Date predictedTime = null;
final Calendar predictedTime;
final String prognosis = ParserUtils.resolveEntities(mDepFine.group(2));
if (prognosis != null)
{
predictedTime = new GregorianCalendar(timeZone());
if (prognosis.equals("pünktlich"))
predictedTime = plannedTime;
{
predictedTime.setTimeInMillis(plannedTime.getTimeInMillis());
}
else
predictedTime = ParserUtils.joinDateTime(currentTime, ParserUtils.parseTime(prognosis));
{
predictedTime.setTimeInMillis(currentTime.getTimeInMillis());
ParserUtils.parseEuropeanTime(predictedTime, prognosis);
}
}
else
{
predictedTime = null;
}
final String lineType = mDepFine.group(3);
@ -210,8 +217,8 @@ public class NasaProvider extends AbstractHafasProvider
final String position = mDepFine.group(7) != null ? "Gl. " + ParserUtils.resolveEntities(mDepFine.group(7)) : null;
final Departure dep = new Departure(plannedTime, predictedTime, line, line != null ? lineColors(line) : null, null, position,
destinationId, destination, null);
final Departure dep = new Departure(plannedTime.getTime(), predictedTime != null ? predictedTime.getTime() : null, line,
line != null ? lineColors(line) : null, null, position, destinationId, destination, null);
if (!departures.contains(dep))
departures.add(dep);

View file

@ -20,7 +20,6 @@ package de.schildbach.pte;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.regex.Matcher;
@ -129,8 +128,10 @@ public class NsProvider extends AbstractHafasProvider
if (mHeadFine.matches())
{
final String location = ParserUtils.resolveEntities(mHeadFine.group(1));
final Date currentTime = ParserUtils.joinDateTime(ParserUtils.parseDateSlash(mHeadFine.group(3)),
ParserUtils.parseTime(mHeadFine.group(2)));
final Calendar currentTime = new GregorianCalendar(timeZone());
currentTime.clear();
ParserUtils.parseEuropeanTime(currentTime, mHeadFine.group(2));
ParserUtils.parseGermanDate(currentTime, mHeadFine.group(3));
final List<Departure> departures = new ArrayList<Departure>(8);
final Matcher mDepCoarse = P_DEPARTURES_COARSE.matcher(mHeadCoarse.group(2));
@ -143,19 +144,16 @@ public class NsProvider extends AbstractHafasProvider
final String destination = ParserUtils.resolveEntities(mDepFine.group(2));
final Calendar current = new GregorianCalendar();
current.setTime(currentTime);
final Calendar parsed = new GregorianCalendar();
parsed.setTime(ParserUtils.parseTime(mDepFine.group(3)));
parsed.set(Calendar.YEAR, current.get(Calendar.YEAR));
parsed.set(Calendar.MONTH, current.get(Calendar.MONTH));
parsed.set(Calendar.DAY_OF_MONTH, current.get(Calendar.DAY_OF_MONTH));
if (ParserUtils.timeDiff(parsed.getTime(), currentTime) < -PARSER_DAY_ROLLOVER_THRESHOLD_MS)
parsed.add(Calendar.DAY_OF_MONTH, 1);
final Calendar parsedTime = new GregorianCalendar(timeZone());
parsedTime.setTimeInMillis(currentTime.getTimeInMillis());
ParserUtils.parseEuropeanTime(parsedTime, mDepFine.group(3));
if (parsedTime.getTimeInMillis() - currentTime.getTimeInMillis() < -PARSER_DAY_ROLLOVER_THRESHOLD_MS)
parsedTime.add(Calendar.DAY_OF_MONTH, 1);
mDepFine.group(4); // TODO delay
final Departure dep = new Departure(parsed.getTime(), line, line != null ? lineColors(line) : null, null, 0, destination);
final Departure dep = new Departure(parsedTime.getTime(), line, line != null ? lineColors(line) : null, null, 0, destination);
if (!departures.contains(dep))
departures.add(dep);

View file

@ -21,7 +21,9 @@ import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -387,13 +389,13 @@ public class OebbProvider extends AbstractHafasProvider
{
final Location from = new Location(LocationType.ANY, 0, null, ParserUtils.resolveEntities(mHead.group(1)));
final Location to = new Location(LocationType.ANY, 0, null, ParserUtils.resolveEntities(mHead.group(2)));
final Date currentDate = ParserUtils.parseDate(mHead.group(3));
final String linkEarlier = mHead.group(4) != null ? ParserUtils.resolveEntities(mHead.group(4)) : null;
final Calendar time = new GregorianCalendar(timeZone());
time.clear();
ParserUtils.parseGermanDate(time, mHead.group(3));
// final String linkEarlier = mHead.group(4) != null ? ParserUtils.resolveEntities(mHead.group(4)) : null;
final String linkLater = mHead.group(5) != null ? ParserUtils.resolveEntities(mHead.group(5)) : null;
final List<Connection> connections = new ArrayList<Connection>();
Date lastDate = currentDate;
final Matcher mConCoarse = P_CONNECTIONS_COARSE.matcher(page);
while (mConCoarse.find())
{
@ -404,14 +406,20 @@ public class OebbProvider extends AbstractHafasProvider
final Matcher mConFine = P_CONNECTIONS_FINE.matcher(overview);
if (mConFine.matches())
{
final Date overviewDepartureDate = ParserUtils.parseDate(mConFine.group(1));
final Date overviewArrivalDate = mConFine.group(2) != null ? ParserUtils.parseDate(mConFine.group(2)) : null;
final Date overviewDepartureTime = ParserUtils.joinDateTime(overviewDepartureDate, ParserUtils.parseTime(mConFine.group(3)));
final Date overviewArrivalTime = ParserUtils.joinDateTime(overviewArrivalDate != null ? overviewArrivalDate
: overviewDepartureDate, ParserUtils.parseTime(mConFine.group(4)));
final Calendar overviewDepartureTime = new GregorianCalendar(timeZone());
overviewDepartureTime.clear();
ParserUtils.parseGermanDate(overviewDepartureTime, mConFine.group(1));
ParserUtils.parseEuropeanTime(overviewDepartureTime, mConFine.group(3));
final Calendar overviewArrivalTime = new GregorianCalendar(timeZone());
overviewArrivalTime.setTimeInMillis(overviewDepartureTime.getTimeInMillis());
if (mConFine.group(2) != null)
ParserUtils.parseGermanDate(overviewArrivalTime, mConFine.group(2));
ParserUtils.parseEuropeanTime(overviewArrivalTime, mConFine.group(4));
final String link = allDetailsUri; // TODO use print link?
final Connection connection = new Connection(id, link, overviewDepartureTime, overviewArrivalTime, from, to,
final Connection connection = new Connection(id, link, overviewDepartureTime.getTime(), overviewArrivalTime.getTime(), from, to,
new ArrayList<Connection.Part>(1), null);
connections.add(connection);
@ -428,12 +436,10 @@ public class OebbProvider extends AbstractHafasProvider
final Location departure = new Location(departureId != 0 ? LocationType.STATION : LocationType.ANY, departureId, null,
ParserUtils.resolveEntities(mDetFine.group(2)));
Date detailsDepartureDate = mDetFine.group(3) != null ? ParserUtils.parseDate(mDetFine.group(3)) : lastDate;
if (detailsDepartureDate != null)
lastDate = detailsDepartureDate;
final Date detailsDepartureTime = ParserUtils.parseTime(mDetFine.group(4));
final Date detailsDepartureDateTime = ParserUtils.joinDateTime(detailsDepartureDate, detailsDepartureTime);
if (mDetFine.group(3) != null)
ParserUtils.parseGermanDate(time, mDetFine.group(3));
ParserUtils.parseEuropeanTime(time, mDetFine.group(4));
final Date detailsDepartureTime = time.getTime();
final String lineType = mDetFine.group(6);
@ -442,12 +448,10 @@ public class OebbProvider extends AbstractHafasProvider
final Location arrival = new Location(arrivalId != 0 ? LocationType.STATION : LocationType.ANY, arrivalId, null,
ParserUtils.resolveEntities(mDetFine.group(9)));
Date detailsArrivalDate = mDetFine.group(10) != null ? ParserUtils.parseDate(mDetFine.group(10)) : lastDate;
if (detailsArrivalDate != null)
lastDate = detailsArrivalDate;
final Date detailsArrivalTime = ParserUtils.parseTime(mDetFine.group(11));
final Date detailsArrivalDateTime = ParserUtils.joinDateTime(detailsArrivalDate, detailsArrivalTime);
if (mDetFine.group(10) != null)
ParserUtils.parseGermanDate(time, mDetFine.group(10));
ParserUtils.parseEuropeanTime(time, mDetFine.group(11));
final Date detailsArrivalTime = time.getTime();
if (!lineType.equals("fuss"))
{
@ -467,13 +471,13 @@ public class OebbProvider extends AbstractHafasProvider
final Location destination = mDetFine.group(13) != null ? new Location(LocationType.ANY, 0, null,
ParserUtils.resolveEntities(mDetFine.group(13))) : null;
final Connection.Trip trip = new Connection.Trip(line, destination, detailsDepartureDateTime, departurePosition,
departure, detailsArrivalDateTime, arrivalPosition, arrival, null, null);
final Connection.Trip trip = new Connection.Trip(line, destination, detailsDepartureTime, departurePosition,
departure, detailsArrivalTime, arrivalPosition, arrival, null, null);
connection.parts.add(trip);
}
else
{
final int min = (int) (detailsArrivalDateTime.getTime() - detailsDepartureDateTime.getTime()) / 1000 / 60;
final int min = (int) (detailsArrivalTime.getTime() - detailsDepartureTime.getTime()) / 1000 / 60;
final Connection.Footway footway = new Connection.Footway(min, departure, arrival, null);
connection.parts.add(footway);
@ -568,8 +572,10 @@ public class OebbProvider extends AbstractHafasProvider
final JSONObject departure = aDeparture.optJSONObject(i);
if (departure != null)
{
final Date time = ParserUtils.joinDateTime(ParserUtils.parseDate(departure.getString("da")),
ParserUtils.parseTime(departure.getString("ti")));
final Calendar parsedTime = new GregorianCalendar(timeZone());
parsedTime.clear();
ParserUtils.parseGermanDate(parsedTime, departure.getString("da"));
ParserUtils.parseEuropeanTime(parsedTime, departure.getString("ti"));
final String line = normalizeLine(ParserUtils.resolveEntities(departure.getString("pr")));
final String destination = ParserUtils.resolveEntities(departure.getString("st"));
String position = departure.optString("tr");
@ -578,8 +584,8 @@ public class OebbProvider extends AbstractHafasProvider
final boolean rt = head.optBoolean("rt", false);
final String lineLink = departure.optString("tinfoline");
departures.add(new Departure(!rt ? time : null, rt ? time : null, line, line != null ? lineColors(line) : null, lineLink,
position, 0, destination, null));
departures.add(new Departure(!rt ? parsedTime.getTime() : null, rt ? parsedTime.getTime() : null, line,
line != null ? lineColors(line) : null, lineLink, position, 0, destination, null));
}
}
}

View file

@ -262,8 +262,10 @@ public class RmvProvider extends AbstractHafasProvider
{
final Location from = new Location(LocationType.ANY, 0, null, ParserUtils.resolveEntities(mHead.group(1)));
final Location to = new Location(LocationType.ANY, 0, null, ParserUtils.resolveEntities(mHead.group(2)));
final Date currentDate = ParserUtils.parseDate(mHead.group(3));
final String linkEarlier = mHead.group(4) != null ? ParserUtils.resolveEntities(mHead.group(4)) : null;
final Calendar currentDate = new GregorianCalendar(timeZone());
currentDate.clear();
ParserUtils.parseGermanDate(currentDate, mHead.group(3));
// final String linkEarlier = mHead.group(4) != null ? ParserUtils.resolveEntities(mHead.group(4)) : null;
final String linkLater = mHead.group(5) != null ? ParserUtils.resolveEntities(mHead.group(5)) : null;
final List<Connection> connections = new ArrayList<Connection>();
@ -274,19 +276,24 @@ public class RmvProvider extends AbstractHafasProvider
if (mConFine.matches())
{
final String link = ParserUtils.resolveEntities(mConFine.group(1));
Date departureTime = ParserUtils.joinDateTime(currentDate, ParserUtils.parseTime(mConFine.group(2)));
final Calendar departureTime = new GregorianCalendar(timeZone());
departureTime.setTimeInMillis(currentDate.getTimeInMillis());
ParserUtils.parseEuropeanTime(departureTime, mConFine.group(2));
if (!connections.isEmpty())
{
final long diff = ParserUtils.timeDiff(departureTime, connections.get(connections.size() - 1).departureTime);
final long diff = departureTime.getTimeInMillis() - connections.get(connections.size() - 1).departureTime.getTime();
if (diff > PARSER_DAY_ROLLOVER_THRESHOLD_MS)
departureTime = ParserUtils.addDays(departureTime, -1);
departureTime.add(Calendar.DAY_OF_YEAR, -1);
else if (diff < -PARSER_DAY_ROLLOVER_THRESHOLD_MS)
departureTime = ParserUtils.addDays(departureTime, 1);
departureTime.add(Calendar.DAY_OF_YEAR, 1);
}
Date arrivalTime = ParserUtils.joinDateTime(currentDate, ParserUtils.parseTime(mConFine.group(3)));
final Calendar arrivalTime = new GregorianCalendar(timeZone());
arrivalTime.setTimeInMillis(currentDate.getTimeInMillis());
ParserUtils.parseEuropeanTime(arrivalTime, mConFine.group(3));
if (departureTime.after(arrivalTime))
arrivalTime = ParserUtils.addDays(arrivalTime, 1);
final Connection connection = new Connection(extractConnectionId(link), link, departureTime, arrivalTime, from, to, null, null);
arrivalTime.add(Calendar.DAY_OF_YEAR, 1);
final Connection connection = new Connection(extractConnectionId(link), link, departureTime.getTime(), arrivalTime.getTime(),
from, to, null, null);
connections.add(connection);
}
else
@ -337,16 +344,22 @@ public class RmvProvider extends AbstractHafasProvider
if (mHead.matches())
{
final Location firstDeparture = new Location(LocationType.ANY, 0, null, ParserUtils.resolveEntities(mHead.group(1)));
final Date currentDate = ParserUtils.parseDate(mHead.group(2));
final List<Connection.Part> parts = new ArrayList<Connection.Part>(4);
final Calendar currentDate = new GregorianCalendar(timeZone());
currentDate.clear();
ParserUtils.parseGermanDate(currentDate, mHead.group(2));
Date lastTime = currentDate;
final Calendar time = new GregorianCalendar(timeZone());
time.setTimeInMillis(currentDate.getTimeInMillis());
Date lastTime = time.getTime();
Date firstDepartureTime = null;
Date lastArrivalTime = null;
Location lastArrival = null;
Connection.Trip lastTrip = null;
final List<Connection.Part> parts = new ArrayList<Connection.Part>(4);
final Matcher mDetCoarse = P_CONNECTION_DETAILS_COARSE.matcher(page);
while (mDetCoarse.find())
{
@ -366,18 +379,50 @@ public class RmvProvider extends AbstractHafasProvider
final Location destination = new Location(LocationType.ANY, 0, null, ParserUtils.resolveEntities(mDetFine.group(2)));
final Date plannedDepartureTime = upTime(lastTime,
ParserUtils.joinDateTime(currentDate, ParserUtils.parseTime(mDetFine.group(3))));
final Date predictedDepartureTime = mDetFine.group(4) != null ? upTime(lastTime,
ParserUtils.joinDateTime(currentDate, ParserUtils.parseTime(mDetFine.group(4)))) : null;
ParserUtils.parseEuropeanTime(time, mDetFine.group(3));
if (time.getTime().before(lastTime))
time.add(Calendar.DAY_OF_YEAR, 1);
final Date plannedDepartureTime = time.getTime();
lastTime.setTime(time.getTimeInMillis());
final Date predictedDepartureTime;
if (mDetFine.group(4) != null)
{
ParserUtils.parseEuropeanTime(time, mDetFine.group(4));
if (time.getTime().before(lastTime))
time.add(Calendar.DAY_OF_YEAR, 1);
predictedDepartureTime = time.getTime();
lastTime.setTime(time.getTimeInMillis());
}
else
{
predictedDepartureTime = null;
}
final Date departureTime = predictedDepartureTime != null ? predictedDepartureTime : plannedDepartureTime;
final String departurePosition = ParserUtils.resolveEntities(mDetFine.group(5));
final Date plannedArrivalTime = upTime(lastTime,
ParserUtils.joinDateTime(currentDate, ParserUtils.parseTime(mDetFine.group(6))));
final Date predictedArrivalTime = mDetFine.group(7) != null ? upTime(lastTime,
ParserUtils.joinDateTime(currentDate, ParserUtils.parseTime(mDetFine.group(7)))) : null;
ParserUtils.parseEuropeanTime(time, mDetFine.group(6));
if (time.getTime().before(lastTime))
time.add(Calendar.DAY_OF_YEAR, 1);
final Date plannedArrivalTime = time.getTime();
lastTime.setTime(time.getTimeInMillis());
final Date predictedArrivalTime;
if (mDetFine.group(7) != null)
{
ParserUtils.parseEuropeanTime(time, mDetFine.group(7));
if (time.getTime().before(lastTime))
time.add(Calendar.DAY_OF_YEAR, 1);
predictedArrivalTime = time.getTime();
lastTime.setTime(time.getTimeInMillis());
}
else
{
predictedArrivalTime = null;
}
final Date arrivalTime = predictedArrivalTime != null ? predictedArrivalTime : plannedArrivalTime;
final String arrivalPosition = ParserUtils.resolveEntities(mDetFine.group(8));
@ -410,8 +455,8 @@ public class RmvProvider extends AbstractHafasProvider
}
}
return new GetConnectionDetailsResult(currentDate, new Connection(extractConnectionId(uri), uri, firstDepartureTime, lastArrivalTime,
firstDeparture, lastArrival, parts, null));
return new GetConnectionDetailsResult(currentDate.getTime(), new Connection(extractConnectionId(uri), uri, firstDepartureTime,
lastArrivalTime, firstDeparture, lastArrival, parts, null));
}
else
{
@ -419,16 +464,6 @@ public class RmvProvider extends AbstractHafasProvider
}
}
private static Date upTime(final Date lastTime, Date time)
{
while (time.before(lastTime))
time = ParserUtils.addDays(time, 1);
lastTime.setTime(time.getTime());
return time;
}
private String departuresQueryUri(final String stationId, final int maxDepartures)
{
final DateFormat DATE_FORMAT = new SimpleDateFormat("dd.MM.yy");
@ -499,8 +534,10 @@ public class RmvProvider extends AbstractHafasProvider
if (mHeadFine.matches())
{
final String location = ParserUtils.resolveEntities(mHeadFine.group(1));
final Date currentTime = ParserUtils.joinDateTime(ParserUtils.parseDate(mHeadFine.group(3)),
ParserUtils.parseTime(mHeadFine.group(2)));
final Calendar currentTime = new GregorianCalendar(timeZone());
currentTime.clear();
ParserUtils.parseEuropeanTime(currentTime, mHeadFine.group(2));
ParserUtils.parseGermanDate(currentTime, mHeadFine.group(3));
final List<Departure> departures = new ArrayList<Departure>(8);
final Matcher mDepCoarse = P_DEPARTURES_COARSE.matcher(mHeadCoarse.group(2));
@ -513,34 +550,32 @@ public class RmvProvider extends AbstractHafasProvider
final String destination = ParserUtils.resolveEntities(mDepFine.group(2));
final Calendar current = new GregorianCalendar();
current.setTime(currentTime);
final Calendar parsed = new GregorianCalendar();
final Calendar plannedTime = new GregorianCalendar(timeZone());
plannedTime.setTimeInMillis(currentTime.getTimeInMillis());
ParserUtils.parseEuropeanTime(plannedTime, mDepFine.group(3));
parsed.setTime(ParserUtils.parseTime(mDepFine.group(3)));
parsed.set(Calendar.YEAR, current.get(Calendar.YEAR));
parsed.set(Calendar.MONTH, current.get(Calendar.MONTH));
parsed.set(Calendar.DAY_OF_MONTH, current.get(Calendar.DAY_OF_MONTH));
if (ParserUtils.timeDiff(parsed.getTime(), currentTime) < -PARSER_DAY_ROLLOVER_THRESHOLD_MS)
parsed.add(Calendar.DAY_OF_MONTH, 1);
final Date plannedTime = parsed.getTime();
if (plannedTime.getTimeInMillis() - currentTime.getTimeInMillis() < -PARSER_DAY_ROLLOVER_THRESHOLD_MS)
plannedTime.add(Calendar.DAY_OF_MONTH, 1);
Date predictedTime = null;
final Calendar predictedTime;
if (mDepFine.group(4) != null)
{
parsed.setTime(ParserUtils.parseTime(mDepFine.group(4)));
parsed.set(Calendar.YEAR, current.get(Calendar.YEAR));
parsed.set(Calendar.MONTH, current.get(Calendar.MONTH));
parsed.set(Calendar.DAY_OF_MONTH, current.get(Calendar.DAY_OF_MONTH));
if (ParserUtils.timeDiff(parsed.getTime(), currentTime) < -PARSER_DAY_ROLLOVER_THRESHOLD_MS)
parsed.add(Calendar.DAY_OF_MONTH, 1);
predictedTime = parsed.getTime();
predictedTime = new GregorianCalendar(timeZone());
predictedTime.setTimeInMillis(currentTime.getTimeInMillis());
ParserUtils.parseEuropeanTime(predictedTime, mDepFine.group(4));
if (predictedTime.getTimeInMillis() - currentTime.getTimeInMillis() < -PARSER_DAY_ROLLOVER_THRESHOLD_MS)
predictedTime.add(Calendar.DAY_OF_MONTH, 1);
}
else
{
predictedTime = null;
}
final String position = ParserUtils.resolveEntities(ParserUtils.selectNotNull(mDepFine.group(5), mDepFine.group(6)));
final Departure dep = new Departure(plannedTime, predictedTime, line, line != null ? lineColors(line) : null, null, position,
0, destination, null);
final Departure dep = new Departure(plannedTime.getTime(), predictedTime != null ? predictedTime.getTime() : null, line,
line != null ? lineColors(line) : null, null, position, 0, destination, null);
if (!departures.contains(dep))
departures.add(dep);

View file

@ -21,7 +21,6 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.regex.Matcher;
@ -43,7 +42,7 @@ public class SbbProvider extends AbstractHafasProvider
public static final NetworkId NETWORK_ID = NetworkId.SBB;
public static final String OLD_NETWORK_ID = "fahrplan.sbb.ch";
private static final String API_BASE = "http://fahrplan.sbb.ch/bin/";
private static final String API_URI = "http://fahrplan.sbb.ch/bin/extxml.exe";
private static final String API_URI = "http://fahrplan.sbb.ch/bin/extxml.exe"; // xmlfahrplan.sbb.ch
private static final long PARSER_DAY_ROLLOVER_THRESHOLD_MS = 12 * 60 * 60 * 1000;
@ -143,8 +142,10 @@ public class SbbProvider extends AbstractHafasProvider
if (mHeadFine.matches())
{
final String location = ParserUtils.resolveEntities(mHeadFine.group(1));
final Date currentTime = ParserUtils.joinDateTime(ParserUtils.parseDate(mHeadFine.group(3)),
ParserUtils.parseTime(mHeadFine.group(2)));
final Calendar currentTime = new GregorianCalendar(timeZone());
currentTime.clear();
ParserUtils.parseEuropeanTime(currentTime, mHeadFine.group(2));
ParserUtils.parseGermanDate(currentTime, mHeadFine.group(3));
final int locationId = Integer.parseInt(mHeadFine.group(4));
final List<Departure> departures = new ArrayList<Departure>(8);
// String oldZebra = null;
@ -166,19 +167,17 @@ public class SbbProvider extends AbstractHafasProvider
final String destination = ParserUtils.resolveEntities(mDepFine.group(2));
final Calendar current = new GregorianCalendar();
current.setTime(currentTime);
final Calendar parsed = new GregorianCalendar();
parsed.setTime(ParserUtils.parseTime(mDepFine.group(3)));
parsed.set(Calendar.YEAR, current.get(Calendar.YEAR));
parsed.set(Calendar.MONTH, current.get(Calendar.MONTH));
parsed.set(Calendar.DAY_OF_MONTH, current.get(Calendar.DAY_OF_MONTH));
if (ParserUtils.timeDiff(parsed.getTime(), currentTime) < -PARSER_DAY_ROLLOVER_THRESHOLD_MS)
parsed.add(Calendar.DAY_OF_MONTH, 1);
final Calendar parsedTime = new GregorianCalendar(timeZone());
parsedTime.setTimeInMillis(currentTime.getTimeInMillis());
ParserUtils.parseEuropeanTime(parsedTime, mDepFine.group(3));
if (parsedTime.getTimeInMillis() - currentTime.getTimeInMillis() < -PARSER_DAY_ROLLOVER_THRESHOLD_MS)
parsedTime.add(Calendar.DAY_OF_MONTH, 1);
final String position = ParserUtils.resolveEntities(mDepFine.group(4));
final Departure dep = new Departure(parsed.getTime(), line, line != null ? lineColors(line) : null, position, 0, destination);
final Departure dep = new Departure(parsedTime.getTime(), line, line != null ? lineColors(line) : null, position, 0,
destination);
if (!departures.contains(dep))
departures.add(dep);

View file

@ -26,6 +26,7 @@ import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -58,6 +59,12 @@ public class SeptaProvider extends AbstractHafasProvider
return NETWORK_ID;
}
@Override
protected TimeZone timeZone()
{
return TimeZone.getTimeZone("EST");
}
@Override
protected char normalizeType(final String type)
{
@ -182,8 +189,10 @@ public class SeptaProvider extends AbstractHafasProvider
return new QueryDeparturesResult(Status.SERVICE_DOWN);
final String location = ParserUtils.resolveEntities(mPageCoarse.group(1));
final Date currentTime = ParserUtils.joinDateTime(ParserUtils.parseAmericanDate(mPageCoarse.group(2)),
ParserUtils.parseAmericanTime(mPageCoarse.group(3)));
final Calendar currentTime = new GregorianCalendar(timeZone());
currentTime.clear();
ParserUtils.parseAmericanDate(currentTime, mPageCoarse.group(2));
ParserUtils.parseAmericanTime(currentTime, mPageCoarse.group(3));
final List<Departure> departures = new ArrayList<Departure>(8);
String oldZebra = null;
@ -200,26 +209,31 @@ public class SeptaProvider extends AbstractHafasProvider
final Matcher mDepFine = P_DEPARTURES_FINE.matcher(mDepCoarse.group(2));
if (mDepFine.matches())
{
final Calendar current = new GregorianCalendar();
current.setTime(currentTime);
final Calendar parsed = new GregorianCalendar();
parsed.setTime(ParserUtils.parseAmericanTime(mDepFine.group(1)));
parsed.set(Calendar.YEAR, current.get(Calendar.YEAR));
parsed.set(Calendar.MONTH, current.get(Calendar.MONTH));
parsed.set(Calendar.DAY_OF_MONTH, current.get(Calendar.DAY_OF_MONTH));
if (ParserUtils.timeDiff(parsed.getTime(), currentTime) < -PARSER_DAY_ROLLOVER_THRESHOLD_MS)
parsed.add(Calendar.DAY_OF_MONTH, 1);
final Calendar plannedTime = new GregorianCalendar(timeZone());
plannedTime.setTimeInMillis(currentTime.getTimeInMillis());
ParserUtils.parseAmericanTime(plannedTime, mDepFine.group(1));
final Date plannedTime = parsed.getTime();
if (plannedTime.getTimeInMillis() - currentTime.getTimeInMillis() < -PARSER_DAY_ROLLOVER_THRESHOLD_MS)
plannedTime.add(Calendar.DAY_OF_MONTH, 1);
Date predictedTime = null;
final Calendar predictedTime;
final String prognosis = ParserUtils.resolveEntities(mDepFine.group(2));
if (prognosis != null)
{
predictedTime = new GregorianCalendar(timeZone());
if (prognosis.equals("pünktlich"))
predictedTime = plannedTime;
{
predictedTime.setTimeInMillis(plannedTime.getTimeInMillis());
}
else
predictedTime = ParserUtils.joinDateTime(currentTime, ParserUtils.parseAmericanTime(prognosis));
{
predictedTime.setTimeInMillis(currentTime.getTimeInMillis());
ParserUtils.parseAmericanTime(predictedTime, prognosis);
}
}
else
{
predictedTime = null;
}
final String lineType = mDepFine.group(3);
@ -232,8 +246,8 @@ public class SeptaProvider extends AbstractHafasProvider
final String position = mDepFine.group(7) != null ? "Gl. " + ParserUtils.resolveEntities(mDepFine.group(7)) : null;
final Departure dep = new Departure(plannedTime, predictedTime, line, line != null ? lineColors(line) : null, null, position,
destinationId, destination, null);
final Departure dep = new Departure(plannedTime.getTime(), predictedTime != null ? predictedTime.getTime() : null, line,
line != null ? lineColors(line) : null, null, position, destinationId, destination, null);
if (!departures.contains(dep))
departures.add(dep);

View file

@ -20,7 +20,6 @@ package de.schildbach.pte;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.regex.Matcher;
@ -129,8 +128,10 @@ public class SncbProvider extends AbstractHafasProvider
if (mHeadFine.matches())
{
final String location = ParserUtils.resolveEntities(mHeadFine.group(1));
final Date currentTime = ParserUtils.joinDateTime(ParserUtils.parseDateSlash(mHeadFine.group(3)),
ParserUtils.parseTime(mHeadFine.group(2)));
final Calendar currentTime = new GregorianCalendar(timeZone());
currentTime.clear();
ParserUtils.parseEuropeanTime(currentTime, mHeadFine.group(2));
ParserUtils.parseGermanDate(currentTime, mHeadFine.group(3));
final List<Departure> departures = new ArrayList<Departure>(8);
final Matcher mDepCoarse = P_DEPARTURES_COARSE.matcher(mHeadCoarse.group(2));
@ -143,19 +144,16 @@ public class SncbProvider extends AbstractHafasProvider
final String destination = ParserUtils.resolveEntities(mDepFine.group(2));
final Calendar current = new GregorianCalendar();
current.setTime(currentTime);
final Calendar parsed = new GregorianCalendar();
parsed.setTime(ParserUtils.parseTime(mDepFine.group(3)));
parsed.set(Calendar.YEAR, current.get(Calendar.YEAR));
parsed.set(Calendar.MONTH, current.get(Calendar.MONTH));
parsed.set(Calendar.DAY_OF_MONTH, current.get(Calendar.DAY_OF_MONTH));
if (ParserUtils.timeDiff(parsed.getTime(), currentTime) < -PARSER_DAY_ROLLOVER_THRESHOLD_MS)
parsed.add(Calendar.DAY_OF_MONTH, 1);
final Calendar parsedTime = new GregorianCalendar(timeZone());
parsedTime.setTimeInMillis(currentTime.getTimeInMillis());
ParserUtils.parseEuropeanTime(parsedTime, mDepFine.group(3));
if (parsedTime.getTimeInMillis() - currentTime.getTimeInMillis() < -PARSER_DAY_ROLLOVER_THRESHOLD_MS)
parsedTime.add(Calendar.DAY_OF_MONTH, 1);
mDepFine.group(4); // TODO delay
final Departure dep = new Departure(parsed.getTime(), line, line != null ? lineColors(line) : null, null, 0, destination);
final Departure dep = new Departure(parsedTime.getTime(), line, line != null ? lineColors(line) : null, null, 0, destination);
if (!departures.contains(dep))
departures.add(dep);

View file

@ -160,8 +160,10 @@ public class VgsProvider extends AbstractHafasProvider
if (mHeadFine.matches())
{
final String location = ParserUtils.resolveEntities(mHeadFine.group(1));
final Date currentTime = ParserUtils.joinDateTime(ParserUtils.parseDate(mHeadFine.group(2)),
ParserUtils.parseTime(mHeadFine.group(3)));
final Calendar currentTime = new GregorianCalendar(timeZone());
currentTime.clear();
ParserUtils.parseGermanDate(currentTime, mHeadFine.group(2));
ParserUtils.parseEuropeanTime(currentTime, mHeadFine.group(3));
final List<Departure> departures = new ArrayList<Departure>(8);
String oldZebra = null;
@ -177,26 +179,31 @@ public class VgsProvider extends AbstractHafasProvider
final Matcher mDepFine = P_DEPARTURES_FINE.matcher(mDepCoarse.group(2));
if (mDepFine.matches())
{
final Calendar current = new GregorianCalendar();
current.setTime(currentTime);
final Calendar parsed = new GregorianCalendar();
parsed.setTime(ParserUtils.parseTime(mDepFine.group(1)));
parsed.set(Calendar.YEAR, current.get(Calendar.YEAR));
parsed.set(Calendar.MONTH, current.get(Calendar.MONTH));
parsed.set(Calendar.DAY_OF_MONTH, current.get(Calendar.DAY_OF_MONTH));
if (ParserUtils.timeDiff(parsed.getTime(), currentTime) < -PARSER_DAY_ROLLOVER_THRESHOLD_MS)
parsed.add(Calendar.DAY_OF_MONTH, 1);
final Calendar plannedTime = new GregorianCalendar(timeZone());
plannedTime.setTimeInMillis(currentTime.getTimeInMillis());
ParserUtils.parseEuropeanTime(plannedTime, mDepFine.group(1));
final Date plannedTime = parsed.getTime();
if (plannedTime.getTimeInMillis() - currentTime.getTimeInMillis() < -PARSER_DAY_ROLLOVER_THRESHOLD_MS)
plannedTime.add(Calendar.DAY_OF_MONTH, 1);
Date predictedTime = null;
final Calendar predictedTime;
final String prognosis = ParserUtils.resolveEntities(mDepFine.group(2));
if (prognosis != null)
{
if (prognosis.equals("pünktlich"))
predictedTime = plannedTime;
predictedTime = new GregorianCalendar(timeZone());
if (!prognosis.equals("pünktlich"))
{
predictedTime.setTimeInMillis(plannedTime.getTimeInMillis());
}
else
predictedTime = ParserUtils.joinDateTime(currentTime, ParserUtils.parseTime(prognosis));
{
predictedTime.setTimeInMillis(currentTime.getTimeInMillis());
ParserUtils.parseEuropeanTime(predictedTime, prognosis);
}
}
else
{
predictedTime = null;
}
final String lineType = mDepFine.group(3);
@ -209,8 +216,8 @@ public class VgsProvider extends AbstractHafasProvider
final String position = mDepFine.group(7) != null ? "Gl. " + ParserUtils.resolveEntities(mDepFine.group(7)) : null;
final Departure dep = new Departure(plannedTime, predictedTime, line, line != null ? lineColors(line) : null, null, position,
destinationId, destination, null);
final Departure dep = new Departure(plannedTime.getTime(), predictedTime != null ? predictedTime.getTime() : null, line,
line != null ? lineColors(line) : null, null, position, destinationId, destination, null);
if (!departures.contains(dep))
departures.add(dep);

View file

@ -29,8 +29,6 @@ import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
@ -263,55 +261,7 @@ public final class ParserUtils
return builder.toString();
}
public static Date parseDate(final String str)
{
try
{
return new SimpleDateFormat("dd.MM.yy").parse(str);
}
catch (final ParseException x)
{
throw new RuntimeException(x);
}
}
public static Date parseDateSlash(final String str)
{
try
{
return new SimpleDateFormat("dd/MM/yy").parse(str);
}
catch (final ParseException x)
{
throw new RuntimeException(x);
}
}
public static Date parseAmericanDate(final String str)
{
try
{
return new SimpleDateFormat("MM/dd/yyyy").parse(str);
}
catch (final ParseException x)
{
throw new RuntimeException(x);
}
}
public static Date parseTime(final String str)
{
try
{
return new SimpleDateFormat("HH:mm").parse(str);
}
catch (final ParseException x)
{
throw new RuntimeException(x);
}
}
private static final Pattern P_GERMAN_DATE = Pattern.compile("(\\d{2})\\.(\\d{2})\\.(\\d{2,4})");
private static final Pattern P_GERMAN_DATE = Pattern.compile("(\\d{2})[\\./](\\d{2})[\\./](\\d{2,4})");
public static final void parseGermanDate(final Calendar calendar, final CharSequence str)
{
@ -325,6 +275,20 @@ public final class ParserUtils
calendar.set(Calendar.YEAR, year >= 100 ? year : year + 2000);
}
private static final Pattern P_AMERICAN_DATE = Pattern.compile("(\\d{2})/(\\d{2})/(\\d{2,4})");
public static final void parseAmericanDate(final Calendar calendar, final CharSequence str)
{
final Matcher m = P_AMERICAN_DATE.matcher(str);
if (!m.matches())
throw new RuntimeException("cannot parse: '" + str + "'");
calendar.set(Calendar.MONTH, Integer.parseInt(m.group(1)) - 1);
calendar.set(Calendar.DAY_OF_MONTH, Integer.parseInt(m.group(2)));
final int year = Integer.parseInt(m.group(3));
calendar.set(Calendar.YEAR, year >= 100 ? year : year + 2000);
}
private static final Pattern P_EUROPEAN_TIME = Pattern.compile("(\\d{1,2}):(\\d{2})(?::(\\d{2}))?");
public static final void parseEuropeanTime(final Calendar calendar, final CharSequence str)
@ -338,28 +302,18 @@ public final class ParserUtils
calendar.set(Calendar.SECOND, m.group(3) != null ? Integer.parseInt(m.group(3)) : 0);
}
public static Date parseAmericanTime(final String str)
{
try
{
return new SimpleDateFormat("h:mm a").parse(str);
}
catch (final ParseException x)
{
throw new RuntimeException(x);
}
}
private static final Pattern P_AMERICAN_TIME = Pattern.compile("(\\d{1,2}):(\\d{2})(?::(\\d{2}))? (AM|PM)");
public static Date joinDateTime(final Date date, final Date time)
public static final void parseAmericanTime(final Calendar calendar, final CharSequence str)
{
final Calendar cDate = new GregorianCalendar();
cDate.setTime(date);
final Calendar cTime = new GregorianCalendar();
cTime.setTime(time);
cTime.set(Calendar.YEAR, cDate.get(Calendar.YEAR));
cTime.set(Calendar.MONTH, cDate.get(Calendar.MONTH));
cTime.set(Calendar.DAY_OF_MONTH, cDate.get(Calendar.DAY_OF_MONTH));
return cTime.getTime();
final Matcher m = P_AMERICAN_TIME.matcher(str);
if (!m.matches())
throw new RuntimeException("cannot parse: '" + str + "'");
calendar.set(Calendar.HOUR, Integer.parseInt(m.group(1)));
calendar.set(Calendar.MINUTE, Integer.parseInt(m.group(2)));
calendar.set(Calendar.SECOND, m.group(3) != null ? Integer.parseInt(m.group(3)) : 0);
calendar.set(Calendar.AM_PM, m.group(4).equals("AM") ? Calendar.AM : Calendar.PM);
}
public static long timeDiff(final Date d1, final Date d2)

View file

@ -17,10 +17,17 @@
package de.schildbach.pte.live;
import java.util.Date;
import org.junit.Test;
import de.schildbach.pte.RmvProvider;
import de.schildbach.pte.NetworkProvider.WalkSpeed;
import de.schildbach.pte.dto.Connection;
import de.schildbach.pte.dto.Location;
import de.schildbach.pte.dto.LocationType;
import de.schildbach.pte.dto.NearbyStationsResult;
import de.schildbach.pte.dto.QueryConnectionsResult;
import de.schildbach.pte.dto.QueryDeparturesResult;
/**
@ -29,6 +36,7 @@ import de.schildbach.pte.dto.QueryDeparturesResult;
public class RmvProviderLiveTest
{
private final RmvProvider provider = new RmvProvider();
protected static final String ALL_PRODUCTS = "IRSUTBFC";
@Test
public void nearbyStation() throws Exception
@ -45,4 +53,16 @@ public class RmvProviderLiveTest
System.out.println(result.stationDepartures);
}
@Test
public void shortConnection() throws Exception
{
final QueryConnectionsResult result = provider.queryConnections(new Location(LocationType.ANY, 0, null, "Hanau Hauptbahnhof!"), null,
new Location(LocationType.ANY, 0, null, "Frankfurt Hauptbahnhof!"), new Date(), true, ALL_PRODUCTS, WalkSpeed.NORMAL);
System.out.println(result);
final QueryConnectionsResult moreResult = provider.queryMoreConnections(result.context);
for (final Connection connection : result.connections)
provider.getConnectionDetails(connection.link);
System.out.println(moreResult);
}
}