mirror of
https://gitlab.com/oeffi/public-transport-enabler.git
synced 2025-07-13 16:20:34 +00:00
use correct timezone
git-svn-id: https://public-transport-enabler.googlecode.com/svn/trunk@535 0924bc21-9374-b0fa-ee44-9ff1593b38f0
This commit is contained in:
parent
4d745ee647
commit
2524ad72b3
2 changed files with 93 additions and 62 deletions
|
@ -19,7 +19,6 @@ package de.schildbach.pte;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
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;
|
||||||
|
@ -28,6 +27,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;
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@ 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;
|
||||||
|
@ -383,7 +384,9 @@ 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 Date currentDate = ParserUtils.parseDate(mHead.group(3));
|
final Calendar currentDate = new GregorianCalendar(TIME_ZONE);
|
||||||
|
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 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>();
|
||||||
|
@ -395,20 +398,24 @@ 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));
|
||||||
Date departureTime = ParserUtils.joinDateTime(currentDate, ParserUtils.parseTime(mConFine.group(2)));
|
final Calendar departureTime = new GregorianCalendar(TIME_ZONE);
|
||||||
|
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_ROLLDOWN_THRESHOLD_MS)
|
else if (diff < -PARSER_DAY_ROLLDOWN_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(TIME_ZONE);
|
||||||
|
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
|
||||||
|
@ -459,7 +466,9 @@ 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 Date currentDate = ParserUtils.parseDate(mHead.group(1));
|
final Calendar currentDate = new GregorianCalendar(TIME_ZONE);
|
||||||
|
currentDate.clear();
|
||||||
|
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);
|
||||||
|
|
||||||
Date firstDepartureTime = null;
|
Date firstDepartureTime = null;
|
||||||
|
@ -497,9 +506,11 @@ public final class BvgProvider extends AbstractHafasProvider
|
||||||
final String min = mDetFine.group(14);
|
final String min = mDetFine.group(14);
|
||||||
if (min == null)
|
if (min == null)
|
||||||
{
|
{
|
||||||
Date departureTime = ParserUtils.joinDateTime(currentDate, ParserUtils.parseTime(mDetFine.group(6)));
|
final Calendar departureTime = new GregorianCalendar(TIME_ZONE);
|
||||||
if (lastArrivalTime != null && departureTime.before(lastArrivalTime))
|
departureTime.setTimeInMillis(currentDate.getTimeInMillis());
|
||||||
departureTime = ParserUtils.addDays(departureTime, 1);
|
ParserUtils.parseEuropeanTime(departureTime, mDetFine.group(6));
|
||||||
|
if (lastArrivalTime != null && departureTime.getTime().before(lastArrivalTime))
|
||||||
|
departureTime.add(Calendar.DAY_OF_YEAR, 1);
|
||||||
|
|
||||||
final String departurePosition = mDetFine.group(7);
|
final String departurePosition = mDetFine.group(7);
|
||||||
|
|
||||||
|
@ -510,9 +521,11 @@ 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]);
|
||||||
|
|
||||||
Date arrivalTime = ParserUtils.joinDateTime(currentDate, ParserUtils.parseTime(mDetFine.group(10)));
|
final Calendar arrivalTime = new GregorianCalendar(TIME_ZONE);
|
||||||
|
arrivalTime.setTimeInMillis(currentDate.getTimeInMillis());
|
||||||
|
ParserUtils.parseEuropeanTime(arrivalTime, mDetFine.group(10));
|
||||||
if (departureTime.after(arrivalTime))
|
if (departureTime.after(arrivalTime))
|
||||||
arrivalTime = ParserUtils.addDays(arrivalTime, 1);
|
arrivalTime.add(Calendar.DAY_OF_YEAR, 1);
|
||||||
|
|
||||||
final String arrivalPosition = mDetFine.group(11);
|
final String arrivalPosition = mDetFine.group(11);
|
||||||
|
|
||||||
|
@ -522,14 +535,14 @@ public final class BvgProvider extends AbstractHafasProvider
|
||||||
|
|
||||||
final Location arrival = new Location(LocationType.STATION, arrivalId, arrivalPlaceAndName[0], arrivalPlaceAndName[1]);
|
final Location arrival = new Location(LocationType.STATION, arrivalId, arrivalPlaceAndName[0], arrivalPlaceAndName[1]);
|
||||||
|
|
||||||
parts.add(new Connection.Trip(line, destination, departureTime, departurePosition, departure, arrivalTime, arrivalPosition,
|
parts.add(new Connection.Trip(line, destination, departureTime.getTime(), departurePosition, departure,
|
||||||
arrival, null, null));
|
arrivalTime.getTime(), arrivalPosition, arrival, null, null));
|
||||||
|
|
||||||
if (firstDepartureTime == null)
|
if (firstDepartureTime == null)
|
||||||
firstDepartureTime = departureTime;
|
firstDepartureTime = departureTime.getTime();
|
||||||
|
|
||||||
lastArrival = arrival;
|
lastArrival = arrival;
|
||||||
lastArrivalTime = arrivalTime;
|
lastArrivalTime = arrivalTime.getTime();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -564,10 +577,10 @@ public final class BvgProvider extends AbstractHafasProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstDepartureTime != null && lastArrivalTime != null)
|
if (firstDepartureTime != null && lastArrivalTime != null)
|
||||||
return new GetConnectionDetailsResult(currentDate, new Connection(AbstractHafasProvider.extractConnectionId(uri), uri,
|
return new GetConnectionDetailsResult(currentDate.getTime(), new Connection(AbstractHafasProvider.extractConnectionId(uri), uri,
|
||||||
firstDepartureTime, lastArrivalTime, firstDeparture, lastArrival, parts, null));
|
firstDepartureTime, lastArrivalTime, firstDeparture, lastArrival, parts, null));
|
||||||
else
|
else
|
||||||
return new GetConnectionDetailsResult(currentDate, null);
|
return new GetConnectionDetailsResult(currentDate.getTime(), null);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -597,7 +610,7 @@ public final class BvgProvider extends AbstractHafasProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Pattern P_DEPARTURES_HEAD = Pattern.compile(".*?" //
|
private static final Pattern P_DEPARTURES_HEAD = Pattern.compile(".*?" //
|
||||||
+ "<strong>(.*?)</strong>.*?Datum:(.*?)<br />.*" //
|
+ "<strong>(.*?)</strong>.*?Datum:\\s*([^<\n]+)[<\n].*?" //
|
||||||
, Pattern.DOTALL);
|
, Pattern.DOTALL);
|
||||||
private static final Pattern P_DEPARTURES_COARSE = Pattern.compile("" //
|
private static final Pattern P_DEPARTURES_COARSE = Pattern.compile("" //
|
||||||
+ "<tr class=\"ivu_table_bg\\d\">\\s*((?:<td class=\"ivu_table_c_dep\">|<td>).+?)\\s*</tr>" //
|
+ "<tr class=\"ivu_table_bg\\d\">\\s*((?:<td class=\"ivu_table_c_dep\">|<td>).+?)\\s*</tr>" //
|
||||||
|
@ -646,7 +659,9 @@ 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 Date currentTime = parseDate(mHead.group(2));
|
final Calendar currentTime = new GregorianCalendar(TIME_ZONE);
|
||||||
|
currentTime.clear();
|
||||||
|
parseDateTime(currentTime, mHead.group(2));
|
||||||
final List<Departure> departures = new ArrayList<Departure>(8);
|
final List<Departure> departures = new ArrayList<Departure>(8);
|
||||||
|
|
||||||
// choose matcher
|
// choose matcher
|
||||||
|
@ -656,24 +671,21 @@ 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 current = new GregorianCalendar();
|
final Calendar parsedTime = new GregorianCalendar(TIME_ZONE);
|
||||||
current.setTime(currentTime);
|
parsedTime.setTimeInMillis(currentTime.getTimeInMillis());
|
||||||
final Calendar parsed = new GregorianCalendar();
|
ParserUtils.parseEuropeanTime(parsedTime, mDepFine.group(1));
|
||||||
parsed.setTime(ParserUtils.parseTime(mDepFine.group(1)));
|
|
||||||
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);
|
|
||||||
|
|
||||||
boolean isPlanned = mDepFine.group(2) != null;
|
boolean isPlanned = mDepFine.group(2) != null;
|
||||||
|
|
||||||
Date plannedTime = null;
|
Date plannedTime = null;
|
||||||
Date predictedTime = null;
|
Date predictedTime = null;
|
||||||
if (!isPlanned)
|
if (!isPlanned)
|
||||||
predictedTime = parsed.getTime();
|
predictedTime = parsedTime.getTime();
|
||||||
else
|
else
|
||||||
plannedTime = parsed.getTime();
|
plannedTime = parsedTime.getTime();
|
||||||
|
|
||||||
final String line = normalizeLine(ParserUtils.resolveEntities(mDepFine.group(3)));
|
final String line = normalizeLine(ParserUtils.resolveEntities(mDepFine.group(3)));
|
||||||
|
|
||||||
|
@ -725,7 +737,9 @@ 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 Date currentTime = parseDate(mHead.group(2));
|
final Calendar currentTime = new GregorianCalendar(TIME_ZONE);
|
||||||
|
currentTime.clear();
|
||||||
|
ParserUtils.parseGermanDate(currentTime, mHead.group(2));
|
||||||
final List<Departure> departures = new ArrayList<Departure>(8);
|
final List<Departure> departures = new ArrayList<Departure>(8);
|
||||||
|
|
||||||
// choose matcher
|
// choose matcher
|
||||||
|
@ -735,17 +749,14 @@ 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 current = new GregorianCalendar();
|
final Calendar parsedTime = new GregorianCalendar(TIME_ZONE);
|
||||||
current.setTime(currentTime);
|
parsedTime.setTimeInMillis(currentTime.getTimeInMillis());
|
||||||
final Calendar parsed = new GregorianCalendar();
|
ParserUtils.parseEuropeanTime(parsedTime, 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 (parsedTime.getTimeInMillis() - currentTime.getTimeInMillis() < -PARSER_DAY_ROLLOVER_THRESHOLD_MS)
|
||||||
|
parsedTime.add(Calendar.DAY_OF_MONTH, 1);
|
||||||
|
|
||||||
|
final Date plannedTime = parsedTime.getTime();
|
||||||
|
|
||||||
final String line = normalizeLine(ParserUtils.resolveEntities(mDepFine.group(2)));
|
final String line = normalizeLine(ParserUtils.resolveEntities(mDepFine.group(2)));
|
||||||
|
|
||||||
|
@ -777,23 +788,16 @@ public final class BvgProvider extends AbstractHafasProvider
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Date parseDate(String str)
|
private static final Pattern P_DATE_TIME = Pattern.compile("([^,]*), (.*?)");
|
||||||
|
|
||||||
|
private static final void parseDateTime(final Calendar calendar, final CharSequence str)
|
||||||
{
|
{
|
||||||
try
|
final Matcher m = P_DATE_TIME.matcher(str);
|
||||||
{
|
if (!m.matches())
|
||||||
return new SimpleDateFormat("dd.MM.yyyy, HH:mm:ss").parse(str);
|
throw new RuntimeException("cannot parse: '" + str + "'");
|
||||||
}
|
|
||||||
catch (ParseException x1)
|
ParserUtils.parseGermanDate(calendar, m.group(1));
|
||||||
{
|
ParserUtils.parseEuropeanTime(calendar, m.group(2));
|
||||||
try
|
|
||||||
{
|
|
||||||
return new SimpleDateFormat("dd.MM.yy").parse(str);
|
|
||||||
}
|
|
||||||
catch (ParseException x2)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(x2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Pattern P_NORMALIZE_LINE = Pattern.compile("([A-Za-zÄÖÜäöüßáàâéèêíìîóòôúùû]+)[\\s-]*(.*)");
|
private static final Pattern P_NORMALIZE_LINE = Pattern.compile("([A-Za-zÄÖÜäöüßáàâéèêíìîóòôúùû]+)[\\s-]*(.*)");
|
||||||
|
|
|
@ -311,6 +311,33 @@ public final class ParserUtils
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
final Matcher m = P_GERMAN_DATE.matcher(str);
|
||||||
|
if (!m.matches())
|
||||||
|
throw new RuntimeException("cannot parse: '" + str + "'");
|
||||||
|
|
||||||
|
calendar.set(Calendar.DAY_OF_MONTH, Integer.parseInt(m.group(1)));
|
||||||
|
calendar.set(Calendar.MONTH, Integer.parseInt(m.group(2)) - 1);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
final Matcher m = P_EUROPEAN_TIME.matcher(str);
|
||||||
|
if (!m.matches())
|
||||||
|
throw new RuntimeException("cannot parse: '" + str + "'");
|
||||||
|
|
||||||
|
calendar.set(Calendar.HOUR_OF_DAY, 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);
|
||||||
|
}
|
||||||
|
|
||||||
public static Date parseAmericanTime(final String str)
|
public static Date parseAmericanTime(final String str)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue