... the user friendly GPS tool


Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Fehler bei der Behandlung von Zeitzonen?
#1
Hallo,

Ich bin grade dabei, RouteConverter zum Parsen von GPS-Logdateien in meine Anwendung einzubinden und glaube (auch nach Lektüre des Quelltextes), auf einen ziemlich gravierenden Bug gestoßen zu sein, zumindest beim Lesen von NMEA-Dateien, aber vermutlich auch bei einigen anderen Formaten. Es kommt mir aber etwas seltsam vor, daß das noch niemand bemerkt hat, vielleicht übersehe ich auch was.

Das Problem ist, daß die Zeitstempel aus den Dateien mit der Default-Zeitzone geparst werden, d.h. hierzulande Europe/Berlin. Das stimmt aber nicht, da die Geräte (meins jedenfalls) die Zeit in UTC speichern, so wie sie im GPS-Signal enthalten ist. Kann sein, daß sich das beim Konvertieren ausgleicht, wenn beim Speichern die gleiche falsche Zeitzone verwendet wird, beim Parsen kommt jedenfalls nicht das richtige Ergebnis raus.

Zur Behebung müßte im Code bei jeder Verwendung von Calendar.getInstance(), new SimpleDateFormat() und ähnlichem explizit die Zeitzone gesetzt werden, entweder UTC oder (falls es sowas gibt) die in der Datei angegebene. Als Workaround kann man zwar die Default-Zeitzone auf UTC setzen, aber das stört natürlich im Rest der Anwendung, und gemeinerweise kann man es nicht nur während des Parsens tun, da die DateFormat-Instanzen ja static sind.
Reply
#2
(12.07.2010, 23:37)brazzy Wrote: Ich bin grade dabei, RouteConverter zum Parsen von GPS-Logdateien in meine Anwendung einzubinden und glaube (auch nach Lektüre des Quelltextes), auf einen ziemlich gravierenden Bug gestoßen zu sein, zumindest beim Lesen von NMEA-Dateien, aber vermutlich auch bei einigen anderen Formaten. Es kommt mir aber etwas seltsam vor, daß das noch niemand bemerkt hat, vielleicht übersehe ich auch was.

Nachdem es so viele Nutzer gibt, vermute ich auch, daß Du etwas übersiehst.

(12.07.2010, 23:37)brazzy Wrote: Das Problem ist, daß die Zeitstempel aus den Dateien mit der Default-Zeitzone geparst werden, d.h. hierzulande Europe/Berlin.

Woraus schließt Du das?

(12.07.2010, 23:37)brazzy Wrote: Zur Behebung müßte im Code bei jeder Verwendung von Calendar.getInstance(), new SimpleDateFormat() und ähnlichem explizit die Zeitzone gesetzt werden, entweder UTC oder (falls es sowas gibt) die in der Datei angegebene.

Bei NMEA z.B. wird der CompactCalendar verwendet:

public class CompactCalendar {
public static final TimeZone GMT = TimeZone.getTimeZone("GMT");

private final long timeInMillis;
private final String timeZoneId;

public static CompactCalendar fromCalendar(Calendar calendar) {
return new CompactCalendar(calendar.getTimeInMillis(), calendar.getTimeZone().getID());
}

public static CompactCalendar getInstance() {
return fromCalendar(Calendar.getInstance());
}

private CompactCalendar(long timeInMillis, String timeZoneId) {
this.timeInMillis = timeInMillis;
this.timeZoneId = timeZoneId.equals("GMT") ? "GMT" : timeZoneId.intern();
}

public long getTimeInMillis() {
return timeInMillis;
}

public String getTimeZoneId() {
return timeZoneId;
}

public Calendar getCalendar() {
Calendar result = Calendar.getInstance(getTimeZone());
result.setTimeInMillis(getTimeInMillis());
return result;
}

Du siehst: viel Gehampelt mit Zeitzonen.

Schau mal in den Code und schreib einen Test wie in TimeZoneTest, der zeigt, wo das Problem liegt.
--
Christian
Reply
#3
(13.07.2010, 07:30)routeconverter Wrote:
(12.07.2010, 23:37)brazzy Wrote: Das Problem ist, daß die Zeitstempel aus den Dateien mit der Default-Zeitzone geparst werden, d.h. hierzulande Europe/Berlin.

Woraus schließt Du das?
Na daraus, daß ich falsche Ergebnisse bekomme, und im Debugger verfolgen kann, wie die zustande kommen.

(13.07.2010, 07:30)routeconverter Wrote: Bei NMEA z.B. wird der CompactCalendar verwendet:

[...]

public static CompactCalendar fromCalendar(Calendar calendar) {
return new CompactCalendar(calendar.getTimeInMillis(), calendar.getTimeZone().getID());
}

public static CompactCalendar getInstance() {
return fromCalendar(Calendar.getInstance());
}

private CompactCalendar(long timeInMillis, String timeZoneId) {
this.timeInMillis = timeInMillis;
this.timeZoneId = timeZoneId.equals("GMT") ? "GMT" : timeZoneId.intern();
}

[...]

Du siehst: viel Gehampelt mit Zeitzonen.

Die Zeitzone wird aus dem übergebenen Calendar übernommen. Und woher hat der sie? In BaseNmeaFormat.java finde ich:

private static final DateFormat PRECISE_DATE_AND_TIME_FORMAT = new SimpleDateFormat("ddMMyy HHmmss.SSS");

[...]

Date parsed = PRECISE_DATE_AND_TIME_FORMAT.parse(dateAndTime);
Calendar calendar = Calendar.getInstance();
calendar.setTime(parsed);
return CompactCalendar.fromCalendar(calendar);


Tja, SimpleDateFormat nimmt leider die Default-Zeitzone wenn man sie nicht explizit setzt oder sie im Pattern vorkommt. Damit kommt schonmal beim Parsen das definitiv falsche Ergebnis raus. Daß der mit Calendar.getInstance() geholte Calendar dann die Default-Zeitzone in den CompactCalendar weitergibt ist dann auch schon egal.

Zeitzonen sind was ekliges, ich hab da bei meinem Projekt auch schon genug Lehrgeld bezahlt...

(13.07.2010, 07:30)routeconverter Wrote: Schau mal in den Code und schreib einen Test wie in TimeZoneTest, der zeigt, wo das Problem liegt.

Ist angehängt.


Attached Files
.txt   RouteConverterNmeaTest.java.txt (Size: 2.34 KB / Downloads: 722)
Reply
#4
(14.07.2010, 21:01)brazzy Wrote:
(13.07.2010, 07:30)routeconverter Wrote: Woraus schließt Du das?
Na daraus, daß ich falsche Ergebnisse bekomme, und im Debugger verfolgen kann, wie die zustande kommen.

Sorry, Du hast recht! Ich bin durch die vielen blinden Alarme etwas abgestumpft.

(14.07.2010, 21:01)brazzy Wrote: Tja, SimpleDateFormat nimmt leider die Default-Zeitzone wenn man sie nicht explizit setzt oder sie im Pattern vorkommt. Damit kommt schonmal beim Parsen das definitiv falsche Ergebnis raus.

Und an diversen Stellen wurde im Code Calendar.getInstance() benutzt. Die Testsuites haben das auch getan und damit das Problem verschleiert. Und die XML-Formate hatten einen kruden Fehler, der das ganze noch verschlimmbessert hat....

Ich habe eine Menge Code angefaßt, die Testsuites benutzen nun durchgängig GMT und ich hoffe, es ist kein Bug mehr drin. Bitte teste mal!
--
Christian
Reply
#5
So, zurück aus dem Urlaub...

(19.07.2010, 16:56)routeconverter Wrote: Ich habe eine Menge Code angefaßt, die Testsuites benutzen nun durchgängig GMT und ich hoffe, es ist kein Bug mehr drin. Bitte teste mal!

Ja, mit der aktuellen Vorabversion funktioniert's bei mir nun so wie es soll. Vielen Dank!
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)