Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Cross-Platform-Entwicklung (https://www.delphipraxis.net/91-cross-platform-entwicklung/)
-   -   Delphi (Android) Fehler in DateUtils behoben // TTimezone.Local.ID // Ich bitte um Prüfung (https://www.delphipraxis.net/204980-android-fehler-dateutils-behoben-ttimezone-local-id-ich-bitte-um-pruefung.html)

QuickAndDirty 20. Jul 2020 14:39

(Android) Fehler in DateUtils behoben // TTimezone.Local.ID // Ich bitte um Prüfung
 
Wenn man
TTimezone.Local.ID innerhalb einer 64Bit Android App abruft,
dann meldet die APP in Deutschland als Zeitzonen-ID "ET" .
Das ist "Eastern Time" alias "Eastern Standard Time" alias "EST".

Korrekt wäre es, wenn als Zeitzone "CET"(deprecated) oder "Europe/Berlin" gemeldet würde
Selbst wenn ich die Zeitzone nach Portugal verlege, meldet die App dann nicht "WET" was korrekt wäre, sondern auch "ET" als Zeitzone.
Sprich der erste Buchstabe geht verloren! *ARRRGH*
Die App denkt also immer sie wäre in einer US-Zeitzone, weil es "ET" in meiner Datenbank tatsächlich gibt....

Ich habe also die Codestellen in der unit DateUtils.pas die diesen Code benutzen:
Delphi-Quellcode:
Einstring := Utf8ToString(LChars)
In folgenden Code geändert:
Delphi-Quellcode:
Einstring := Trim(TEncoding.UTF8.GetString(LChars))
;

Das Trim ist notwendig sonst funktionieren die Vergleiche nicht...
Vermutlich wäre es besser gewesen Utf8ToString zu fixen, aber ich habe mich das nicht getraut und ich habe die Typen rawstring usw. nicht auf Anhieb verstanden.

Bitte sagt mir ob die Anpassung in Ordnung ist. Soll ich das über meine Firma an die QC weitergeben oder ist das Problem schon von Emba gelöst?


Listing der ganzen Funktion in der 3 Stellen geöndert wurden.
(nach "Korrektur" ohne Gänsefüßchen suchen)
Delphi-Quellcode:
function TLocalTimeZone.GetChangesForYear(const AYear: Word): PYearlyChanges;
{$IF defined(MSWINDOWS)}
  function GetAbsoluteDateFromRule(const AYear, AMonth, ADoW, ADoWIndex: Word; AToD: TTime): TDateTime;
  const
    CReDoW: array [0 .. 6] of Integer = (7, 1, 2, 3, 4, 5, 6);

  var
    LExpDayOfWeek, LActualDayOfWeek: Word;

  begin
    { No actual rule }
    if (AMonth = 0) and (ADoW = 0) and (ADoWIndex = 0) then
      Exit(0);

    { Transform into ISO 8601 day of week }
    LExpDayOfWeek := CReDoW[ADoW];

    { Generate a date in the form of: Year/Month/1st of month }
    Result := EncodeDate(AYear, AMonth, 1);

    { Get the day of week for this newly crafted date }
    LActualDayOfWeek := DayOfTheWeek(Result);

    { We're too far off now, let's decrease the number of days till we get to the desired one }
    if LActualDayOfWeek > LExpDayOfWeek then
      Result := IncDay(Result, DaysPerWeek - LActualDayOfWeek + LExpDayOfWeek)
    else if (LActualDayOfWeek < LExpDayOfWeek) Then
      Result := IncDay(Result, LExpDayOfWeek - LActualDayOfWeek);

    { Skip the required number of weeks }
    Result := IncDay(Result, DaysPerWeek * (ADoWIndex - 1));

    { If we've skipped the day in this moth, go back a few weeks until we get it right again }
    while (MonthOf(Result) > AMonth) do
      Result := IncDay(Result, -DaysPerWeek);

    { Add the time part }
    Result := Result + AToD;
  end;

var
  LTZ: TTimeZoneInformation;
  LResult: Cardinal;

begin
  Result := AllocMem(SizeOf(TYearlyChanges));
  LTZ := Default(TTimeZoneInformation);

  { Win32 can't handle dates outside this range }
  if (AYear <= 1601) or (AYear > 30827) then
    exit;

  { Use either Vista of lower APIs. If Vista one fails, also use the lower API. }
  if TOSVersion.Check(6, 1, 1) and GetTimeZoneInformationForYear(AYear, nil, LTZ) then
    LResult := TIME_ZONE_ID_STANDARD
  else
    LResult := GetTimeZoneInformation(LTZ); { Try with the old API }

  { Exit on error }
  if LResult = TIME_ZONE_ID_INVALID then
    exit;

  { Try to obtain the daylight adjustment for the specified year }
  if LResult <> TIME_ZONE_ID_UNKNOWN then
  begin
    with LTZ.StandardDate do
      Result.FEndOfDST := GetAbsoluteDateFromRule(AYear, wMonth, wDayOfWeek,
        wDay, EncodeTime(wHour, wMinute, wSecond, 0));

    with LTZ.DaylightDate do
      Result.FStartOfDST := GetAbsoluteDateFromRule(AYear, wMonth, wDayOfWeek,
        wDay, EncodeTime(wHour, wMinute, wSecond, 0));
  end;

  Result.FBias := -SecsPerMin * (LTZ.StandardBias + LTZ.Bias);
  Result.FBiasWithDST := -SecsPerMin * (LTZ.DaylightBias + LTZ.Bias);
  Result.FName := LTZ.StandardName;
  Result.FDSTName := LTZ.DaylightName;
end;
{$ELSEIF defined(MACOS)}
function MacToDateTime(const AbsTime: CFAbsoluteTime; const ATZ: CFTimeZoneRef): TDateTime;
var
  LDate: CFGregorianDate;
begin
  { Decompose the object }
  LDate := CFAbsoluteTimeGetGregorianDate(AbsTime, ATZ);

  { Generate a TDateTime now }
  with LDate do
    Result := EncodeDateTime(year, month, day, hour, minute, Round(second), 0);
end;

procedure CopyInfo(const ATZ: CFTimeZoneRef; const AStartBT: CFAbsoluteTime; out LPt1DT, LPt2DT: TDateTime;
  out LPt1Off, LPt2Off: Int64);
var
  L1stTrans, L2ndTrans: CFAbsoluteTime;
begin
  { Calculate the first and the last transition times }
  L1stTrans := CFTimeZoneGetNextDaylightSavingTimeTransition(ATZ, AStartBT);
  L2ndTrans := CFTimeZoneGetNextDaylightSavingTimeTransition(ATZ, L1stTrans);

  { Obtain the GMT offset before first transition }
  LPt1Off := Round(CFTimeZoneGetSecondsFromGMT(ATZ, AStartBT));

  if (L1stTrans <> 0) or (L2ndTrans > L1stTrans) then
  begin
    { Convert the first transition to TDateTime }
    LPt1DT := MacToDateTime(L1stTrans, ATZ);

    { Convert the second transition to TDateTime }
    LPt2DT := MacToDateTime(L2ndTrans, ATZ);

    { Obtain the GMT offset before second transition }
    LPt2Off := Round(CFTimeZoneGetSecondsFromGMT(ATZ, L1stTrans));
  end else
  begin
    { There were no transitions. Use the base data }
    LPt2Off := LPt1Off;
    LPt1DT := MacToDateTime(AStartBT, ATZ);
    LPt2DT := LPt1DT;
  end;
end;

var
  LLocaleRef: CFLocaleRef;
  L1stJan: CFAbsoluteTime;
  LDate: CFGregorianDate;

  { What we expect }
  LStart, LEnd: TDateTime;
begin
  { Create the changes block. Keep it clean so far. }
  Result := AllocMem(SizeOf(TYearlyChanges));

  if FTZ <> nil then
  begin
    { Encode 1st Jan of the given year into Absolute time }
    with LDate do
    begin
      year := AYear;
      month := MonthJanuary;
      day := 1;
      hour := 0;
      minute := 0;
      second := 0;
    end;

    { Generate an absolute time (1st Jan Year) }
    L1stJan := CFGregorianDateGetAbsoluteTime(LDate, FTZ);

    { Use CopyInfo but reverse the variables depending on the Northern/Southern hemispheres }
    if not CFTimeZoneIsDaylightSavingTime(FTZ, L1stJan) then
      CopyInfo(FTZ, L1stJan, LStart, LEnd, Result.FBias, Result.FBiasWithDST)
    else
      CopyInfo(FTZ, L1stJan, LEnd, LStart, Result.FBiasWithDST, Result.FBias);

    { Fill the remaining parts of the structure }
    LLocaleRef := CFLocaleCopyCurrent();

    if LLocaleRef <> nil then
    begin
      { Obtain localized names of the locale (normal and DST) }
      try
        Result.FName := TCFString(CFTimeZoneCopyLocalizedName(FTZ,
          kCFTimeZoneNameStyleStandard, LLocaleRef)).AsString(True);

        Result.FDSTName := TCFString(CFTimeZoneCopyLocalizedName(FTZ,
          kCFTimeZoneNameStyleDaylightSaving, LLocaleRef)).AsString(True);
      finally
        CFRelease(LLocaleRef);
      end;
    end else
    begin
      { Fall back to std info }
      Result.FName := TCFString(CFTimeZoneGetName(FTZ));
      Result.FDSTName := Result.FName;
    end;

    Result.FStartOfDST := IncSecond(LStart, Result.FBias - Result.FBiasWithDST); // Remove the save time from result
    Result.FEndOfDST := IncSecond(LEnd, Result.FBiasWithDST - Result.FBias);    // Add the save time to result
  end;
end;
{$ELSEIF defined(POSIX)}
var
  LComp: tm;
  LTime: time_t;
  LLastOffset, LDay: Integer;
  LIsSecondCycle, LIsStandard: Boolean;
  LChars: TBytes;
begin
  SetLength(LChars, 256);
  { Create the changes block. Keep it clean so far. }
  Result := AllocMem(SizeOf(TYearlyChanges));

  if (SizeOf(LongInt) = 4) and ((AYear < 1970) or (AYear > 2037)) then
    Exit; // Not supported

  { Generate a value that starts with 1st of the current year }
  FillChar(LComp, SizeOf(LComp), 0);
  LComp.tm_mday := 1;
  LComp.tm_year := AYear - 1900;
  LTime := mktime(LComp);

  if LTime = -1 then
    Exit; // Some error occured!

  { Unknown DST information. Quit. }
  if LComp.tm_isdst < -1 then
    Exit;

  { Check if the DST or STD time was in effect at 1st Jan }
  LIsStandard := LComp.tm_isdst = 0;

  { Prepare to iterate over the year }
  LLastOffset := LComp.tm_gmtoff;
  LIsSecondCycle := false;

  { Initialize info, in some locales like Russia and in some years the clock is not changed for daylight saving }
  Result.FStartOfDST := IncSecond(FileDateToDateTime(LTime), LLastOffset - LComp.tm_gmtoff);
  Result.FEndOfDST := Result.FStartOfDST;
  Result.FBias := LLastOffset;
  Result.FDSTName := '';
  Result.FBiasWithDST := LLastOffset;
  strftime(MarshaledAString(LChars), Length(LChars), '%Z', LComp); // DO NOT LOCALIZE
  Result.FName := Trim(TEncoding.UTF8.GetString(LChars));//<----- Korrektur   Alter Code----> //  Result.FName := Utf8ToString(LChars);

  for LDay := 0 to DaysInAYear(AYear) - 1 do
  begin
    { Skip to next day }
    Inc(LTime, SecsPerDay);

    { Decompose the time }
    if localtime_r(LTime, LComp) <> @LComp then
      Exit;

    if LComp.tm_gmtoff <> LLastOffset then
    begin
      { We found the day when the time change occured. Serach the hour now. }

      repeat
        Dec(LTime, SecsPerHour);

        { Decompose the time }
        if localtime_r(LTime, LComp) <> @LComp then
          Exit;
      until LComp.tm_gmtoff = LLastOffset;

      { Search for the minute }
      repeat
        Inc(LTime, SecsPerMin);

        { Decompose the time }
        if localtime_r(LTime, LComp) <> @LComp then
          Exit;
      until LComp.tm_gmtoff <> LLastOffset;

      { Generate the time zone abbreviation }
      strftime(MarshaledAString(LChars), Length(LChars), '%Z', LComp); // DO NOT LOCALIZE
      if LIsStandard then
      begin
        { We were in the standard period }
        Result.FStartOfDST := IncSecond(FileDateToDateTime(LTime), LLastOffset - LComp.tm_gmtoff);
        Result.FBias := LLastOffset;
        Result.FDSTName := Trim(TEncoding.UTF8.GetString(LChars));//<----- Korrektur   Alter Code----> //Result.FDSTName := Utf8ToString(LChars);
      end else
      begin
        { We were in the DST period }
        Result.FEndOfDST := IncSecond(FileDateToDateTime(LTime), LLastOffset - LComp.tm_gmtoff);
        Result.FBiasWithDST := LLastOffset;
        Result.FName := Trim(TEncoding.UTF8.GetString(LChars));//<----- Korrektur   Alter Code----> //Result.FName := Utf8ToString(LChars);
      end;

      { Set the last offset }
      LLastOffset := LComp.tm_gmtoff;
      LIsStandard := not LIsStandard;

      { Die if this is the second cycle }
      if LIsSecondCycle then
        Exit
      else
        LIsSecondCycle := true;
    end;
  end;
end;
{$ENDIF}

QuickAndDirty 21. Jul 2020 08:04

AW: (Android) Fehler in DateUtils behoben // TTimezone.Local.ID // Ich bitte um Prüfu
 
Sorry, aber gibts grundsätzlich etwas gegen diese Lösung einzuwenden?
Ich will nicht wie ein Idiot dastehen wenn ich das bei QC posten sollte.

Rollo62 21. Jul 2020 10:25

AW: (Android) Fehler in DateUtils behoben // TTimezone.Local.ID // Ich bitte um Prüfu
 
Man kann das nur Aufwendig mit den Lokalisierungen Testen.

Du schreibst ja dass das Problem ursächlich beim UTF8 konvertieren liegt,
gibt es dafür vielleicht einen kleinen Testcode der den Fehler, ohne das ganze Android/Language Gewusel ?

Ich verstehe Dich so, dass
Delphi-Quellcode:
Utf8ToString(LChars) // mit LChars: TBytes;
aus z.B. 'CET' nur 'ET' macht, und das erste Zeichen verschluckt.

Es könnte sein das UTF8ToString wirklich zwingend ein BOM für UTF8 benötigt,
und dadurch das erste Zeichen verschluckt.
Kann ich mir aber eigentlich nicht wirklich vorstellen, das müsste ja an zig. Stellen auftauchen.

Die Frage wäre was in LChars wirkliich drinsteht, ist das ein ANSI-String ?
https://android.developreference.com...+in+Rad+Studio

Ein Mini-Beispiel dazu wäre auf jeden Fall sinnvoll.

himitsu 21. Jul 2020 10:37

AW: (Android) Fehler in DateUtils behoben // TTimezone.Local.ID // Ich bitte um Prüfu
 
Zitat:

Delphi-Quellcode:
Result.FName := Trim(TEncoding.UTF8.GetString(LChars));
Result.FName := Utf8ToString(LChars);

OK, abgesehn vom TRIM sollte, UTF8.GetString und Utf8ToString doch eigentlich gleiche Ergebnisse liefern,
und wenn sie das nicht tun, dann sollte man besser auch gleich mit prüfen was dort schief läuft.


Ansonsten:

Warum gibt die Funktion einen Pointer zurück, anstatt des Records?
Gerade hier ist das eine Liebslingsstelle für Speicherlecks und dazumal es absolot sinnlos ist, weil immer was zurückgegeben wird im Delphi (XE) ist/war das auch noch ein Record.

Und an ein paar gewissen Stellen würde ich noch eine Bereichsprüfung einfügen.
Zitat:

Delphi-Quellcode:
ExpDayOfWeek := CReDoW[ADoW];

entweder die
Delphi-Quellcode:
{$RANGECHECKS ON}
aktiv,
oder mit Fehlermelduing
Delphi-Quellcode:
if ADoW > 6 then raise ...

oder zumindestens wildlaufende Speicherzugriffe abfangen
Delphi-Quellcode:
ExpDayOfWeek := CReDoW[ADoW mod 7];
, was hier möglich ist, also einfach den Überstand in die nachfolgenden Wochen verschieben.

Und sonst erstmal noch nicht weiter gesucht. (war so das "Schlimmste", was gleich auf den ersten Blick brutal ins Auge stach)

QuickAndDirty 21. Jul 2020 14:15

AW: (Android) Fehler in DateUtils behoben // TTimezone.Local.ID // Ich bitte um Prüfu
 
@himitsu
Ich habe wirklich nur 3 Zeilen in dem Listing verändert. "Korrektur" steht neben dran. Der rest ist original code aus dateutils.pas.
Ich habe quasi in der Funktion aus der Dateutils.pas einfach 3 stellen gepatcht.
Ich wollte möglichst wenig EmbarcaderoCode anfassen um mein Problem zu lösen.

@Rollo62
Ich habe jetzt mal die Funktion angesehen die den Fehler macht.
Liegst in der "System.pas"
Leider bin ich nicht gut bewandert in "codierung". Ich bin darauf angewiesen das die Convertierungsmethoden funktionieren.
UTF8ToUnicode gibt es in etlichen überladenen methoden...


unit System.pas
Delphi-Quellcode:
function UTF8ToString(const S: array of Byte): string; overload;
var
  Dest: array[0..511] of Char;
begin
  SetString(Result, Dest, UTF8ToUnicode(Dest, Length(Dest), _PAnsiChr(@S[1]), S[0])-1);
end;

{$IFDEF USE_LIBICU}
{$IFDEF LINUX}
function Utf8ToUnicodeICU(Dest: PWideChar; MaxDestChars: Cardinal; Source: _PAnsiChr; SourceBytes: Cardinal): Cardinal;
{$ELSE !LINUX}
function Utf8ToUnicode(Dest: PWideChar; MaxDestChars: Cardinal; Source: _PAnsiChr; SourceBytes: Cardinal): Cardinal;
{$ENDIF LINUX}
var
  DestLen: Int32;
  ErrorConv: UErrorCode;
begin
  Result := 0;
  if Source = nil then Exit;
  ErrorConv := 0;
  DestLen := 0;
  u_strFromUTF8(PUChar(Dest), MaxDestChars, DestLen, MarshaledAString(Source), SourceBytes, ErrorConv);
  Result := DestLen;
  if Dest <> nil then
  begin
    if (Result > 0) and (Result <= MaxDestChars) then
    begin
      if Result = MaxDestChars then
      begin
        if (Result > 1) and (Word(Dest[Result - 1]) >= $DC00) and (Word(Dest[Result - 1]) <= $DFFF) then
          Dec(Result);
      end else
        Inc(Result);
      Dest[Result - 1] := #0;
    end;
  end;
end;

Edit:
!!!!!!!!!!!!!!HOLY COW!!!!!!!!!!
Delphi-Quellcode:
function UTF8ToString(const S: array of Byte): string; overload;
var
  Dest: array[0..511] of Char;
begin
  SetString(Result, Dest, UTF8ToUnicode(Dest, Length(Dest), _PAnsiChr(@S[1]), S[0])-1);     //   _PAnsiChr(@S[1]) ist "ET" _PAnsiChr(@S[0]) müsste dann "CET" sein???
end;

QuickAndDirty 21. Jul 2020 14:48

AW: (Android) Fehler in DateUtils behoben // TTimezone.Local.ID // Ich bitte um Prüfu
 
OK, Was nun???

himitsu 21. Jul 2020 15:39

AW: (Android) Fehler in DateUtils behoben // TTimezone.Local.ID // Ich bitte um Prüfu
 
Nun: Bugmeldung im Quality-Portal

Delphi-Quellcode:
S[Low(string)]
statt
Delphi-Quellcode:
S[1]

oder gleich den Mist mit dem @ lassen, also
Delphi-Quellcode:
PAnsiChr(S)
statt
Delphi-Quellcode:
PAnsiChr(@S[1])
.

Grund: $ZeroBasedStrings sind im NextGen (Android/iOS) aktiv.
http://docwiki.embarcadero.com/RADSt...rings_(Delphi)

Rollo62 21. Jul 2020 15:56

AW: (Android) Fehler in DateUtils behoben // TTimezone.Local.ID // Ich bitte um Prüfu
 
Nur mal gerade in den Delphi-Sourcen gesucht, es gibt allein ca. 34-40 Units die das benutzen.
Das würde ja an allen möglichen Stellen abrauchen, kann ich gar nicht glauben :shock:
Ganz zu schweigen von externen Libraries und Code.
Macht Emba keine Unit-Tests ?

Was ist jetzt besser, nur bei DateUtils zu fixen oder direkt das Übel an der Wurzel ? Gute Frage.

Ich muss wohl mal bei mir checken ob und wo ich das nutze.

himitsu 21. Jul 2020 16:07

AW: (Android) Fehler in DateUtils behoben // TTimezone.Local.ID // Ich bitte um Prüfu
 
Besser ist es immer das grundlegende Problem, anstatt nur die Symptome zu beheben.
Rein funktionell geht es auch den "Fehler" an beiden Stellen zu beheben, wobei TEncoding da einen größeren Overhead hat.


Wenn du über den String-Helper gehst, dann ist es dort auch überall 0-basiered und in jeder Platform einheitlich.
S.Chars(0) = S[1] {im Windows} ... abgesehn von dem nutzlosen Funktionsaufruf bei .Chars .

Auch beim Copy-Befehl seh ich zu oft, dass es bei 0 beginnt (
Delphi-Quellcode:
Copy(S, 0, ...)
), was "oft" funktioniert, da es nach unten abgefangen wird, aber mit höheren Indize wird dann natürlich auch falsch zugegriffen, wenn der Entwickler das immer falsch macht.

samso 21. Jul 2020 17:07

AW: (Android) Fehler in DateUtils behoben // TTimezone.Local.ID // Ich bitte um Prüfu
 
Zitat:

Zitat von QuickAndDirty (Beitrag 1470004)

Delphi-Quellcode:
function UTF8ToString(const S: array of Byte): string; overload;
var
  Dest: array[0..511] of Char;
begin
  SetString(Result, Dest, UTF8ToUnicode(Dest, Length(Dest), _PAnsiChr(@S[1]), S[0])-1);     //   _PAnsiChr(@S[1]) ist "ET" _PAnsiChr(@S[0]) müsste dann "CET" sein???
end;



Diese Funktion ist anscheinend von ShortString nach "array of bytes" adaptiert worden. Man beachte das S[0]. Das soll ja wohl die Länge sein..

QuickAndDirty 22. Jul 2020 12:34

AW: (Android) Fehler in DateUtils behoben // TTimezone.Local.ID // Ich bitte um Prüfu
 
Zitat:

Zitat von Rollo62 (Beitrag 1470021)
Nur mal gerade in den Delphi-Sourcen gesucht, es gibt allein ca. 34-40 Units die das benutzen.
Das würde ja an allen möglichen Stellen abrauchen, kann ich gar nicht glauben :shock:
Ganz zu schweigen von externen Libraries und Code.
Macht Emba keine Unit-Tests ?

Es gibt das in vielen (5?) überladenen versionen.
Sprich vielleicht kommt bei dir nie die Array of Bytes version zum Einsatz...
Überladene namen lassen sich leider nicht wirklich toll suchen!

Zitat:

Zitat von Rollo62 (Beitrag 1470021)
Was ist jetzt besser, nur bei DateUtils zu fixen oder direkt das Übel an der Wurzel ?

Ja, eben. Was nun?

Zitat:

Zitat von Rollo62 (Beitrag 1470021)
Gute Frage.

Deine Frage war übrigens auch nicht übel. ;-)

QuickAndDirty 22. Jul 2020 12:46

AW: (Android) Fehler in DateUtils behoben // TTimezone.Local.ID // Ich bitte um Prüfu
 
Zitat:

Zitat von himitsu (Beitrag 1470017)
Nun: Bugmeldung im Quality-Portal

Delphi-Quellcode:
S[Low(string)]
statt
Delphi-Quellcode:
S[1]

oder gleich den Mist mit dem @ lassen, also
Delphi-Quellcode:
PAnsiChr(S)
statt
Delphi-Quellcode:
PAnsiChr(@S[1])
.

Grund: $ZeroBasedStrings sind im NextGen (Android/iOS) aktiv.
http://docwiki.embarcadero.com/RADSt...rings_(Delphi)

Meinst du so
Delphi-Quellcode:
function UTF8ToString(const S: array of Byte): string; overload;
var
  Dest: array[0..511] of Char;
begin
  // _PAnsiChr(@S[1]) ist "ET" _PAnsiChr(@S[0]) müsste dann "CET" sein???
  // SetString(Result, Dest, UTF8ToUnicode(Dest, Length(Dest), _PAnsiChr(@S[1]), S[0])-1);
  SetString(Result, Dest, UTF8ToUnicode(Dest, Length(Dest), PAnsiChr(S), length(S))-1);
  //
end;
und was bedeutet in
Delphi-Quellcode:
UTF8ToUnicode(a, b, c, d) -1
das "-1"
????

QuickAndDirty 22. Jul 2020 12:50

AW: (Android) Fehler in DateUtils behoben // TTimezone.Local.ID // Ich bitte um Prüfu
 
Zitat:

Zitat von samso (Beitrag 1470030)
Zitat:

Zitat von QuickAndDirty (Beitrag 1470004)

Delphi-Quellcode:
function UTF8ToString(const S: array of Byte): string; overload;
var
  Dest: array[0..511] of Char;
begin
  SetString(Result, Dest, UTF8ToUnicode(Dest, Length(Dest), _PAnsiChr(@S[1]), S[0])-1);     //   _PAnsiChr(@S[1]) ist "ET" _PAnsiChr(@S[0]) müsste dann "CET" sein???
end;



Diese Funktion ist anscheinend von ShortString nach "array of bytes" adaptiert worden. Man beachte das S[0]. Das soll ja wohl die Länge sein..

Das denke ich auch. Und die Funkionen ein paar Zeilen darüber muten auch alle wie ein Copy-Pasta aus einer Shortstring Funktion an....
Ich habe einfach nur Angst dass in System.pas zu beheben.... wegen der Abhängigkeiten... vielleicht erwartet Abhängigercode diesen Fehler und trägt dafür Sorge...

himitsu 22. Jul 2020 13:36

AW: (Android) Fehler in DateUtils behoben // TTimezone.Local.ID // Ich bitte um Prüfu
 
Zitat:

Zitat von QuickAndDirty (Beitrag 1470097)
vielleicht erwartet Abhängigercode diesen Fehler und trägt dafür Sorge...

Dann ist das ein Fehler in sich.

Diese Funktion ist definitiv falsch, also gehört sie gebugfixt.
Wenn anderer Code diesen "Fehler" erwartet und ungeprüft übernimmt, dann ist dort jemand selbst Schuld.


Wie das jetzt ganz genau am Besten gefixt werden sollte, da müsste ich auch nochmal genauer drüberschauen,
aber da man die System.pas sowieso nicht wirklich kompilieren/austauschen kann, ist es sowieso egal.
Eine alternative funktionierende Funktion mit TEncoding hast du ja und kannst (erstmal) was Anderes benutzen.

Ansonsten muß dieser Fehler (egal ob mit oder ohne Lösungsvorschlag) als "dringend" im Quality-Portal gemeldet werden.
quality.embarcadero.com
IMHO sollte Emba das auch mindestens für 10.3 und 10.4 schnellstmöglich als Patch rausgeben, denn ich würde das schon als "sehr schweren" Fehler betrachten, da diese Funktionen auch von Delphi selbst öfters benutzt werden.

himitsu 22. Jul 2020 13:44

AW: (Android) Fehler in DateUtils behoben // TTimezone.Local.ID // Ich bitte um Prüfu
 
[edit]
please vote

https://quality.embarcadero.com/browse/RSP-10568
https://quality.embarcadero.com/browse/RSP-10581

Also eigentlich hätte man das schon längst beheben können. :wall:

QuickAndDirty 22. Jul 2020 14:32

AW: (Android) Fehler in DateUtils behoben // TTimezone.Local.ID // Ich bitte um Prüfu
 
OK Ich werde dann mal meinem Chef sagen das er das upvoten soll...
Wie heist noch mal der user hier, der auch bei Embarcadero leute kennt?
Ist WANG WANG irgend eine wichtige Person? Weil er stellt sich in den threads echt etwas dumm an.
Warum ist RSP-10568 closed?

bis jetzt nur 9 votes für RSP-10581....

himitsu 22. Jul 2020 16:49

AW: (Android) Fehler in DateUtils behoben // TTimezone.Local.ID // Ich bitte um Prüfu
 
Da steht es sei ein Dupplicat, bei sowas bleibt nur ein Ticket offen (meistens das Erste, oder das Bessere) und die Anderen werden als Doppelt markiert und geschlossen.
Blöder Weise kann ich diesmal aber nicht sehen welches das andere Dupplikat ist (das Offene) ... mir war so dass das sonst ebenfalls im Kopf stünde,
aber es könnte sein, dass 10581 das aktuelle Ticket ist.

MEissing und er arbeitet dort sogar, im deutschen Support :wink:

Wang Wang: keine Ahnung, kenn ihn nicht (dachte erst er seit einer der Entwickler, aber wohl doch nicht)


Die Meisten entwickeln für Windows ... dort fällt der Fehler scheinbar nicht auf
und zu Viele schauen leider garnicht erst in QC, bzw. ins neue Quality-Portal.

TurboMagic 22. Jul 2020 19:58

AW: (Android) Fehler in DateUtils behoben // TTimezone.Local.ID // Ich bitte um Prüfu
 
Ich glaube auch, das Wang Wang Anwender ist.

QuickAndDirty 23. Dez 2020 15:11

AW: (Android) Fehler in DateUtils behoben // TTimezone.Local.ID // Ich bitte um Prüfu
 
Der Fehler ist in Delphi 10.41 samt aller Patches immernoch in der System.pas....
Und auch die System.DateUtils.Pas benutzt immernoch UTF8ToString für Bytearrays....
Warum gucken die nicht in den Fehlerbericht. Im Prinzip ist die Lösung ja fast mitgeliefert.

himitsu 23. Dez 2020 15:31

AW: (Android) Fehler in DateUtils behoben // TTimezone.Local.ID // Ich bitte um Prüfu
 
Zitat:

Zitat von QuickAndDirty (Beitrag 1479777)
Im Prinzip ist die Lösung ja fast mitgeliefert.

Das ist zu einfach.
Bei sowas mußt du erst 10 Jahre warten. (vielleicht muß man ja bei Fremdcode vorher die NSA fragen, damit die darin nach bösem russischen Hackercode gucken können)

Vor etwa 10 Jahren hatte ich einen QC erstellt, wo es um ein "Event" für Records geht (erstellen, kopieren/zuweisen und freigeben)
und hatte einen Lösungsvorschlag gleich mitgeliefert (etwa 5 Zeilen Code und zwei/drei Felder in der RTTI des Records).
Jetzt wurde sowas (bissl anders) als nagelneues Feature verkauft ... nennt sich Managed Records. :stupid:

venice2 23. Dez 2020 15:44

AW: (Android) Fehler in DateUtils behoben // TTimezone.Local.ID // Ich bitte um Prüfu
 
Zitat:

Jetzt wurde sowas (bissl anders) als nagelneues Feature verkauft ... nennt sich Managed Records.
Allein an deinen Beiträgen sieht man schon das du zur Elite MVP gehörst.
Manchmal wird das können und wissen einfach nicht genug gewürdigt.

Ohne deines professionellen Wissens wären so einige hier Aufgeschmissen.
Danke dafür.

Traurig genug wenn die Arbeit anderer als eigene Ausgegeben wird.

himitsu 23. Dez 2020 15:59

AW: (Android) Fehler in DateUtils behoben // TTimezone.Local.ID // Ich bitte um Prüfu
 
Ach, die grundsätzliche Idee, das es sowas geben sollte, hatten auch paar Andere. :)
Und letztendlich hatten die es dann auch auf einem anderen Wege implementiert. (gibt ja mehrer möglche Lösungen)

Zum Glück hatten die ihre erste Lösung gleich nochmal überarbeitet.
Hab gehört das war in 10.3 schon drin, aber sooo langsam/schlecht, dass man es nicht veröffentlicht hatte. :stupid:



Das Einzige was wir effektiv machen können.
Massig QCs erstellen und noch mehr dafür zu Voten.

venice2 23. Dez 2020 16:04

AW: (Android) Fehler in DateUtils behoben // TTimezone.Local.ID // Ich bitte um Prüfu
 
Zitat:

Zitat von himitsu (Beitrag 1479780)
Ach, die grundsätzliche Idee, das es sowas geben sollte, hatten auch paar Andere. :)
Und letztendlich hatten die es dann auch auf einem anderen Wege implementiert. (gibt ja mehrer möglche Lösungen)

Zum Glück hatten die ihre erste Lösung gleich nochmal überarbeitet.
Hab gehört das war in 10.3 schon drin, aber sooo langsam/schlecht, dass man es nicht veröffentlicht hatte. :stupid:



Das Einzige was wir effektiv machen können.
Massig QCs erstellen und noch mehr dafür zu Voten.

Ahh jo wollte nur mal danke sagen das hatte sich gerade angeboten.. :)

TurboMagic 24. Dez 2020 10:15

AW: (Android) Fehler in DateUtils behoben // TTimezone.Local.ID // Ich bitte um Prüfu
 
Hallo,

1. nur weil ein Bugreport erfasst ist, kann er oft leider nicht gleich bearbeitet werden.
EMBT hat auch gewisse Pläne was wann angegangen wird (Priorisierung)

2. nur weil ein Bugreport einen Lösungsansatz enthält heißt das nicht, dass das unbedingt
der richtige sein muss. Meist gibt's noch mehr zu beachten.

3. die haben Unit Tests, nur vermutlich nicht genügend und m.W. je nach Arbeitsgebiet auch
eine unterschiedlich hohe Testabdeckung

4. Nimm doch am 10.4.2 Feldtest teil. Da ist meist ein direkterter und effizienterer
Austausch mit EMBT's Angestellten möglich und manchmal können da Bugs dann sogar zeitnah
gefixt werden, trotz Zeitplan.

Ja, auch ich höätte gerne weniger Bugs im Produkt, nur kann man halt realistisch pro
Zeiteinheit nur eine begrenzte Anzahl an Dingen umsetzen und unterschiedliche Kunden wollen
auch meist sehr unterschiedliche Bugfixes und Features umgesetzt haben und jeder denkt, dass
seine die wichtigsten wären...

Grüße und frohe Weihnachten
TurboMagic

Rollo62 24. Dez 2020 17:59

AW: (Android) Fehler in DateUtils behoben // TTimezone.Local.ID // Ich bitte um Prüfu
 
Zu den Unit Tests würde mich auch mal interessieren ob es irgendwo eine große Sammlung für alle System und anderen Delphi Units gibt ?
Es hat wahrscheinlich jeder so seine eigene Testabdeckung, aber es würde doch Sinn machen mal einen großen MegaDelphiTest zu haben, insbesondere bei neuen Versionen.
Gibt's da eventuell was von Github ?


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:14 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