Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi XML Datum kann nicht 0.0 sein? (https://www.delphipraxis.net/199942-xml-datum-kann-nicht-0-0-sein.html)

QuickAndDirty 4. Mär 2019 11:49

XML Datum kann nicht 0.0 sein?
 
Hallo, ich benutze SOAP zur Kommunikation zwischen Client und Server.
Nach Update auf Delphi 10.3 wirft diese Operation einen Fehler, aber NUR auf Android! In einem Windows kompilat geht es.
In 10.2 geht es auch auf Android.
Delphi-Quellcode:
  lastUpdate := TXSDatetime.Create;
  lastUpdate.AsDateTime := 0.0; //Das hier geht jetzt nicht mehr in Android...

TiGü 4. Mär 2019 13:11

AW: XML Datum kann nicht 0.0 sein?
 
Kopiere dir doch mal die function DateTimeToXMLTime(Value: TDateTime; ApplyLocalBias: Boolean = True): InvString; aus der Unit Soap.XSBuiltIns direkt ins Projekt, reichere sie mit Log-Ausgaben an und versuche herauszufinden, welcher Schritt davon in Android nicht geht.
Scheitert es schon am FormatDateTime-Aufruf?

QuickAndDirty 5. Mär 2019 07:27

AW: XML Datum kann nicht 0.0 sein?
 
Ich entwickele auf einem Android 4.1 Gerät :(
Der Fehler wird auf dem Smartphone von einem kollegen ausgegeben...
Ich warte noch auf ein neueres Smartphone....um das selbst debuggen zu können.
Bis jetzt steht fest: der Fehler kommt aus dieser Zeile
Delphi-Quellcode:
function DateTimeToXMLTime(Value: TDateTime; ApplyLocalBias: Boolean = True): InvString;
const
  Neg: array[Boolean] of string= ('+', '-');
var
  Bias: Integer;
  tz:TTimeZone;
begin
  Result := FormatDateTime('yyyy''-''mm''-''dd''T''hh'':''nn'':''ss''.''zzz', Value); { Do not localize }
  tz := TTimeZone.Local;
  Bias := Trunc(tz.GetUTCOffset(Value).Negate.TotalMinutes);//<-------------HIER KOMMT DIE EXCEPTION HER
  if (Bias <> 0) and ApplyLocalBias then
  begin
    Result := Format('%s%s%.2d:%.2d', [Result, Neg[Bias > 0],                        { Do not localize }
                                       Abs(Bias) div MinsPerHour,
                                       Abs(Bias) mod MinsPerHour]);
  end else
    Result := Result + 'Z'; { Do not localize }
end;
Dank Delphi 10.3 bekomme ich dann irgendwann(hoffentlich in kürze)ein neues Entwicklungshandy, dann kann ich dem auf den Grund gehen...auch wenn ich davon ausgehe, dass es sinnlos ist, da Embarcadero es ja wieder so hinbiegen sollte, dass es funktioniert wie vorher, oder zumindest auf allen Plattformen gleich funktioniert.

TiGü 5. Mär 2019 13:46

AW: XML Datum kann nicht 0.0 sein?
 
Hast du denn den Aufruf für den Bias mal aufgeschlüsselt und dir nach jeden Step Log-Ausgaben gemacht?
Eigentlich sehe ich in Tokyo keine Plattform-spezifischen Sachen, aber ich habe auch nicht gründlich nachgeschaut.

Delphi-Quellcode:
uses
   System.DateUtils, Soap.InvokeRegistry, System.TimeSpan;

function DateTimeToXMLTime(Value: TDateTime; ApplyLocalBias: Boolean = True): InvString;
const
  Neg: array[Boolean] of string= ('+', '-');
var
  Bias: Integer;
  tz:TTimeZone;
  Offset: TTimeSpan;
  NegOffset: TTimeSpan;
  TotalMinutsBias: Double;
begin
  Result := FormatDateTime('yyyy''-''mm''-''dd''T''hh'':''nn'':''ss''.''zzz', Value); { Do not localize }
  tz := TTimeZone.Local;
  Offset := tz.GetUTCOffset(Value);
  NegOffset := Offset.Negate;
  TotalMinutsBias := NegOffset.TotalMinutes;
  Bias := Trunc(TotalMinutsBias);
  if (Bias <> 0) and ApplyLocalBias then
  begin
    Result := Format('%s%s%.2d:%.2d', [Result, Neg[Bias > 0], { Do not localize }
                                       Abs(Bias) div MinsPerHour,
                                       Abs(Bias) mod MinsPerHour]);
  end else
    Result := Result + 'Z'; { Do not localize }
end;

skoschke 5. Mär 2019 14:16

AW: XML Datum kann nicht 0.0 sein?
 
Warum ist der Formatstring so kryptisch?

FormatDateTime('yyyy-mm-dd''T''hh:nn:ss.zzz', Value)

ergibt doch ebenfalls z.B. "2019-03-05T15:15:23.123"

Ciao
Stefan

TiGü 5. Mär 2019 15:14

AW: XML Datum kann nicht 0.0 sein?
 
Das musst du den ursprünglichen Embarcadero/Codegear/Borland-Mitarbeiter fragen.
Das steht schon so in Delpi XE drin.

Schokohase 5. Mär 2019 15:25

AW: XML Datum kann nicht 0.0 sein?
 
Zitat:

Zitat von TiGü (Beitrag 1427003)
Das musst du den ursprünglichen Embarcadero/Codegear/Borland-Mitarbeiter fragen.
Das steht schon so in Delpi XE drin.

Weil der Entwickler sich die Dokumentation durchgelesen hat und sich dann (korrekt) für diese Variante entschieden hat.

Denn was bewirkt ein
Delphi-Quellcode:
:
im Format-String?
Zitat:

Zeigt als Uhrzeittrennzeichen das in der globalen Variablen TimeSeparator angegebene Zeichen an.
Und was bewirken die einfachen oder doppelten Anführungszeichen im Format-String?
Zitat:

In halbe oder ganze Anführungszeichen eingeschlossene Zeichen wirken sich nicht auf die Formatierung aus und werden wie eingegeben angezeigt.
Also um auf Nummer Sicher zu gehen werden ALLE Zeichen die sich niemals ändern dürfen entsprechend von Anführungsstrichen umschlossen.

Da hat sich tatsächlich der Entwickler mal etwas bei gedacht und nicht nur von der Tapete bis zur Wand (wie man es an manchen Stellen leider zu oft sieht).

TiGü 5. Mär 2019 15:41

AW: XML Datum kann nicht 0.0 sein?
 
Wird wirklich Zeit, dass die Forensoftware der internationalen DP auch hier eingeführt wird. Ich möchte mich für die meisten deiner Beiträge per einfachen Klick bedanken. Immer kurz und knackig auf den Punkt und lehrreich dazu.
:thumb:

Der schöne Günther 5. Mär 2019 17:15

AW: XML Datum kann nicht 0.0 sein?
 
Um nochmal zum eigentlichen Problem zurückzukommen: Was für eine Exception?

Wenn
Delphi-Quellcode:
Bias := Trunc(tz.GetUTCOffset(Value).Negate.TotalMinutes);
wirklich auf manchen Plattformen eine Exception auslöst, was könnte es sein? Ein Überlauf sodass das Ergebnis von
Delphi-Quellcode:
Trunc(..)
nicht mehr in einen Integer passt?


Vielleicht dass
Delphi-Quellcode:
TTimeZone.Local.GetUtcOffset(..)
irgendwas schräges liefert...

TiGü 6. Mär 2019 08:51

AW: XML Datum kann nicht 0.0 sein?
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1427009)
Um nochmal zum eigentlichen Problem zurückzukommen: Was für eine Exception?

Ja, stimmt!
Schade das QuickAndDirty das nicht mit dazu geschrieben hat.
Obwohl er schon so lange im Forum mit dabei ist und er deswegen eigentlich wissen müsste, dass es eine essentielle Information ist.
Ich debugge mich gerade durch die Aufrufe durch.

Delphi-Quellcode:
System.DateUtils.TLocalTimeZone.TimeZoneChanged
System.DateUtils.TLocalTimeZone.GetCachedChangesForYear(2019)
System.DateUtils.TLocalTimeZone.DoGetOffsetsAndType(43554,96875,4676218962906710016,18721139674706580,lttStandard)
System.DateUtils.TTimeZone.GetUtcOffsetInSeconds(43554,96875,False)
Die Funktion TimeZoneChanged hat in meiner Version $IF-Defs für Windows, MacOS und POSIX. Ich nehme an, Android wird als POSIX Betriebssystem abgehandelt, da im Kern ein Linux.
Da wird bspw. localtime_r aufgerufen (https://linux.die.net/man/3/localtime_r).

In TTimeZone.GetUtcOffsetInSeconds besteht die Möglichkeit, dass eine ELocalTimeInvalid-Exception geworfen wird.
TTimeSpan.GetScaledInterval: EArgumentException.
TTimeSpan.Negate: EIntOverflow.
Trunc wird am Ende und intern beim Durchlauf ein-zweimal aufgerufen. Da wäre ggf. auch eine Fehlerquelle, falls die Umsetzung für Android/Linux fehlerhaft ist (
Delphi-Quellcode:
{       functions & procedures that need compiler magic }
)

QuickAndDirty 6. Mär 2019 14:28

AW: XML Datum kann nicht 0.0 sein?
 
Ich würde gerne mehr dazu sagen, aber ich versuche seit dem letzten Post Delphi 10.3 mit dem NOKIA 6.1(Android 9) zum debuggen zu verbinden...
leider bleibt die IDE dann in der Anzeige

"Installieren von"
c:\MeinOrdner\Meine.apk

hängen....
Und ich bekomme das Handy(Sony Z3) von dem Kollegen nicht welches ja ginge...

Aus dem kopf weiß ich die Exception nicht mehr genau,
aber es hieß irgendwie "Datum liegt vor der Sommerzeit"

TiGü 6. Mär 2019 14:36

AW: XML Datum kann nicht 0.0 sein?
 
Zitat:

Zitat von QuickAndDirty (Beitrag 1427082)
Aus dem kopf weiß ich die Exception nicht mehr genau,
aber es hieß irgendwie "Datum liegt vor der Sommerzeit"

Also jene welche?

Delphi-Quellcode:
SLocalTimeInvalid = 'Die angegebene "%s" lokale Uhrzeit ist ungültig (befindet sich im fehlenden Zeitraum vor der Sommerzeit).';

QuickAndDirty 7. Mär 2019 10:42

AW: XML Datum kann nicht 0.0 sein?
 
Ja!
WoW!
Aber warum wird diese Exception auf Delphi 10.3 Android geworfen?

[OT]
mein ADB install
bleibt in der Zeile
hängen
ADB.exe D 03-06 17:17:47 2616 2640 commandline.cpp:372] copy_to_file(2048 -> 2049)
:(
Wieso macht das telefon sowas...

Und das wurde extra angeschafft damit ich den scheiß datums fehler debuggen kann...jetzt schlage ich mich seit tagen damit herum...die app per ADB(oder delphi) auf das phone zu bekommen.
Manchmal hasse ich den Scheiß.
[/O]

TiGü 7. Mär 2019 10:52

AW: XML Datum kann nicht 0.0 sein?
 
Kenne mich damit wirklich nicht aus, aber mir ist in Erinnerung geblieben, wenn sowas nicht geht, dass man per Android Studio ein leeres Projekt erzeugen und rüberspielen soll. Die Suchfunktion hier in der DP sollte dir weiterhelfen.

Sherlock 7. Mär 2019 10:53

AW: XML Datum kann nicht 0.0 sein?
 
Zitat:

Zitat von TiGü (Beitrag 1427006)
Wird wirklich Zeit, dass die Forensoftware der internationalen DP auch hier eingeführt wird. Ich möchte mich für die meisten deiner Beiträge per einfachen Klick bedanken. Immer kurz und knackig auf den Punkt und lehrreich dazu.
:thumb:

Sehe ich genauso!

Sherlock

QuickAndDirty 13. Mär 2019 16:24

AW: XML Datum kann nicht 0.0 sein?
 
Yay, ich kann wieder debuggen....

Der Fehler wird vermutlich(=ich bin nicht sicher) von dem Aufruf der Plattformspezifischen Methode

System.Dateutils.TlocalTimezone.GetChangesForYear

ausgelöst.

:(


WIN32 kann 1899
Delphi-Quellcode:
 
{ Win32 can't handle dates outside this range }
  if (AYear <= 1601) or (AYear > 30827) then
    exit;
POSIX kann 1899 nicht
Delphi-Quellcode:
  if (SizeOf(LongInt) = 4) and ((AYear < 1970) or (AYear > 2037)) then
    Exit; // Not supported
Bin gerade noch mitten drin... mal sehen ob es das ist...

Also System.Dateutils.TlocalTimezone.GetChangesForYear Fügt einen Record in den LChanges Cache hinzu für 1899
Lchanges ist der Cache für YearlyChanges....was auch immer das heist

Dieser record sollte eigentlich komplett leer sein so wie ich das verstanden habe, ODER?

Leider scheint das nicht der fall zu sein.

Die Funktion GETTYPE findet dann den YearlyChangesRecord doof.

Delphi-Quellcode:
function TLocalTimeZone.GetType(const ADateTime: TDateTime; const AChanges: TYearlyChanges): TLocalTimeType;

 function After(const Point: TDateTime): Boolean;
 begin
   Result := CompareDateTime(ADateTime, Point) >= 0;
 end;

 function AfterSum(const Point: TDateTime; const Sum: Int64): Boolean;
 begin
   Result := CompareDateTime(ADateTime, IncSecond(Point, Sum)) >= 0;
 end;

 function Before(const Point: TDateTime): Boolean;
 begin
   Result := CompareDateTime(ADateTime, Point) < 0;
 end;

 function BeforeSum(const Point: TDateTime; const Sum: Int64): Boolean;
 begin
   Result := CompareDateTime(ADateTime, IncSecond(Point, Sum)) < 0;
 end;

var
  LDstSave: Int64;
begin
  { Default to normal }
  Result := lttStandard;

  { Calculate the save }
  LDstSave := (AChanges.FBiasWithDST - AChanges.FBias);//<--- DAS HIER MÜSSTE 0 Ergeben und alles wäre gut ????  Result := lttStandard;

  { Check only if we have a DST bias ... }
  if LDstSave <> 0 then///<------------ LEIDER geht das Programm hier rein :(
  begin
    { NOTE: Apparently there are Countries that use inverse DST rules. This means that instead
      of adjusting their clocks +xxx time in the summer/winter, they adjust by -xxxx at the opposite
      season. In this particular case, LDstSave would be a negative number and thus the invalid/ambiguous
      rules change from start -> end to end -> start.
    }
    if LDstSave > 0 then///<------------ LEIDER HIER AUCH
    begin
      { Invalid time between transitions (Normal Daylight) }
      if After(AChanges.FStartOfDST) and BeforeSum(AChanges.FStartOfDST, LDstSave) then ///<------------ DANN HIER DER Ausstieg Exit(lttInvalid);
        Exit(lttInvalid);

      { Ambiguous time between transitions (Normal Daylight) }
      if Before(AChanges.FEndOfDST) and AfterSum(AChanges.FEndOfDST, -LDstSave) then
        Exit(lttAmbiguous);
    end else
    begin
      { Invalid time between transitions (Inverse Daylight) }
      if Before(AChanges.FStartOfDST) and AfterSum(AChanges.FStartOfDST, LDstSave) then
        Exit(lttInvalid);

      { Ambiguous time between transitions (Inverse Daylight) }
      if After(AChanges.FEndOfDST) and BeforeSum(AChanges.FEndOfDST, -LDstSave) then
        Exit(lttAmbiguous);
    end;

    { Northern Hemisphere OR "Winter Daylight" }
    if (CompareDateTime(AChanges.FStartOfDST, AChanges.FEndOfDST) < 0) and
       (After(AChanges.FStartOfDST) and Before(AChanges.FEndOfDST)) then
      Exit(lttDaylight);

    { Southern Hemisphere OR "Summer Daylight" }
    if (CompareDateTime(AChanges.FStartOfDST, AChanges.FEndOfDST) > 0) and
       (After(AChanges.FStartOfDST) or Before(AChanges.FEndOfDST)) then
      Exit(lttDaylight);
  end;
end;
Ihr habt nicht zufällig ne idee wie man das in ordnung bringt?


1971 als basisdatum nutzen?

Ich brauche 1899 aus Kompatibilitätsgründen zu Firebird und TDatetime in anderen programmen...

Delphi.Narium 13. Mär 2019 16:45

AW: XML Datum kann nicht 0.0 sein?
 
Unixtimestamp = Sekunden seit 1.1.1970 00:00:00 UTC

Unixtimestamp = Integer

Max(Integer) = 2.147.483.647

1 Jahr = 31.556.926 Sekunden (365,24 Tage)

2.147.483.647 / 31.556.926 = 68,051103805231219289229882530383

1.1.1970 + 68 = ca. 2037 bis zum Überlauf.

Wenn ich die zitierte Quelltextzeile recht verstehen, müsste die Berechnung aber, soweit LongInt größer oder kleiner als 4 Byte groß ist, funktionieren.

Definiere doch LongInt mal um, z. B. auf LongInt = Byte. Dann sollte das doch gehen oder? :-)

Ok, das ist jetzt böse, aber:

Der Sinn der zitierten Quelltextzeile erscheint mir doch eher fraglich. Und wenn daraus "nicht näher zu ergründende" Folgefehler resultieren, scheint mir das eher wahrscheinlich.

QuickAndDirty 13. Mär 2019 17:07

AW: XML Datum kann nicht 0.0 sein?
 
Lustig...
Delphi-Quellcode:
  lastUpdate := TXSDatetime.Create;
  lastUpdate.AsUTCDattime := 0.0; //Das hier geht jetzt nicht mehr in Android...

versucht auch den "Localbias" und die Zeitzone zu ermitteln... man weiß ja nie wie sehr UTC von UTC abweicht....
Und stürzt dabei genauso ab....

@Delphinarium ich versuche dafür zu sorgen dass
Delphi-Quellcode:
  lastUpdate := TXSDatetime.Create;
  lastUpdate.AsDateTime := 0.0; //Das hier geht jetzt nicht mehr in Android...
in Delphi Rio weiterhin funktioniert...wie in Delphi Tokyo
:(

irgendwo dadrin passiert das
Delphi-Quellcode:
function DateTimeToXMLTime(Value: TDateTime; ApplyLocalBias: Boolean = True): InvString;
const
  Neg: array[Boolean] of string= ('+', '-');
var
  Bias: Integer;
  tz:TTimeZone;
begin
  Result := FormatDateTime('yyyy''-''mm''-''dd''T''hh'':''nn'':''ss''.''zzz', Value); { Do not localize }
  tz := TTimeZone.Local;
  Bias := Trunc(tz.GetUTCOffset(Value).Negate.TotalMinutes);
  if (Bias <> 0) and ApplyLocalBias then
  begin
    Result := Format('%s%s%.2d:%.2d', [Result, Neg[Bias > 0],                        { Do not localize }
                                       Abs(Bias) div MinsPerHour,
                                       Abs(Bias) mod MinsPerHour]);
  end else
    Result := Result + 'Z'; { Do not localize }
end;
TTimZone.GetUTCOffset versucht aus einem Cache die Offsets für Daylight savingstime zu ermitteln... Weil sich sowas Jahr für Jahr und Land für Land ändert...
Dabei dann schmeißt Embarcadero mit Fehlern (Localtimetype =lttInvalid) für 1899 um sich :(
Das war vorher nicht so!

:(

Delphi.Narium 13. Mär 2019 17:46

AW: XML Datum kann nicht 0.0 sein?
 
DateTimeToUnix und UnixToDateTime (aus DateUtils bei Delphi 7) zur Konvertierung zwischen den "Welten" nutzen?

Die Konvertierung von Unix nach TDateTime scheint mir damit plausibel zu sein, aber von DateTime nach Unix nicht. Aus dem 30.12.1899 wird als Unix 2085805696, das zurückverwandelt ergibt aber 05.02.2036 06:28:16.

Delphi-Quellcode:
lastUpdate := TXSDatetime.Create;
  lastUpdate.AsDateTime := 0.0; //Das hier geht jetzt nicht mehr in Android...
schon klar, aber 0 ist nunmal < 1970 und deshalb fliegt Dir das "irgendwie" um die Ohren.

Der 01.01.1970 ist als TDateTime = 25569 das entspricht also 0 als Unix.

Wenn es Dir darum geht z. B. kein Datum = 0 in "beiden Welten" zu ermöglichen, so musst Du da wohl die 25569 irgendwie als Korrekturwert einbauen.

Ok, andererseits: Wo ist der Cache? Ist sein Inhalt unter Android (in der speziellen Delphiversion) eventuell fehlerhaft befüllt?

Wo kommst Du mit dem Debugger hin, wenn Du hier noch weiter durchsteppst?

Delphi-Quellcode:
if After(AChanges.FStartOfDST) and BeforeSum(AChanges.FStartOfDST, LDstSave) then ///<------------ DANN HIER DER Ausstieg Exit(lttInvalid);

After und BeforeSum müssen doch auch noch irgendwas machen, um den Schluss ziehen zu können, dass das Datum 0 / 30.12.1899 lttInvalid ist.

Und hier müssen sich irgendwelche Unterschiede bei den Delphiversionen ergeben. Hast Du die Möglichkeit mal in zwei IDEs quasi parallel mit dem Debugger dadurchzugehen, um so die Problemursache zu finden?

Hast Du die Quellen der unterschiedlichen Delphiversionen und kannst die betroffenen Units mal mit 'nem Diff vergleichen?

QuickAndDirty 13. Mär 2019 21:56

AW: XML Datum kann nicht 0.0 sein?
 
Fuck me!
Klar ich habe beide Delphis in Virtuellen maschienen, und zwei smartphones mit jeweils passendem Android

0.0 mag 1970 sein, aber GetUTCOffset(Value) rechnet mit 1899 weiter. nicht mit 1970...

Ich gucke mal wie das in 10.2 läuft.


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:51 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz