Delphi-PRAXiS
Seite 2 von 3     12 3      

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)

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 :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:42 Uhr.
Seite 2 von 3     12 3      

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