Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Konvertierung UnixTimeStamp nacht TDateTime und zurück (https://www.delphipraxis.net/196625-konvertierung-unixtimestamp-nacht-tdatetime-und-zurueck.html)

Ghostwalker 5. Jun 2018 03:58

Konvertierung UnixTimeStamp nacht TDateTime und zurück
 
Moinmoin,

im Rahmen eines Projektes brauch ich die Umrechnung von TDatetime-Werten nach UnixTimeStamp und zurück. Das ganze aber manuell ohne Dateutils. Da die Funktionen aus der Codelib Hier, nicht so wirklich funktionieren (erstens wird von der Deutschen Zeitzone ausgegangen, 2 wird der Zeitteil nicht wirklich korrekt berechnet), hab ich mich dazu entschlossen, das ganze selbst um zusetzen.

Die Umrechnung eines TDatetime-Wertes zu einem Unixtimestamp funktioniert auch schon:
Delphi-Quellcode:
const
  cSecPerDay = 86400;
  cMSecPerDay = 86400000;
  cDelphiEpoche = -2209161600; //30.12.1899 als UTS

function DateTimeToUnixtimestamp(const value:TDateTime):Int64;
var
  TimePart : extended;
  Zeit : int64;
  datum: int64;

begin
  zeit := Trunc(Abs(Frac(value))*cSecPerDay); //Zeitanteil in Sekunden
  timepart := frac(Abs(Frac(value))*cMSecPerDay); //Millisekunden
  datum := trunc(int(value)*cSecPerDay); //Anzahl der Tage mit Bezug Delphi-Epoche in Sekunden
  result := cDelphiEpoche+(datum+zeit);
  if (timepart > 0.5) then //Korrektur bei 500+ Millisekunden
    inc(result);
end;
Leider will die Umkehrfunktion (also von Unixtimestamp nach TDatetime) nicht so wirklich funktionieren.

Delphi-Quellcode:
function UnixTimeStampToDateTime(const value:int64):TDateTime;
var
  datum    : int64;
  base,rest    : int64;
  zeit,timepart      : Extended;

  base := cDelphiEpoche - value;
  datum := base DIV cSecPerDay;
  rest := base MOD cSecPerDay;
  timepart := cMSecPerDay/ABS(rest);
  zeit := cSecPerDay/Abs(rest);
  if (Frac(abs(Timepart))>0.5) then
    zeit := cSecPerDay/(base - (datum*cSecPerday))+1;
  result := datum+zeit;
end;
Ein Unterschied von 1 sek (+/-) wär ok, da ein Unixtimestamp keine Millisekunden berücksichtigt. Leider bekomme ich aber Unterschieder von teilweise mehreren Tagen.

Kann mir da jemand auf die Sprünge helfen ?


Anmerkung: Das ganze sollte sowohl mit positiven als auch negativen Werten klarkommen.

samso 5. Jun 2018 06:53

AW: Konvertierung UnixTimeStamp nacht TDateTime und zurück
 
Die Zeitzone würde ich gesondert behandeln. D.h. ich würde den Datetimewert vor der Konvertierung in UTC umrechnen und dann in die Unixtimestamp umrechnen. Im umgekehrten Fall würde ich den berechneten Datetimewert wieder in lokale Zeit umrechnen, falls das erforderlich sein sollte. Hier mein Vorschlag für die Umrechnung von UTC-Datetimewerte in die Unixtimestamp und zurück (nur grob mit einigen Testdaten von https://www.freeformatter.com/epoch-...converter.html getestet):

Delphi-Quellcode:
uses
  System.SysUtils;
(*
{ Days between TDateTime basis (12/31/1899) and Unix time_t basis (1/1/1970) }

  UnixDateDelta = 25569;
*)

function UnixTimeToDatetime(UnixTime: Int64): TDatetime;
begin
  Result := UnixTime/SecsPerDay + UnixDateDelta;
end;

function DatetimeToUnixTime(Datetime: TDatetime): Int64;
var
  t: TDatetime;
begin
  t := Datetime - UnixDateDelta;
  if t>=0
  then
    Result := trunc(t*SecsPerDay + 0.5)
  else
    Result := trunc(t*SecsPerDay - 0.5);
end;

KodeZwerg 5. Jun 2018 07:29

AW: Konvertierung UnixTimeStamp nacht TDateTime und zurück
 
Warum nicht die Funktionen aus DateUtils.pas verwenden?

Delphi-Quellcode:
uses nichts;

const
  UnixDateDelta = 25569;
  SecsPerDay   = 86400;


function DateTimeToUnix(const AValue: TDateTime): Int64;
begin
  Result := Round((AValue - UnixDateDelta) * SecsPerDay);
end;

function UnixToDateTime(const AValue: Int64): TDateTime;
begin
  Result := AValue / SecsPerDay + UnixDateDelta;
end;

Ghostwalker 5. Jun 2018 07:47

AW: Konvertierung UnixTimeStamp nacht TDateTime und zurück
 
@samso

Nah drann.

Bei den (Test)-Daten hauts nicht hin:

So, 23.08.1733 18:33:44
-60759,7734259259
-7458672376

Bei DateTimeToUnix fehlen 2 Sekunden. Bei UnixToDateTime mehr als ein Tag. :)

@KodeZwerk
Das ganze soll möglichst unabhängig von anderen (auch Delphi-Eigenen) Units laufen.

btw leided deine Variante unter dem gleichen Problem wie Samso's

KodeZwerg 5. Jun 2018 07:48

AW: Konvertierung UnixTimeStamp nacht TDateTime und zurück
 
Zitat:

Zitat von KodeZwerg (Beitrag 1403909)
Delphi-Quellcode:
uses nichts;

Wieviel mehr kann man denn unabhängig sein? Nja egal, bin raus.

Ghostwalker 5. Jun 2018 08:15

AW: Konvertierung UnixTimeStamp nacht TDateTime und zurück
 
@KodeZwerg
Da ich die Starter verwende hab ich keine .pas zu den Delphiegenen Units :)

Lustig ist nur, das die von dir gepostet variante bei oben genannten Datum das gleiche fehlerhafte
Ergebnis liefert.

Die orginal Funktion dagegen haut hin.

So wie es aussieht hackt es bei Daten vor dem 30.12.1899 00:00:00 (also der "Delphi-Epoche")

KodeZwerg 5. Jun 2018 08:20

AW: Konvertierung UnixTimeStamp nacht TDateTime und zurück
 
Wenn man sich die SysUtils.pas anschaut, vielleicht ist das von Bedeutung für Dein Problem.
Delphi-Quellcode:
{ Days between 1/1/0001 and 12/31/1899 }

  DateDelta = 693594;

{ Days between TDateTime basis (12/31/1899) and Unix time_t basis (1/1/1970) }

  UnixDateDelta = 25569;

KodeZwerg 5. Jun 2018 08:22

AW: Konvertierung UnixTimeStamp nacht TDateTime und zurück
 
Zitat:

Zitat von Ghostwalker (Beitrag 1403914)
Da ich die Starter verwende hab ich keine .pas zu den Delphiegenen Units

Was ich oben schrieb war/ist Original Code von DateUtils.pas aus Delphi 2009.

samso 5. Jun 2018 08:27

AW: Konvertierung UnixTimeStamp nacht TDateTime und zurück
 
Ja, das 1899-Problem habe ich nun auch erkannt. Das sollte schon mal besser sein:
Delphi-Quellcode:
function DatetimeToUnixTime(Datetime: TDatetime): Int64;
var
  t: TDatetime;
begin
  if Datetime<0
  then
    t := trunc(Datetime) - frac(Datetime) - UnixDateDelta
  else
    t := Datetime - UnixDateDelta;
  if t>0
  then
    Result := trunc(t*SecsPerDay + 0.5)
  else
    Result := trunc(t*SecsPerDay - 0.5);
end;
Für DateTimeToUnix habe ich noch keine kompakte Lösung.

Ghostwalker 5. Jun 2018 08:57

AW: Konvertierung UnixTimeStamp nacht TDateTime und zurück
 
Naja...DateTimeToUnix tut ja so:

Delphi-Quellcode:
var
  Zeit : int64;
  datum: int64;

begin
  zeit := Trunc((Abs(Frac(value))*cSecPerDay)+0.5); //Zeitanteil in Sekunden
  datum := trunc(int(value)*cSecPerDay); //Anzahl der Tage mit Bezug Delphi-Epoche in Sekunden
  result.fvalue := cDelphiEpocheUT+(datum+zeit);
end;
auch bei Daten vor 31.12.1899.

Nur die UnixTimeStamp nach TDateTime leidet hier unter dem 1899'er problem.

Ich probier grad, ob ich mit der Info von KodeZwerk hinsichtlich DateDelta was rauskrieg.

TiGü 5. Jun 2018 10:18

AW: Konvertierung UnixTimeStamp nacht TDateTime und zurück
 
Ich verstehe das rumfummeln nicht.
Du hast zwar nicht die Quelltexte in der Starter, kannst doch aber trotzdem auf die Funktionen von System.DateUtils zugreifen?
Die Umwandlung davon sind doch richtig und korrekt?
Dieser NonRTL-Ansatz ist doch Käse.
Da müsstest du doch konsequenterweise auch auf System.Trunc verzichten.

Delphi-Quellcode:
program Project5;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  System.DateUtils;

procedure Main;
var
  DateTimeStr: string;
  TimeStr: string;
  MyTime: TTime;
  MyDate: TDate;
  MyDateTime: TDateTime;
  UnixTimeStamp: Int64;
begin
  DateTimeStr := '23.08.1733 18:33:44';
  Writeln('Testdatum: ', DateTimeStr);

  MyDateTime := StrToDateTime(DateTimeStr);
  Writeln('Umwandung in TDateTime: ', Double(MyDateTime).ToString);

  UnixTimeStamp := System.DateUtils.DateTimeToUnix(MyDateTime);
  Writeln('UnixTimeStamp: ', UnixTimeStamp.ToString);

  MyDateTime := System.DateUtils.UnixToDateTime(UnixTimeStamp);
  DateTimeStr := FormatDateTime('DD.MM.YYYY HH:MM:SS', MyDateTime);
  Writeln('Rückwandlung von Timestamp in TDateTime und in String: ', DateTimeStr);
  Trunc
end;


begin
  try
    Main;
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Alter Mann 5. Jun 2018 13:15

AW: Konvertierung UnixTimeStamp nacht TDateTime und zurück
 
@TiGU

ganz so einfach ist es nicht, wie schon in #4 vermeldet passen die Ergebnisse nicht.

Delphi-Quellcode:
program UT2;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  System.DateUtils;

const                                       <- aus DateUtils Delphi 2009
  _UnixDateDelta = 25569;
  _SecsPerDay   = 86400;

function _DateTimeToUnix(const AValue: TDateTime): Int64;
begin
  Result := Round((AValue - _UnixDateDelta) * _SecsPerDay);
end;

function _UnixToDateTime(const AValue: Int64): TDateTime;
begin
  Result := AValue / _SecsPerDay + _UnixDateDelta;
end;


procedure Main;
var
  DateTimeStr: string;
  MyDateTime: TDateTime;
  UnixTimeA,
  UnixTimeB : Int64;
begin
  DateTimeStr := '23.08.1733 18:33:44';
  Writeln('Testdatum: ', DateTimeStr);

  MyDateTime := StrToDateTime(DateTimeStr);
  Writeln('Umwandung in TDateTime: ', Double(MyDateTime).ToString);

  UnixTimeA := System.DateUtils.DateTimeToUnix(MyDateTime);
  Writeln('UnixTime(DateUtils - XE8  ): ', UnixTimeA.ToString);

  UnixTimeB := _DateTimeToUnix(MyDateTime);
  Writeln('UnixTime(DateUtils - D2009): ', UnixTimeB.ToString);

  Writeln('Rückwandlung von UnixTime in TDateTime und in String');

  Writeln('(DateUtils - XE8  ): ', FormatDateTime('DD.MM.YYYY HH:MM:SS', System.DateUtils.UnixToDateTime(UnixTimeA)));
  Writeln('(DateUtils - D2009): ', FormatDateTime('DD.MM.YYYY HH:MM:SS', _UnixToDateTime(UnixTimeA)));

end;

begin
  try
    Main;
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
also TiGU welcher Code hat Dein vertrauen?

TiGü 5. Jun 2018 13:43

AW: Konvertierung UnixTimeStamp nacht TDateTime und zurück
 
Zitat:

Zitat von Alter Mann (Beitrag 1403949)
@TiGU

ganz so einfach ist es nicht, wie schon in #4 vermeldet passen die Ergebnisse nicht.

also TiGU welcher Code hat Dein vertrauen?

Der TE hat im Profil zu stehen: Delphi 10.2 Tokyo Starter, bei mir steht Delphi 10.2 Berlin Professional und bei dir steht Delphi 10.2 Tokyo Professional...warum wird jetzt die Funktion aus dem Jahre 2008 hervorgeholt?
Das früher mal etwas nicht gestimmt hat kann ja gut sein, aber jetzt ist das doch nicht mehr relevant.

KodeZwerg 5. Jun 2018 15:17

AW: Konvertierung UnixTimeStamp nacht TDateTime und zurück
 
Mit der alten Version da habe ich Schuld, ich sah nur vom Ghostwalger den Source, startete mein D2009 und teilte den Inhalt. Tut mir leid Khostwalker und alle anderen!!

Ich habe es selber noch nicht getestet aber ich vermute für vor 1899 muss man das andere Delta nehmen (wenn Input negativ ist?).

edit
Ps: Die Konstanten stammen bei mir aus SysUtils.pas nicht aus DateUtils.pas.

edit #2
Also die Tokyo Version bekomme ich nicht so einfach raus kopiert, die greift auf viele Sub-Funktionen zurück aber wie man am Alter Mann Beispiel sehen kann, funktioniert der "XE8-Way" (auch in Starter enthalten) weitaus zuverlässiger ohne weiteres zu tun oder herum rechnen und biegen.

Ghostwalker 5. Jun 2018 15:53

AW: Konvertierung UnixTimeStamp nacht TDateTime und zurück
 
@TiGu

Ob der verzicht nun sinnvoll ist oder nicht tut nix zur Frage und dem Problem :)

Die Lösung, die KodeZwerg gepostet hat, ist auch die, die an den meisten Stellen im Internet rumgeistert (vgl. CodeLib, SwissDelphiCenter.ch u.v.m), aber genau das Problem mit Daten vor 1899 hat.

Wie steht es den in den neueren Versionen drinn ?

KodeZwerg 5. Jun 2018 16:36

AW: Konvertierung UnixTimeStamp nacht TDateTime und zurück
 
mein Beitrag war falsch.

samso 5. Jun 2018 18:53

AW: Konvertierung UnixTimeStamp nacht TDateTime und zurück
 
So, ich melde mich wieder zurück, mit folgendem Vorschlag:
Delphi-Quellcode:
function UnixTimeToDatetime(UnixTime: Int64): TDatetime;
var
  t: Double;
begin
  t := UnixTime/SecsPerDay + UnixDateDelta;
  if t>=0
  then
    Result := t
  else
    Result := trunc(t) - frac(t) - 2;
end;

KodeZwerg 5. Jun 2018 19:42

AW: Konvertierung UnixTimeStamp nacht TDateTime und zurück
 
Liste der Anhänge anzeigen (Anzahl: 1)
Wie man hier sehen kann, funktionieren 3 Methoden. Anhang 49213
Tokyo per Units, D2009 per Code, Samso per Code.
Die GW Methode aus Post #1 bei Rückverwandlung klappt etwas nicht.

Der Fehler mit D2009 Rückverwandlung entstand weil UnixTimeA verwendet wurde und nicht sein zugewiesener UnixTimeB.
Nun A B C D vorhanden :-)

Delphi-Quellcode:
program UT2;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  System.DateUtils;

const
  _DateDelta = 693594;
  _UnixDateDelta = 25569;
  _HoursPerDay  = 24;
  _MinsPerHour  = 60;
  _SecsPerMin   = 60;
  _MSecsPerSec  = 1000;
  _MinsPerDay   = _HoursPerDay * _MinsPerHour;
  _SecsPerDay   = _MinsPerDay * _SecsPerMin;
  _SecsPerHour  = _SecsPerMin * _MinsPerHour;
  _MSecsPerDay  = _SecsPerDay * _MSecsPerSec;
  _DelphiEpoche = -2209161600; //30.12.1899 als UTS

function _DateTimeToUnix(const AValue: TDateTime): Int64;
begin
  Result := Round((AValue - _UnixDateDelta) * _SecsPerDay);
end;

function _UnixToDateTime(const AValue: Int64): TDateTime;
begin
  Result := AValue / _SecsPerDay + _UnixDateDelta;
end;

function _UnixTimeToDatetime(UnixTime: Int64): TDatetime;
var
  t: Double;
begin
  t := UnixTime / _SecsPerDay + _UnixDateDelta;
  if t > 0
  then
    Result := t
  else
    Result := trunc(t) - frac(t) - 2;
end;

function _DateTimeToUnixTime(Datetime: TDatetime): Int64;
var
  t: TDatetime;
begin
  if Datetime < 0
  then
    t := trunc(Datetime) - frac(Datetime) - _UnixDateDelta
  else
    t := Datetime - _UnixDateDelta;
  if t>0
  then
    Result := trunc(t * _SecsPerDay + 0.5)
  else
    Result := trunc(t * _SecsPerDay - 0.5);
end;

function _DateTimeToUnixtimestamp(const value:TDateTime):Int64;
var
  TimePart : extended;
  Zeit : int64;
  datum: int64;
begin
  zeit := Trunc(Abs(Frac(value)) * _SecsPerDay); //Zeitanteil in Sekunden
  timepart := frac(Abs(Frac(value)) * _MSecsPerDay); //Millisekunden
  datum := trunc(int(value) * _SecsPerDay); //Anzahl der Tage mit Bezug Delphi-Epoche in Sekunden
  result := _DelphiEpoche + (datum+zeit);
  if (timepart > 0.5) then //Korrektur bei 500+ Millisekunden
    inc(result);
end;

function _UnixTimeStampToDateTime(const value:int64):TDateTime;
var
  datum : int64;
  base,rest : int64;
  zeit,timepart : Extended;
begin
  base := _DelphiEpoche - value;
  datum := base DIV _SecsPerDay;
  rest := base MOD _SecsPerDay;
  timepart := _MSecsPerDay/ABS(rest);
  zeit := _SecsPerDay/Abs(rest);
  if (Frac(abs(Timepart))>0.5) then
    zeit := _SecsPerDay/(base - (datum*_SecsPerday))+1;
  result := datum+zeit;
end;

procedure Main;
var
  DateTimeStr: string;
  MyDateTime: TDateTime;
  UnixTimeA, UnixTimeB, UnixTimeC, UnixTimeD : Int64;
begin
  DateTimeStr := '23.08.1733 18:33:44';
  Writeln('Testdatum: ', DateTimeStr);

  MyDateTime := StrToDateTime(DateTimeStr);
  Writeln('Umwandung in TDateTime: ', Double(MyDateTime).ToString);

  UnixTimeA := System.DateUtils.DateTimeToUnix(MyDateTime);
  Writeln('DateTimeToUnix (Tokyo): ', UnixTimeA.ToString);
  UnixTimeB := _DateTimeToUnix(MyDateTime);
  Writeln('DateTimeToUnix (D2009): ', UnixTimeB.ToString);
  UnixTimeC := _DateTimeToUnixTime(MyDateTime);
  Writeln('DateTimeToUnix (Samso): ', UnixTimeC.ToString);
  UnixTimeD := _DateTimeToUnixtimestamp(MyDateTime);
  Writeln('DateTimeToUnix (GWalg): ', UnixTimeD.ToString);

  Writeln('Rückwandlung von UnixTime in TDateTime und in String');

  Writeln('UnixToDateTime (Tokyo): ', FormatDateTime('DD.MM.YYYY HH:MM:SS', System.DateUtils.UnixToDateTime(UnixTimeA)));
  Writeln('UnixToDateTime (D2009): ', FormatDateTime('DD.MM.YYYY HH:MM:SS', _UnixToDateTime(UnixTimeB)));
  Writeln('UnixToDateTime (Samso): ', FormatDateTime('DD.MM.YYYY HH:MM:SS', _UnixTimeToDateTime(UnixTimeC)));
  Writeln('UnixToDateTime (GWalg): ', FormatDateTime('DD.MM.YYYY HH:MM:SS', _UnixTimeStampToDateTime(UnixTimeD)));

end;

begin
  try
    Main;
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
edit
Fazit: Für volle Unit Unabhängigkeit und sehr hohe Kompatibilität Benutze Samsos Umsetzung.
D2009 nur von und mit D2009 Code, dann klappt der auch ganz gut.

KodeZwerg 5. Jun 2018 21:34

AW: Konvertierung UnixTimeStamp nacht TDateTime und zurück
 
gelöscht - meine Korrektur für Deine Rückverwandlung war mehr als falsch. Sorry, ich versuchs nochmal.

Ghostwalker 6. Jun 2018 05:20

AW: Konvertierung UnixTimeStamp nacht TDateTime und zurück
 
Vielen Dank für eure Mühen :)

Samso's Variante funktioniert perfekt :)

KodeZwerg 6. Jun 2018 11:46

AW: Konvertierung UnixTimeStamp nacht TDateTime und zurück
 
Deine Rückverwandlung konnte ich halbwegs Reparieren aber wenn ich Härtetest durchführe, je näher man dem Datum "31.12.1899 23:59:59" kommt umso ungenauer wird es mit dem "DelphiEpoche"-Stil, da spielen die Werte verrückt da Du den "30.12.1899" gewählt hast, die Zeit geht irgendwie auch immer verloren, da habe ich auch keine Lösung für gefunden.

KodeZwerg 6. Jun 2018 14:36

AW: Konvertierung UnixTimeStamp nacht TDateTime und zurück
 
Für D2009 habe ich einen mini-Hotfix
Delphi-Quellcode:
function _DateTimeToUnix(const AValue: TDateTime): Int64;
begin
  if AValue >= 0 then
    Result := Round((AValue - _UnixDateDelta) * _SecsPerDay)
  else
    Result := 172798 + Round((AValue - _UnixDateDelta) * _SecsPerDay);
end;

function _UnixToDateTime(const AValue: Int64): TDateTime;
begin
  if AValue >= 0 then
    Result := AValue / _SecsPerDay + _UnixDateDelta
  else
    Result := (AValue - 172798) / _SecsPerDay + _UnixDateDelta;
end;
Es ist allerdings anzumerken, _UnixToDateTime() hat noch einen Fehler!!
Die Sekunden-Angabe schwankt was zum Beispiel bei 23:59:59 auch den nächsten Tag zur Folge haben könnte !!
Oder anders herum kann auch aus ein 00:00:00 der vorige Tag werden !! Je nachdem wohin die MSecs schwanken +0.5 oder -0.5.
Ich hoffe es ist Verständlich was ich meine.

samso 7. Jun 2018 06:10

AW: Konvertierung UnixTimeStamp nacht TDateTime und zurück
 
Zitat:

Zitat von Ghostwalker (Beitrag 1403994)
Samso's Variante funktioniert perfekt :)

Leider nicht. Bei der Uhrzeit 00:00:00 gab es Probleme, die ich so gelöst habe:

Delphi-Quellcode:
uses
  SysUtils, Math;

function UnixTimeToDatetime(UnixTime: Int64): TDatetime;
var
  d, t: Double;
begin
  d := UnixTime/SecsPerDay + UnixDateDelta;
  t := frac(d);
  if (d>=0) or IsZero(t)
  then
    Result := d
  else
    Result := trunc(d) - t - 2;
end;

Ghostwalker 7. Jun 2018 07:13

AW: Konvertierung UnixTimeStamp nacht TDateTime und zurück
 
@Samso

Jup, aber nur bei Daten vor oder gleich dem 30.12.1899 .

Habs nochmal korregiert, lt. meinen Unit-Tests funktionierts so:

Delphi-Quellcode:
function UnixToDateTime(const value:int64):TDateTime
var
  d, t: Extended;
begin
  d := value/cSecPerDay + cUnixEpocheDT;
  t := frac(d);
  if (value <= cDelphiEpocheUT) then
  begin
    if (d>=0) or IsZero(t)
    then
      Result := d
    else
      Result := trunc(d) - t - 2;
  end
  else
    result := d;
end;

samso 7. Jun 2018 07:46

AW: Konvertierung UnixTimeStamp nacht TDateTime und zurück
 
Die Fälle in denen das Datum >= 30.12.1899 ist, wird bereits durch die Abfrage "d>=0" behandelt und führt immer in den Zweig "Result := d". Deshalb ist die Abfrage value <= cDelphiEpocheUT redundant.

KodeZwerg 7. Jun 2018 08:23

AW: Konvertierung UnixTimeStamp nacht TDateTime und zurück
 
Mein D2009 Hotfix ist auch nicht das gelbe vom Ei.
Meine Problem Daten sind diese hier 29-31.12.1899 00:00:00/23:59:59 und hört hier auf 31.12.1969 23:59:59.
Alles au0erhalb dieses Bereichs funktioniert mit der D2009 Methode auf Anhieb, alles was da zwischen liegt kann Probleme bereiten.

edit
Ich bastel noch ein wenig am D2009 rum, wenn ich mir aus den Werten einen TimeStamp erzeuge kann ich sehr einfach das lösen was D2009 noch falsch macht.
Für alles zwischen 01.01.1900 00:00:00 und 01.01.1970 00:00:00 muss man einen Tag und 2 Sekunden dazu addieren.
Probleme habe ich noch wenn man exakt 31.12.1899 bzw 31.12.1969 verwendet, aber das bekomme ich auch noch gefixt.
Am ToUnix muss ich auch nochmal ran, der Interpretiert auch noch nicht alles korrekt was dann logischerweise zu einem falschen Ergebnis führt, also alles mehr oder minder leicht zu korrigieren wenn man genug Zeit investiert um alle möglichen Datums angaben durchzutesten :-)

Ghostwalker 7. Jun 2018 11:50

AW: Konvertierung UnixTimeStamp nacht TDateTime und zurück
 
@Samso

Jup..hast recht.

Damit funktionieren jetzt beide Varianten (Unix->TDateTime und TDateTime->Unix).


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