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

View file

@ -20,7 +20,6 @@ package de.schildbach.pte;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
@ -29,6 +28,7 @@ import java.util.GregorianCalendar;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TimeZone;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -65,6 +65,11 @@ public abstract class AbstractHafasProvider implements NetworkProvider
this.accessId = accessId; this.accessId = accessId;
} }
protected TimeZone timeZone()
{
return TimeZone.getTimeZone("CET");
}
protected String[] splitNameAndPlace(final String name) protected String[] splitNameAndPlace(final String name)
{ {
return new String[] { null, name }; return new String[] { null, name };
@ -252,8 +257,6 @@ public abstract class AbstractHafasProvider implements NetworkProvider
// System.out.println(request); // System.out.println(request);
// ParserUtils.printXml(ParserUtils.scrape(apiUri, true, wrap(request), null, false)); // ParserUtils.printXml(ParserUtils.scrape(apiUri, true, wrap(request), null, false));
final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMdd");
InputStream is = null; InputStream is = null;
try try
@ -314,8 +317,9 @@ public abstract class AbstractHafasProvider implements NetworkProvider
XmlPullUtil.enter(pp, "Overview"); XmlPullUtil.enter(pp, "Overview");
XmlPullUtil.require(pp, "Date"); XmlPullUtil.require(pp, "Date");
final Calendar currentDate = new GregorianCalendar(); final Calendar currentDate = new GregorianCalendar(timeZone());
currentDate.setTime(DATE_FORMAT.parse(XmlPullUtil.text(pp))); currentDate.clear();
parseDate(currentDate, XmlPullUtil.text(pp));
XmlPullUtil.enter(pp, "Departure"); XmlPullUtil.enter(pp, "Departure");
XmlPullUtil.enter(pp, "BasicStop"); XmlPullUtil.enter(pp, "BasicStop");
while (pp.getName().equals("StAttrList")) while (pp.getName().equals("StAttrList"))
@ -352,7 +356,9 @@ public abstract class AbstractHafasProvider implements NetworkProvider
final Location sectionDeparture = parseLocation(pp); final Location sectionDeparture = parseLocation(pp);
XmlPullUtil.enter(pp, "Dep"); XmlPullUtil.enter(pp, "Dep");
XmlPullUtil.require(pp, "Time"); 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.enter(pp, "Platform");
XmlPullUtil.require(pp, "Text"); XmlPullUtil.require(pp, "Text");
String departurePos = XmlPullUtil.text(pp).trim(); String departurePos = XmlPullUtil.text(pp).trim();
@ -434,7 +440,9 @@ public abstract class AbstractHafasProvider implements NetworkProvider
final Location sectionArrival = parseLocation(pp); final Location sectionArrival = parseLocation(pp);
XmlPullUtil.enter(pp, "Arr"); XmlPullUtil.enter(pp, "Arr");
XmlPullUtil.require(pp, "Time"); 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.enter(pp, "Platform");
XmlPullUtil.require(pp, "Text"); XmlPullUtil.require(pp, "Text");
String arrivalPos = XmlPullUtil.text(pp).trim(); String arrivalPos = XmlPullUtil.text(pp).trim();
@ -451,8 +459,8 @@ public abstract class AbstractHafasProvider implements NetworkProvider
if (min == 0 || line != null) if (min == 0 || line != null)
{ {
parts.add(new Connection.Trip(line, destination, departureTime, departurePos, sectionDeparture, arrivalTime, arrivalPos, parts.add(new Connection.Trip(line, destination, departureTime.getTime(), departurePos, sectionDeparture, arrivalTime
sectionArrival, null, null)); .getTime(), arrivalPos, sectionArrival, null, null));
} }
else else
{ {
@ -468,8 +476,8 @@ public abstract class AbstractHafasProvider implements NetworkProvider
} }
if (firstDepartureTime == null) if (firstDepartureTime == null)
firstDepartureTime = departureTime; firstDepartureTime = departureTime.getTime();
lastArrivalTime = arrivalTime; lastArrivalTime = arrivalTime.getTime();
} }
XmlPullUtil.exit(pp); XmlPullUtil.exit(pp);
@ -487,10 +495,6 @@ public abstract class AbstractHafasProvider implements NetworkProvider
{ {
throw new RuntimeException(x); throw new RuntimeException(x);
} }
catch (final ParseException x)
{
throw new RuntimeException(x);
}
finally finally
{ {
if (is != null) if (is != null)
@ -531,39 +535,43 @@ public abstract class AbstractHafasProvider implements NetworkProvider
return attributeVariants; 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 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); final Matcher m = P_TIME.matcher(str);
if (m.matches()) if (!m.matches())
{ throw new IllegalArgumentException("cannot parse: '" + str + "'");
final Calendar c = new GregorianCalendar();
c.set(Calendar.YEAR, currentDate.get(Calendar.YEAR)); calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(m.group(2)));
c.set(Calendar.MONTH, currentDate.get(Calendar.MONTH)); calendar.set(Calendar.MINUTE, Integer.parseInt(m.group(3)));
c.set(Calendar.DAY_OF_MONTH, currentDate.get(Calendar.DAY_OF_MONTH)); calendar.set(Calendar.SECOND, Integer.parseInt(m.group(4)));
c.set(Calendar.HOUR_OF_DAY, Integer.parseInt(m.group(2))); calendar.set(Calendar.MILLISECOND, 0);
c.set(Calendar.MINUTE, Integer.parseInt(m.group(3))); calendar.add(Calendar.DAY_OF_MONTH, Integer.parseInt(m.group(1)));
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);
}
} }
private static final Pattern P_DURATION = Pattern.compile("(\\d+):(\\d{2})"); 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); final Matcher m = P_DURATION.matcher(str);
if (m.matches()) if (m.matches())
return Integer.parseInt(m.group(1)) * 60 + Integer.parseInt(m.group(2)); return Integer.parseInt(m.group(1)) * 60 + Integer.parseInt(m.group(2));
else else
throw new IllegalArgumentException("cannot parse duration: " + str); throw new IllegalArgumentException("cannot parse duration: '" + str + "'");
} }
private static final String location(final Location location) 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 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 Location to = new Location(LocationType.ANY, 0, null, ParserUtils.resolveEntities(mHead.group(2)));
final Date currentDate = ParserUtils.parseDate(mHead.group(3)); final Calendar currentDate = new GregorianCalendar(timeZone());
final String linkEarlier = mHead.group(4) != null ? ParserUtils.resolveEntities(mHead.group(4)) : null; 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 String linkLater = mHead.group(5) != null ? ParserUtils.resolveEntities(mHead.group(5)) : null;
final List<Connection> connections = new ArrayList<Connection>(); final List<Connection> connections = new ArrayList<Connection>();
@ -254,20 +256,24 @@ public final class BahnProvider extends AbstractHafasProvider
if (mConFine.matches()) if (mConFine.matches())
{ {
final String link = ParserUtils.resolveEntities(mConFine.group(1)); 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()) 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) 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) 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)) if (departureTime.after(arrivalTime))
arrivalTime = ParserUtils.addDays(arrivalTime, 1); arrivalTime.add(Calendar.DAY_OF_YEAR, 1);
final Connection connection = new Connection(AbstractHafasProvider.extractConnectionId(link), link, departureTime, arrivalTime, final Connection connection = new Connection(AbstractHafasProvider.extractConnectionId(link), link, departureTime.getTime(),
from, to, null, null); arrivalTime.getTime(), from, to, null, null);
connections.add(connection); connections.add(connection);
} }
else else
@ -353,31 +359,31 @@ public final class BahnProvider extends AbstractHafasProvider
final String lineStr = normalizeLine(ParserUtils.resolveEntities(mDetFine.group(2))); final String lineStr = normalizeLine(ParserUtils.resolveEntities(mDetFine.group(2)));
final Line line = new Line(lineStr, lineColors(lineStr)); 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 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 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 String arrivalPosition = ParserUtils.resolveEntities(mDetFine.group(8));
final Date arrivalDate = ParserUtils.parseDate(mDetFine.group(9)); lastTrip = new Connection.Trip(line, null, departureTime.getTime(), departurePosition, departure, arrivalTime.getTime(),
final Date departureDateTime = ParserUtils.joinDateTime(departureDate, departureTime);
final Date arrivalDateTime = ParserUtils.joinDateTime(arrivalDate, arrivalTime);
lastTrip = new Connection.Trip(line, null, departureDateTime, departurePosition, departure, arrivalDateTime,
arrivalPosition, arrival, null, null); arrivalPosition, arrival, null, null);
parts.add(lastTrip); parts.add(lastTrip);
if (firstDepartureTime == null) if (firstDepartureTime == null)
firstDepartureTime = departureDateTime; firstDepartureTime = departureTime.getTime();
lastArrival = arrival; lastArrival = arrival;
lastArrivalTime = arrivalDateTime; lastArrivalTime = arrivalTime.getTime();
} }
else if (mDetFine.group(10) != null) else if (mDetFine.group(10) != null)
{ {
@ -415,8 +421,9 @@ public final class BahnProvider extends AbstractHafasProvider
if (firstDepartureTime == null || lastArrivalTime == null) if (firstDepartureTime == null || lastArrivalTime == null)
throw new IllegalStateException("could not parse all parts of:\n" + mHead.group(1) + "\n" + parts); 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, return new GetConnectionDetailsResult(new GregorianCalendar(timeZone()).getTime(), new Connection(
lastArrivalTime, firstDeparture, lastArrival, parts, null)); AbstractHafasProvider.extractConnectionId(uri), uri, firstDepartureTime, lastArrivalTime, firstDeparture, lastArrival, parts,
null));
} }
else else
{ {
@ -479,7 +486,6 @@ public final class BahnProvider extends AbstractHafasProvider
} }
final List<Departure> departures = new ArrayList<Departure>(8); final List<Departure> departures = new ArrayList<Departure>(8);
final Calendar calendar = new GregorianCalendar();
final Matcher mDepCoarse = P_DEPARTURES_COARSE.matcher(page); final Matcher mDepCoarse = P_DEPARTURES_COARSE.matcher(page);
while (mDepCoarse.find()) while (mDepCoarse.find())
@ -489,15 +495,21 @@ public final class BahnProvider extends AbstractHafasProvider
{ {
if (mDepFine.group(8) == null) if (mDepFine.group(8) == null)
{ {
final Date plannedTime = ParserUtils.joinDateTime(ParserUtils.parseDate(mDepFine.group(2)), final Calendar plannedTime = new GregorianCalendar(timeZone());
ParserUtils.parseTime(mDepFine.group(1))); 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) if (mDepFine.group(3) != null)
{ {
calendar.setTime(plannedTime); predictedTime = new GregorianCalendar(timeZone());
calendar.add(Calendar.MINUTE, Integer.parseInt(mDepFine.group(3))); predictedTime.setTimeInMillis(plannedTime.getTimeInMillis());
predictedTime = calendar.getTime(); 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; 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)); final String message = ParserUtils.resolveEntities(mDepFine.group(9));
departures.add(new Departure(plannedTime, predictedTime, line, line != null ? lineColors(line) : null, null, position, 0, departures.add(new Departure(plannedTime.getTime(), predictedTime != null ? predictedTime.getTime() : null, line,
destination, message)); line != null ? lineColors(line) : null, null, position, 0, destination, message));
} }
} }
else else

View file

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

View file

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

View file

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

View file

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

View file

@ -21,7 +21,9 @@ import java.io.IOException;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; 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 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 Location to = new Location(LocationType.ANY, 0, null, ParserUtils.resolveEntities(mHead.group(2)));
final Date currentDate = ParserUtils.parseDate(mHead.group(3)); final Calendar time = new GregorianCalendar(timeZone());
final String linkEarlier = mHead.group(4) != null ? ParserUtils.resolveEntities(mHead.group(4)) : null; 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 String linkLater = mHead.group(5) != null ? ParserUtils.resolveEntities(mHead.group(5)) : null;
final List<Connection> connections = new ArrayList<Connection>(); final List<Connection> connections = new ArrayList<Connection>();
Date lastDate = currentDate;
final Matcher mConCoarse = P_CONNECTIONS_COARSE.matcher(page); final Matcher mConCoarse = P_CONNECTIONS_COARSE.matcher(page);
while (mConCoarse.find()) while (mConCoarse.find())
{ {
@ -404,14 +406,20 @@ public class OebbProvider extends AbstractHafasProvider
final Matcher mConFine = P_CONNECTIONS_FINE.matcher(overview); final Matcher mConFine = P_CONNECTIONS_FINE.matcher(overview);
if (mConFine.matches()) if (mConFine.matches())
{ {
final Date overviewDepartureDate = ParserUtils.parseDate(mConFine.group(1)); final Calendar overviewDepartureTime = new GregorianCalendar(timeZone());
final Date overviewArrivalDate = mConFine.group(2) != null ? ParserUtils.parseDate(mConFine.group(2)) : null; overviewDepartureTime.clear();
final Date overviewDepartureTime = ParserUtils.joinDateTime(overviewDepartureDate, ParserUtils.parseTime(mConFine.group(3))); ParserUtils.parseGermanDate(overviewDepartureTime, mConFine.group(1));
final Date overviewArrivalTime = ParserUtils.joinDateTime(overviewArrivalDate != null ? overviewArrivalDate ParserUtils.parseEuropeanTime(overviewDepartureTime, mConFine.group(3));
: overviewDepartureDate, ParserUtils.parseTime(mConFine.group(4)));
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 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); new ArrayList<Connection.Part>(1), null);
connections.add(connection); 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, final Location departure = new Location(departureId != 0 ? LocationType.STATION : LocationType.ANY, departureId, null,
ParserUtils.resolveEntities(mDetFine.group(2))); ParserUtils.resolveEntities(mDetFine.group(2)));
Date detailsDepartureDate = mDetFine.group(3) != null ? ParserUtils.parseDate(mDetFine.group(3)) : lastDate; if (mDetFine.group(3) != null)
if (detailsDepartureDate != null) ParserUtils.parseGermanDate(time, mDetFine.group(3));
lastDate = detailsDepartureDate; ParserUtils.parseEuropeanTime(time, mDetFine.group(4));
final Date detailsDepartureTime = time.getTime();
final Date detailsDepartureTime = ParserUtils.parseTime(mDetFine.group(4));
final Date detailsDepartureDateTime = ParserUtils.joinDateTime(detailsDepartureDate, detailsDepartureTime);
final String lineType = mDetFine.group(6); 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, final Location arrival = new Location(arrivalId != 0 ? LocationType.STATION : LocationType.ANY, arrivalId, null,
ParserUtils.resolveEntities(mDetFine.group(9))); ParserUtils.resolveEntities(mDetFine.group(9)));
Date detailsArrivalDate = mDetFine.group(10) != null ? ParserUtils.parseDate(mDetFine.group(10)) : lastDate; if (mDetFine.group(10) != null)
if (detailsArrivalDate != null) ParserUtils.parseGermanDate(time, mDetFine.group(10));
lastDate = detailsArrivalDate; ParserUtils.parseEuropeanTime(time, mDetFine.group(11));
final Date detailsArrivalTime = time.getTime();
final Date detailsArrivalTime = ParserUtils.parseTime(mDetFine.group(11));
final Date detailsArrivalDateTime = ParserUtils.joinDateTime(detailsArrivalDate, detailsArrivalTime);
if (!lineType.equals("fuss")) 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, final Location destination = mDetFine.group(13) != null ? new Location(LocationType.ANY, 0, null,
ParserUtils.resolveEntities(mDetFine.group(13))) : null; ParserUtils.resolveEntities(mDetFine.group(13))) : null;
final Connection.Trip trip = new Connection.Trip(line, destination, detailsDepartureDateTime, departurePosition, final Connection.Trip trip = new Connection.Trip(line, destination, detailsDepartureTime, departurePosition,
departure, detailsArrivalDateTime, arrivalPosition, arrival, null, null); departure, detailsArrivalTime, arrivalPosition, arrival, null, null);
connection.parts.add(trip); connection.parts.add(trip);
} }
else 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); final Connection.Footway footway = new Connection.Footway(min, departure, arrival, null);
connection.parts.add(footway); connection.parts.add(footway);
@ -568,8 +572,10 @@ public class OebbProvider extends AbstractHafasProvider
final JSONObject departure = aDeparture.optJSONObject(i); final JSONObject departure = aDeparture.optJSONObject(i);
if (departure != null) if (departure != null)
{ {
final Date time = ParserUtils.joinDateTime(ParserUtils.parseDate(departure.getString("da")), final Calendar parsedTime = new GregorianCalendar(timeZone());
ParserUtils.parseTime(departure.getString("ti"))); 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 line = normalizeLine(ParserUtils.resolveEntities(departure.getString("pr")));
final String destination = ParserUtils.resolveEntities(departure.getString("st")); final String destination = ParserUtils.resolveEntities(departure.getString("st"));
String position = departure.optString("tr"); String position = departure.optString("tr");
@ -578,8 +584,8 @@ public class OebbProvider extends AbstractHafasProvider
final boolean rt = head.optBoolean("rt", false); final boolean rt = head.optBoolean("rt", false);
final String lineLink = departure.optString("tinfoline"); final String lineLink = departure.optString("tinfoline");
departures.add(new Departure(!rt ? time : null, rt ? time : null, line, line != null ? lineColors(line) : null, lineLink, departures.add(new Departure(!rt ? parsedTime.getTime() : null, rt ? parsedTime.getTime() : null, line,
position, 0, destination, null)); 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 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 Location to = new Location(LocationType.ANY, 0, null, ParserUtils.resolveEntities(mHead.group(2)));
final Date currentDate = ParserUtils.parseDate(mHead.group(3)); final Calendar currentDate = new GregorianCalendar(timeZone());
final String linkEarlier = mHead.group(4) != null ? ParserUtils.resolveEntities(mHead.group(4)) : null; 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 String linkLater = mHead.group(5) != null ? ParserUtils.resolveEntities(mHead.group(5)) : null;
final List<Connection> connections = new ArrayList<Connection>(); final List<Connection> connections = new ArrayList<Connection>();
@ -274,19 +276,24 @@ public class RmvProvider extends AbstractHafasProvider
if (mConFine.matches()) if (mConFine.matches())
{ {
final String link = ParserUtils.resolveEntities(mConFine.group(1)); 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()) 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) 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) 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)) if (departureTime.after(arrivalTime))
arrivalTime = ParserUtils.addDays(arrivalTime, 1); arrivalTime.add(Calendar.DAY_OF_YEAR, 1);
final Connection connection = new Connection(extractConnectionId(link), link, departureTime, arrivalTime, from, to, null, null); final Connection connection = new Connection(extractConnectionId(link), link, departureTime.getTime(), arrivalTime.getTime(),
from, to, null, null);
connections.add(connection); connections.add(connection);
} }
else else
@ -337,16 +344,22 @@ public class RmvProvider extends AbstractHafasProvider
if (mHead.matches()) if (mHead.matches())
{ {
final Location firstDeparture = new Location(LocationType.ANY, 0, null, ParserUtils.resolveEntities(mHead.group(1))); final Location firstDeparture = new Location(LocationType.ANY, 0, null, ParserUtils.resolveEntities(mHead.group(1)));
final Date currentDate = ParserUtils.parseDate(mHead.group(2)); final Calendar currentDate = new GregorianCalendar(timeZone());
final List<Connection.Part> parts = new ArrayList<Connection.Part>(4); 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 firstDepartureTime = null;
Date lastArrivalTime = null; Date lastArrivalTime = null;
Location lastArrival = null; Location lastArrival = null;
Connection.Trip lastTrip = null; Connection.Trip lastTrip = null;
final List<Connection.Part> parts = new ArrayList<Connection.Part>(4);
final Matcher mDetCoarse = P_CONNECTION_DETAILS_COARSE.matcher(page); final Matcher mDetCoarse = P_CONNECTION_DETAILS_COARSE.matcher(page);
while (mDetCoarse.find()) 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 Location destination = new Location(LocationType.ANY, 0, null, ParserUtils.resolveEntities(mDetFine.group(2)));
final Date plannedDepartureTime = upTime(lastTime, ParserUtils.parseEuropeanTime(time, mDetFine.group(3));
ParserUtils.joinDateTime(currentDate, ParserUtils.parseTime(mDetFine.group(3)))); if (time.getTime().before(lastTime))
final Date predictedDepartureTime = mDetFine.group(4) != null ? upTime(lastTime, time.add(Calendar.DAY_OF_YEAR, 1);
ParserUtils.joinDateTime(currentDate, ParserUtils.parseTime(mDetFine.group(4)))) : null; 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 Date departureTime = predictedDepartureTime != null ? predictedDepartureTime : plannedDepartureTime;
final String departurePosition = ParserUtils.resolveEntities(mDetFine.group(5)); final String departurePosition = ParserUtils.resolveEntities(mDetFine.group(5));
final Date plannedArrivalTime = upTime(lastTime, ParserUtils.parseEuropeanTime(time, mDetFine.group(6));
ParserUtils.joinDateTime(currentDate, ParserUtils.parseTime(mDetFine.group(6)))); if (time.getTime().before(lastTime))
final Date predictedArrivalTime = mDetFine.group(7) != null ? upTime(lastTime, time.add(Calendar.DAY_OF_YEAR, 1);
ParserUtils.joinDateTime(currentDate, ParserUtils.parseTime(mDetFine.group(7)))) : null; 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 Date arrivalTime = predictedArrivalTime != null ? predictedArrivalTime : plannedArrivalTime;
final String arrivalPosition = ParserUtils.resolveEntities(mDetFine.group(8)); 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, return new GetConnectionDetailsResult(currentDate.getTime(), new Connection(extractConnectionId(uri), uri, firstDepartureTime,
firstDeparture, lastArrival, parts, null)); lastArrivalTime, firstDeparture, lastArrival, parts, null));
} }
else 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) private String departuresQueryUri(final String stationId, final int maxDepartures)
{ {
final DateFormat DATE_FORMAT = new SimpleDateFormat("dd.MM.yy"); final DateFormat DATE_FORMAT = new SimpleDateFormat("dd.MM.yy");
@ -499,8 +534,10 @@ public class RmvProvider extends AbstractHafasProvider
if (mHeadFine.matches()) if (mHeadFine.matches())
{ {
final String location = ParserUtils.resolveEntities(mHeadFine.group(1)); final String location = ParserUtils.resolveEntities(mHeadFine.group(1));
final Date currentTime = ParserUtils.joinDateTime(ParserUtils.parseDate(mHeadFine.group(3)), final Calendar currentTime = new GregorianCalendar(timeZone());
ParserUtils.parseTime(mHeadFine.group(2))); currentTime.clear();
ParserUtils.parseEuropeanTime(currentTime, mHeadFine.group(2));
ParserUtils.parseGermanDate(currentTime, mHeadFine.group(3));
final List<Departure> departures = new ArrayList<Departure>(8); final List<Departure> departures = new ArrayList<Departure>(8);
final Matcher mDepCoarse = P_DEPARTURES_COARSE.matcher(mHeadCoarse.group(2)); 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 String destination = ParserUtils.resolveEntities(mDepFine.group(2));
final Calendar current = new GregorianCalendar(); final Calendar plannedTime = new GregorianCalendar(timeZone());
current.setTime(currentTime); plannedTime.setTimeInMillis(currentTime.getTimeInMillis());
final Calendar parsed = new GregorianCalendar(); ParserUtils.parseEuropeanTime(plannedTime, mDepFine.group(3));
parsed.setTime(ParserUtils.parseTime(mDepFine.group(3))); if (plannedTime.getTimeInMillis() - currentTime.getTimeInMillis() < -PARSER_DAY_ROLLOVER_THRESHOLD_MS)
parsed.set(Calendar.YEAR, current.get(Calendar.YEAR)); plannedTime.add(Calendar.DAY_OF_MONTH, 1);
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();
Date predictedTime = null; final Calendar predictedTime;
if (mDepFine.group(4) != null) if (mDepFine.group(4) != null)
{ {
parsed.setTime(ParserUtils.parseTime(mDepFine.group(4))); predictedTime = new GregorianCalendar(timeZone());
parsed.set(Calendar.YEAR, current.get(Calendar.YEAR)); predictedTime.setTimeInMillis(currentTime.getTimeInMillis());
parsed.set(Calendar.MONTH, current.get(Calendar.MONTH)); ParserUtils.parseEuropeanTime(predictedTime, mDepFine.group(4));
parsed.set(Calendar.DAY_OF_MONTH, current.get(Calendar.DAY_OF_MONTH));
if (ParserUtils.timeDiff(parsed.getTime(), currentTime) < -PARSER_DAY_ROLLOVER_THRESHOLD_MS) if (predictedTime.getTimeInMillis() - currentTime.getTimeInMillis() < -PARSER_DAY_ROLLOVER_THRESHOLD_MS)
parsed.add(Calendar.DAY_OF_MONTH, 1); predictedTime.add(Calendar.DAY_OF_MONTH, 1);
predictedTime = parsed.getTime(); }
else
{
predictedTime = null;
} }
final String position = ParserUtils.resolveEntities(ParserUtils.selectNotNull(mDepFine.group(5), mDepFine.group(6))); 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, final Departure dep = new Departure(plannedTime.getTime(), predictedTime != null ? predictedTime.getTime() : null, line,
0, destination, null); line != null ? lineColors(line) : null, null, position, 0, destination, null);
if (!departures.contains(dep)) if (!departures.contains(dep))
departures.add(dep); departures.add(dep);

View file

@ -21,7 +21,6 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collections; import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import java.util.List; import java.util.List;
import java.util.regex.Matcher; 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 NetworkId NETWORK_ID = NetworkId.SBB;
public static final String OLD_NETWORK_ID = "fahrplan.sbb.ch"; 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_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; 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()) if (mHeadFine.matches())
{ {
final String location = ParserUtils.resolveEntities(mHeadFine.group(1)); final String location = ParserUtils.resolveEntities(mHeadFine.group(1));
final Date currentTime = ParserUtils.joinDateTime(ParserUtils.parseDate(mHeadFine.group(3)), final Calendar currentTime = new GregorianCalendar(timeZone());
ParserUtils.parseTime(mHeadFine.group(2))); currentTime.clear();
ParserUtils.parseEuropeanTime(currentTime, mHeadFine.group(2));
ParserUtils.parseGermanDate(currentTime, mHeadFine.group(3));
final int locationId = Integer.parseInt(mHeadFine.group(4)); final int locationId = Integer.parseInt(mHeadFine.group(4));
final List<Departure> departures = new ArrayList<Departure>(8); final List<Departure> departures = new ArrayList<Departure>(8);
// String oldZebra = null; // String oldZebra = null;
@ -166,19 +167,17 @@ public class SbbProvider extends AbstractHafasProvider
final String destination = ParserUtils.resolveEntities(mDepFine.group(2)); final String destination = ParserUtils.resolveEntities(mDepFine.group(2));
final Calendar current = new GregorianCalendar(); final Calendar parsedTime = new GregorianCalendar(timeZone());
current.setTime(currentTime); parsedTime.setTimeInMillis(currentTime.getTimeInMillis());
final Calendar parsed = new GregorianCalendar(); ParserUtils.parseEuropeanTime(parsedTime, mDepFine.group(3));
parsed.setTime(ParserUtils.parseTime(mDepFine.group(3)));
parsed.set(Calendar.YEAR, current.get(Calendar.YEAR)); if (parsedTime.getTimeInMillis() - currentTime.getTimeInMillis() < -PARSER_DAY_ROLLOVER_THRESHOLD_MS)
parsed.set(Calendar.MONTH, current.get(Calendar.MONTH)); parsedTime.add(Calendar.DAY_OF_MONTH, 1);
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 String position = ParserUtils.resolveEntities(mDepFine.group(4)); 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)) if (!departures.contains(dep))
departures.add(dep); departures.add(dep);

View file

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

View file

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

View file

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

View file

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

View file

@ -17,10 +17,17 @@
package de.schildbach.pte.live; package de.schildbach.pte.live;
import java.util.Date;
import org.junit.Test; import org.junit.Test;
import de.schildbach.pte.RmvProvider; 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.NearbyStationsResult;
import de.schildbach.pte.dto.QueryConnectionsResult;
import de.schildbach.pte.dto.QueryDeparturesResult; import de.schildbach.pte.dto.QueryDeparturesResult;
/** /**
@ -29,6 +36,7 @@ import de.schildbach.pte.dto.QueryDeparturesResult;
public class RmvProviderLiveTest public class RmvProviderLiveTest
{ {
private final RmvProvider provider = new RmvProvider(); private final RmvProvider provider = new RmvProvider();
protected static final String ALL_PRODUCTS = "IRSUTBFC";
@Test @Test
public void nearbyStation() throws Exception public void nearbyStation() throws Exception
@ -45,4 +53,16 @@ public class RmvProviderLiveTest
System.out.println(result.stationDepartures); 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);
}
} }