Konwersja time.time() w Pythonie na TDateTime w Delphi

0

Cześć. Wiecie, że jak umiem to pomagam w problemach z Delphi i Pascalem, ale w większości innych języków jestem lama, a zabrałem się za tłumaczenie kodu servera gry w Pythonie na Delphi i WinAPI. No i napotkałem na problem. Googlowałem, szukałem, kombinowałem, ale nie bardzo mi się udaje. Na jakiejs stronie podawali przykład żeby podzielić jeszcze to co uzyskuje przez $1E6 czy jakoś tak, ale nie wyszło. Otóż chce uzyskać taki sam wynik jaki zwraca funkcja time.time() w Pythonie pod Delphi. Kombinowałem póki co z VCL tak - Delphi:

program Project2;

{$APPTYPE CONSOLE}

uses
  DateUtils, SysUtils;

var
  Res : Double;
  Dt : TDateTime;
  tv_sec : LongInt;
begin
  DecimalSeparator := '.';
  Dt := EncodeDate(1970, 1, 1);
  while True do
  begin
    tv_sec := SecondsBetween(Now, Dt);
    Res := StrToFloat(IntToStr(tv_sec) + DecimalSeparator + FormatDateTime('zzz', Now));
    Writeln(FloatToStr(Res));
  end;
end.

W Pythonie dla testów używam najprostszego skryptu jaki umiałem napisać:

#!/usr/bin/env python

import time

while 0 == 0:
	print(time.time())

Ale różnice w pokazywanych wynikach są znaczne i to nie tylko w ilości milisekund po separatorze dziesiętny, co będzie oczywiste, bo ciężko uruchomić dwa osobne programy w tej samej chwli. Ale liczba przed przecinkiem w przypadku Delphi jest znacznie większa. Prosił bym o jakieś przykłądy rozwiązania. Z góry dziękuję i wybaczcie mi to lamerskie pytanie, bo z Pythonem mam do czynienia od niecałych dwóch dni na zasadzie próby tłumaczenia kodu, co jako tako mi idzie, ale teraz ważne dla servera będzie przekazywanie czasu i klatek między klientami i chce to zrobić w sposób prawidłowy. Dodam, że korzystam z Pythona 3.2 i pod nim też uruchamiam gotowy serwer w pliku *.py. A i wiem, że jest py2exe, ale i tak generuje około 5 MB potrzebnych "dodatków" w postaci plików i dllki poza samym exekiem, a jakbym dobrze przetłumaczł kod do końca to serwer może zajmować po UPX'nięciu od około 19 do może 25 KB, a funkcjonalnośc będzie ta sama i nie potrzeba będzie instalować Pythona ani konwertować źródeł py2exe, który wspiera jako najpóźniejszą chyba Pythona w wersji 2.7.2, bo z taką testowałem. Wybaczcie rozpisanie się. Pora iśc pospać :)

0
  1. Fragment dokumentacji Pythona:

time() -> floating point number
Return the current time in seconds since the Epoch.
Fractions of a second may be present if the system clock provides them.

  1. Java daje takie same wyniki jak Python.

Co sugeruje, że jedna z funkcji EncodeDate lub SecondsBetween działa źle.

0

Tam będziesz miał bodajże różnicę dwóch godzin 60602 s -> 7200 s

coś takiego powinno wyświetlić to samo co w delphi:

import time

while 1:
    print(time.time() - time.altzone)

w sumie poprawnie powinno uwzględniać coś takiego:

def correctTime():
    if time.localtime().tm_isdst and time.daylight:
        return time.time() - time.altzone
    else:
        return time.time() - time.timezone

while 1:
    print(correctTime())

Dochodź sobie do tego co to tm_isdst i daylight - a w sumie na już to masz odjęcie dwóch godzin w delphi ;)

1

Podejrzewam, że ten Windows w uses Ci się nie spodoba, ale to masz mniej więcej poprawne rozwiązanie... W każdym razie masz punkt wyjścia ;)

program Project2;

{$APPTYPE CONSOLE}

uses
  DateUtils, SysUtils, Windows;

var
  Res : Double;
  Dt : TDateTime;
  tv_sec : LongInt;

  tz: TTimeZoneInformation;
  badTime : Integer;
begin
  DecimalSeparator := '.';
  Dt := EncodeDate(1970, 1, 1);

  if GetTimeZoneInformation(tz) = 2 then
    badTime := tz.DaylightBias * 60 - 3600
      else
        badTime := tz.DaylightBias * 60;

  while True do
  begin
    tv_sec := SecondsBetween(Now, Dt) + badTime;
    Res := StrToFloat(IntToStr(tv_sec) + DecimalSeparator + FormatDateTime('zzz', Now));
    Writeln(FloatToStr(Res));
  end;
end.

BTW:

olesio napisał(a)

ale teraz ważne dla servera będzie przekazywanie czasu i klatek między klientami i chce to zrobić w sposób prawidłowy
Jeśli wszyscy klienci będą się porozumiewali wyłącznie poprzez Twój serwer w delphi, to olej to - Twoje rozwiązanie z pierwszego postu jest wystarczające...

0
madmike napisał(a)

Podejrzewam, że ten Windows w uses Ci się nie spodoba, ale to masz mniej więcej poprawne rozwiązanie... W każdym razie masz punkt wyjścia ;)

Działa idealnie. Bardzo Tobie dziękuję. A po dodaniu odpowiednich funkcji, procedur, stałych, typów oraz zmiennych z modułów DateUtils i SysUtils plus potrzebne funkcje C podobne, tak aby całośc działała w WinAPI pod konsolą stworzyłem moduł, który dołaczam do tego posta. Jest tam oczywiście funkcja, którą nazwałem Python_Time_Time zwracająca Double wraz z milisekundami w postaci formatowania %.3u.

madmike napisał(a)

Jeśli wszyscy klienci będą się porozumiewali wyłącznie poprzez Twój serwer w delphi, to olej to - Twoje rozwiązanie z pierwszego postu jest wystarczające...

Może i tak, ale wolałem aby czasy był jak najdokładniejszy i zgodny z tym co zwraca Pythnon, aby wykluczyć późniejsze ewentualne błędy i problemy z obsługą klientów, z powodu czasu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1