[Gelöst] DateTime und Winterzeit

27. Oktober 2008 11:49

Hallo zusammen,

die Umstellung von Sommer- auf Winterzeit hat ein interessantes Phänomen an den Tag gebracht.
Um unser altes, noch in Betrieb befindliches Zeiterfassungssystem Schritt für Schritt in Navision unterzubringen, importiere ich jede Nacht die Daten der letzten drei Monate. Darin enthalten sind Datum, Startzeit, Endezeit und noch einiges mehr. Aufgrund der Probleme, die ich beim Import der Date und Time-Geschichten von Access nach Navision hatte, habe ich in Access eine Abfrage erstellt, welche mir die entsprechenden Felder als Text zurückgibt, und während des Importvorgangs wandle ich diesen Text wieder in gültige Werte vom Typ DateTime um. Das hat bis vor der Winterzeitumstellung wunderbar geklappt.

Nun rufe ich mir heute morgen die Navisiontabelle mit den Daten auf und .... alle Werte sind eine Stunde eher. Die Daten in Access haben sich nicht geändert, wenn ich mir während des Einlesens die Daten per Message anzeigen lasse, stehen da auch die korrekten Werte drin. Öffne ich jedoch die Navision-Tabelle, sind alle Zeiten um die eine Stunde verschoben. was hat das für einen Hintergrund bzw. wie kann ich das abfangen?
Zuletzt geändert von CaddyM am 28. Oktober 2008 13:44, insgesamt 1-mal geändert.

Re: DateTime und Winterzeit

27. Oktober 2008 15:24

Hallo,

kannst du mal kurz erklären, wie du DateTime von Access nach Navision konvertierst. Könnte es sein, das dabei die Umrechnung der Zeitzone auf der Strecke bleibt. NAV speichert DateTime als UTC-Zeit ab. Dafür bist du seit gestern Morgen in einer anderen Zeitzone. Oder hat dein Programm die Sommerzeit Umstellung nicht mitbekommen?

Gruß, Fiddi

Re: DateTime und Winterzeit

28. Oktober 2008 08:04

Hallo,

ich hab das einfach so gelöst:

Code:
          FLD_str := RS.Fields.Item('Start').Value;
          IF STRLEN(FLD_str) > 0 THEN
            EVALUATE(FLD_time, FLD_str)
          ELSE
            FLD_time := TIME;

          ZeZeile.VALIDATE(Erfassungszeit, CREATEDATETIME(FLD_date, FLD_time));

Ich lasse mir von Access einfach den Wert des Feldes vohrher als String zurückgeben und wandle den dann per EVALUATE um. In Access stehen auch die richtigen Werte (In Navision wohl auch), nur das die angezeigten Felder unnötigerweise entsprechend der Sommer / Winterzeit angezeigt werden, und zwar alle Datetimefelder.

Re: DateTime und Winterzeit

28. Oktober 2008 10:08

Das sieht auf den ersten Blick ganz OK aus. Ich kann mir nur noch vorstellen, das dein Programm,NAV bzw. NAV-Server die Zeitumstellung nicht richtig mitbekommen haben. Oder es gibt da ein generelles Problem bei CREATEDATETIME.

Teste doch mal folgendes:

Wenn du in eine Tabelle mit einem DateTime-Feld heute ein Datum aus der Sommerzeit mit CREATEDAETIME einfügst, passiert dann der gleiche Fehler mit der um eine Stunde falschen Zeit?. Wenn ja, würde ich mal vermuten, das CREATEDATETIME das übergebene Datum zur Ermittlung des korrekten Zeitoffsets heranzieht, was nicht unbedingt falsch ist. Die Anzeigeroutine rechnet die Zeit allerdings auf den aktuellen Zeitoffset um, was für eine Anwendung, die gleichzeitig in mehreren Zeitzonen läuft auch nicht falsch wäre, damit alle Anwender den auf Ihre Zeitzone bezogenen Timestamp sehen können.

Ich glaube dir bleibt nichts anderes über, als es nochmal mit zwei getrennten Feldern Date und Time zu probieren.

Gruß, Fiddi

Re: DateTime und Winterzeit

28. Oktober 2008 11:34

Hallo,

ich hab in der Zwischenzeit etwas rumprobiert. Das ganze ist ein reiner Anzeigefehler - Timewerte werden immer entsprechend der Zeitzone angezeigt. Ich hab daher ein kleines Workaround geschrieben, um für Anzeigen auf Formularen / Reports / etc. die Zeiten unabhängig anzeigen zu können:

Code:
fnDTWinterKorrektur(parDateTime : DateTime) : DateTime
//**************************************************************************
//***** Korrektur der Anzeige von Datetime-Werten in der Winterzeit
//***** Hintergrund: Datetime-Werte werden als UTC gespeichert. In der
//***** Winterzeit stimmt daher die Anzeige in Formularen nicht mehr.
//***** varDatumL: Date
//***** varDateL: Record (Date)
//***** varSommerzeitDatumL: Date
//***** varWinterzeitDatumL : Date
//**************************************************************************
varDatumL := DT2DATE(parDateTime);
IF varDatumL <> 0D THEN BEGIN

  //Sommerzeitwechsel holen - letzter Sonntag im März
  varDateL.RESET;
  varDateL.SETRANGE(varDateL."Period Type",varDateL."Period Type"::Date);
  varDateL.SETRANGE(varDateL."Period Start",
                    DMY2DATE(1,3,DATE2DMY(varDatumL,3)),
                    fnHoleGrenzDatum(3,DATE2DMY(varDatumL,3),'LETZTER'));
  varDateL.SETRANGE(varDateL."Period No.",7);
  IF varDateL.FINDLAST THEN
    varSommerzeitDatumL := varDateL."Period Start"
  ELSE
    ERROR('Kann keine Sommerzeitumstellung ermitteln (letzter Sonntag im März)');

  //Winterzeitwechsel holen - letzter Sonntag im Oktober
  varDateL.RESET;
  varDateL.SETRANGE(varDateL."Period Type",varDateL."Period Type"::Date);
  varDateL.SETRANGE(varDateL."Period Start",
                    DMY2DATE(1,10,DATE2DMY(varDatumL,3)),
                    fnHoleGrenzDatum(10,DATE2DMY(varDatumL,3),'LETZTER'));
  varDateL.SETRANGE(varDateL."Period No.",7);
  IF varDateL.FINDLAST THEN
    varWinterzeitDatumL := varDateL."Period Start"
  ELSE
    ERROR('Kann keine Winterzeitumstellung ermitteln (letzter Sonntag im Oktober)');

  //Entsprechend Sommer- oder Winterzeit die Datetime anpassen
  IF (varDatumL < varWinterzeitDatumL) AND (varDatumL >= varSommerzeitDatumL) THEN
    //Sommerzeit
    EXIT(parDateTime)
  ELSE
    //Winterzeitanzeige: Zeit anpassen
    EXIT(parDateTime + 3600000);

END ELSE
  EXIT(0DT);


Der Rückgabewert ist nur für die Anzeige gedacht - nicht zum Modifizieren von Werten in den Navision-Tabellen, da die Daten dort faktisch ja nicht falsch sind, sondern nur die Interpretierung während der Anzeige. In den dafür erstellten Reports und Forms funktioniert das einwandfrei, von daher: gelöst!

Re: [Gelöst]DateTime und Winterzeit

18. November 2008 13:11

Hallo,

ich würde gern den veröffentlichen Quellcode zum Thema "Sommer- / Winterzeit (Datetime)" verwenden. Leider fehlt mir der Code zu der Funktion "fnHoleGrenzDatum". Kann ich den Code auch irgendwo finden ?

Viele Grüße
Stefan