Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Wie Delphi TDateTime zu c++ Datetime Ticks konvertieren? (https://www.delphipraxis.net/192715-wie-delphi-tdatetime-zu-c-datetime-ticks-konvertieren.html)

jus 13. Mai 2017 01:12


Wie Delphi TDateTime zu c++ Datetime Ticks konvertieren?
 
Hallo,

ich muß einem Webservice ein Datetime Tick von einem Datum übergeben. In der Webservice Doku steht folgender Visual C++ Beispielcode fürs Senden an dem Webservice:
Code:
Journal(0x01, DateTime.Parse("2016-03-01T00:00").Ticks, DateTime.UtcNow.Ticks);
Die Delphifunktion ist wie folgt definiert:
Delphi-Quellcode:
Journal(const ftJournalType: Int64; const from: Int64; const to_: Int64);
Doch wie erzeugt man in Delphi Int64 Ticks?

lg,
jus

himitsu 13. Mai 2017 01:20

AW: Wie Delphi TDateTime zu c++ Datetime Ticks konvertieren?
 
Mit C++ hat das erstmal nichts zu tun.

Was ist denn ticks, bzw. was sagt im Visual C++ die Hilfe dazu?

Delphi-Referenz durchsuchenDateTimeToUnix?

jus 13. Mai 2017 09:51

AW: Wie Delphi TDateTime zu c++ Datetime Ticks konvertieren?
 
@himitsu:
Delphi-Referenz durchsuchenDateTimeToUnix liefert nicht den gewünschten Wert zurück.
Ich habe hier aktuell kein Visual Studio. Aber laut MSDN DateTime.Ticks-Eigenschaft sind es 100 Nanosekunden pro Tick.

Zitat:

Ein einziger Tick stellt 100 Nanosekunden bzw. eine Zehnmillionstel Sekunde dar. Es gibt in einer Millisekunde 10.000 Ticks oder 10 Millionen Ticks pro Sekunde.

Der Wert dieser Eigenschaft stellt die Anzahl der 100-Nanosekunden-Intervalle, die seit 12:00:00 Mitternacht, 1. Januar 0001 vergangen sind (0: 00:00 UTC am 1. Januar 0001, im gregorianischen Kalender), steht DateTime.MinValue. Es umfasst nicht die Anzahl der Ticks, die auf Sekunden leap zurückzuführen sind.
Ich wundere mich nur, dass dafür keine fertige Routine/API für die Konvertierung in Delphi existiert, da der Austausch zwischen Visual C doch öfters sein sollte. Anscheinend gehöre ich zu den wenigen Leuten, die sowas brauchen. :gruebel:

lg,
jus

nahpets 13. Mai 2017 10:25

AW: Wie Delphi TDateTime zu c++ Datetime Ticks konvertieren?
 
Guckst Du hier: http://www.delphipraxis.net/132127-c...umwandeln.html

SysUtils.TTimeStamp

System.DateTime Structure

Weitersuchen hier: delphi +datetime +ticks +gregorianisch

jus 14. Mai 2017 00:56

AW: Wie Delphi TDateTime zu c++ Datetime Ticks konvertieren?
 
@nahpets: Vielen Dank fürs Suchen, aber die Links kannte ich auch schon.
Der vielversprechendeste Link war der C++ DateTime in Delphi TDateTime umwandeln, worauf meine aktuelle Quick&Dirty Lösung basiert.
Und zwar habe ich bemerkt, dass, wenn ich direkt Delphi TDateTime mit Hilfe von der WinAPI MSDN-Library durchsuchenSystemTimeToFileTime zu "TFileTime" umwandle, dann genau 1600 Jahre zu wenig sind. Darum addiere ich einfach vorher brutal 1600 Jahre dazu und fertisch. :-D Naja, zugegeben ist nicht grad sauber und ich kann mir auch nicht erklären warum das so ist, aber vielleicht weiß jemand von Forum warum.
Anbei die Lösung, vielleicht kanns wer ja mal brauchen.
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  SystemTime: TSystemTime;
  TimeTicks: UInt64;
  ADateTime: TDateTime;

begin
  ADateTime := StrToDateTime('27.09.2009 22:50:27');
  DateTimeToSystemTime(ADateTime, SystemTime);
  SystemTime.wYear := SystemTime.wYear +1600;
  SystemTimeToFileTime(SystemTime, TFileTime(TimeTicks));
  showMessage(IntToStr(Int64(TimeTicks)));
end;
Zur Probe, ob die berechneten Ticks richtig sind, kann man die Werte hier überprüfen. ;-)

lg,
jus

himitsu 14. Mai 2017 01:10

AW: Wie Delphi TDateTime zu c++ Datetime Ticks konvertieren?
 
Zitat:

Zitat von jus (Beitrag 1371316)
Naja, zugegeben ist nicht grad sauber und ich kann mir auch nicht erklären warum das so ist, aber vielleicht weiß jemand von Forum warum.


DateTime.Ticks > represents the number of 100-nanosecond intervals that have elapsed since 12:00:00 midnight, January 1, 0001 (0:00:00 UTC on January 1, 0001, in the Gregorian calendar)
FILETIME > Contains a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC).
Böse, wer sich da Schlimmes bei denkt.

Sicherer ist es aber, wenn du statt den Jahren, die 100tel-Nanosekunden "nachher" drauf rechnest.
Also einmal für den 1.1.1601 den Wert geben lassen und den dann verwenden.

Denn es kann gern mal sein, dass Datumsfunktionen sich zickig verhalten, wenn man für ein Datum sich den Wert geben lässt, wo eventuell noch nicht die Schaltsekunden und Schaljahre festgelegt wurden, was sooooo weit in der Zukunft (24.05.3617) schon mal vorkommen könnte.
Und der Wert könnte auch falsch sein, wenn bei einem der beiden Werte oder bei Beiden die Schaltsekunden und Co. mit eingerechnet sind, die so dann natürlich nicht stimmen können.

TiGü 15. Mai 2017 13:44

AW: Wie Delphi TDateTime zu c++ Datetime Ticks konvertieren?
 
Hallo jus,

die fiskaltrust-Doku zeigt immer C#-Code. Das ist kein Visual C++.

Anbei noch zwei verschiedene Funktion zur Erzeugung von Ticks.
Welche "besser" ist sei mal dahingestellt.
Die minus Eins ist wegen dem Offset von TTimeStamp.Date (http://docwiki.embarcadero.com/Libra...ils.TTimeStamp)

Delphi-Quellcode:
program ConvertDateTimeToTicksProject;

{$APPTYPE CONSOLE}

{$R *.res}


uses
  System.SysUtils,
  System.TimeSpan;

function ConvertTimeStampToMilliSeconds(const ATimeStamp: TTimeStamp): Int64;
begin
  Result := ATimeStamp.Date - 1;
  Result := (Result * MSecsPerDay) + ATimeStamp.Time;
end;

function ConvertDateTimeToTicks(const ADateTime: TDateTime): Int64;
var
  TimeStamp: TTimeStamp;
  TimeStampInMilliseconds: Int64;
begin
  TimeStamp := DateTimeToTimeStamp(ADateTime);
  TimeStampInMilliseconds := ConvertTimeStampToMilliSeconds(TimeStamp);
  Result := TimeStampInMilliseconds * TTimeSpan.TicksPerMillisecond;
end;

function ConvertDateTimeToTicksEx(const ADateTime: TDateTime): Int64;
var
  TimeSpan: TTimeSpan;
  LHour, LMinute, LSecond, LMilliSecond: Word;
  LDays: Integer;
begin
  LDays := DateTimeToTimeStamp(ADateTime).Date - 1;
  DecodeTime(ADateTime, LHour, LMinute, LSecond, LMilliSecond);
  TimeSpan := TTimeSpan.Create(LDays, LHour, LMinute, LSecond, LMilliSecond);
  Result := TimeSpan.Ticks;
end;

procedure Main;
var
  MyDateTime: TDateTime;
begin
  MyDateTime := System.SysUtils.Now;
  Writeln(FormatDateTime('hh:nn:ss:zzz - dd.mm.yyyy', MyDateTime));
  Writeln(ConvertDateTimeToTicks(MyDateTime));

  MyDateTime := StrToDateTime('01.04.2017 00:00:01');
  Writeln(FormatDateTime('hh:nn:ss:zzz - dd.mm.yyyy', MyDateTime));
  Writeln(ConvertDateTimeToTicks(MyDateTime));

  MyDateTime := StrToDateTime('29.02.2020 12:00:00');
  Writeln(FormatDateTime('hh:nn:ss:zzz - dd.mm.yyyy', MyDateTime));
  Writeln(ConvertDateTimeToTicks(MyDateTime));

  /// //////////////////////////////////////////////////////////////

  MyDateTime := System.SysUtils.Now;
  Writeln(FormatDateTime('hh:nn:ss:zzz - dd.mm.yyyy', MyDateTime));
  Writeln(ConvertDateTimeToTicksEx(MyDateTime));

  MyDateTime := StrToDateTime('01.04.2017 00:00:01');
  Writeln(FormatDateTime('hh:nn:ss:zzz - dd.mm.yyyy', MyDateTime));
  Writeln(ConvertDateTimeToTicksEx(MyDateTime));

  MyDateTime := StrToDateTime('29.02.2020 12:00:00');
  Writeln(FormatDateTime('hh:nn:ss:zzz - dd.mm.yyyy', MyDateTime));
  Writeln(ConvertDateTimeToTicksEx(MyDateTime));
end;

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

end.

jus 15. Mai 2017 14:51

AW: Wie Delphi TDateTime zu c++ Datetime Ticks konvertieren?
 
Zitat:

Zitat von himitsu (Beitrag 1371317)
DateTime.Ticks > represents the number of 100-nanosecond intervals that have elapsed since 12:00:00 midnight, January 1, 0001 (0:00:00 UTC on January 1, 0001, in the Gregorian calendar)
FILETIME > Contains a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC).

Das erklärt natürlich alles. Danke fürs Nachforschen!

Zitat:

Zitat von himitsu (Beitrag 1371317)
Sicherer ist es aber, wenn du statt den Jahren, die 100tel-Nanosekunden "nachher" drauf rechnest.
Also einmal für den 1.1.1601 den Wert geben lassen und den dann verwenden.

Denn es kann gern mal sein, dass Datumsfunktionen sich zickig verhalten, wenn man für ein Datum sich den Wert geben lässt, wo eventuell noch nicht die Schaltsekunden und Schaljahre festgelegt wurden, was sooooo weit in der Zukunft (24.05.3617) schon mal vorkommen könnte.
Und der Wert könnte auch falsch sein, wenn bei einem der beiden Werte oder bei Beiden die Schaltsekunden und Co. mit eingerechnet sind, die so dann natürlich nicht stimmen können.

@himitsu: Danke für den Tipp, werde ich dann auch so umsetzen.

@TiGü: Vielen vielen Dank für die 2 Funktionen! Da ich immer noch Delphi 2007 verwende, kennt mein Delphi leider kein TTimeSpan, somit fällt für mich die "ConvertDateTimeToTicksEx" flach. Interessant ist aber trotzdem, dass TTimeSpan direkt in Ticks umwandeln kann. Anbei deine angepaßte ConvertDateTimeToTicks Routine, damit es in Delphi 2007 läuft:
Delphi-Quellcode:
function ConvertTimeStampToMilliSeconds(const ATimeStamp: TTimeStamp): Int64;
begin
  Result := ATimeStamp.Date - 1;
  Result := (Result * MSecsPerDay) + ATimeStamp.Time;
end;

function ConvertDateTimeToTicks(const ADateTime: TDateTime): Int64;
var
  TimeStamp: TTimeStamp;
  TimeStampInMilliseconds: Int64;
begin
  TimeStamp := DateTimeToTimeStamp(ADateTime);
  TimeStampInMilliseconds := ConvertTimeStampToMilliSeconds(TimeStamp);
//  Result := TimeStampInMilliseconds * TTimeSpan.TicksPerMillisecond;
  Result := TimeStampInMilliseconds * 10000;
end;
lg,
jus


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:44 Uhr.

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