How to convert a python datetime to a delphi TDateTime?

I need to convert datetime.datetime(2018, 4, 1, 16, 22, 9, 920000) into the Delphi TDateTime value 43191.68205925926, on Python versions < 3.2.

I tried

def pdt2ddt(pydt):  # py datetime into delphi time
   start = datetime.datetime(1899, 12, 30)
   delta = pydt - start
   seconds = (delta - datetime.timedelta(days=delta.days)).total_seconds()
   return seconds / 3600 / 24

but timedelta.total_seconds() works only if the python version is 3.2 and above.

Delphi TDateTime values are expressed as a double floating point value counting days since midnight 1899-12-30.

Upvotes: 1

Views: 1157

Answers (2)

Max Kleiner
Max Kleiner

Reputation: 1612

Works also great with evalStr():

PyEngine_netA.ExecString(('from datetime import datetime, timedelta'));
PyEngine_netA.ExecString(UTF8Encode('DELPHI_EPOCH= datetime(1899,12,30)'));
PyEngine_netA.ExecString('def datetime_fromdelphi(dvalue):'+LF+
                         '  return DELPHI_EPOCH + timedelta(days=dvalue)');
println(PyEngine_netA.EvalStr(('datetime_fromdelphi(43191.68205925926)')));

Upvotes: 0

Martijn Pieters
Martijn Pieters

Reputation: 1121744

The Delphi value is the number of days since a specific epoch, 1899-12-30. Construct a timedelta from the value as the days argument and add the epoch to go from Delphi to Python, and to go the other way, produce a delta between the Python datetime and the epoch, and divide the result by a timedelta(days=1) value (Python 3.2 / Python 2.7 and newer) or just add up the seconds and microseconds components and divide by the number of seconds in a day for older Python versions:

from datetime import datetime, timedelta

# A delphi datetime value is the (fractional) number of days since the epoch
# e.g. 42 minutes past the the UNIX epoch is 25569.029166666667 in Delphi terms.
DELPHI_EPOCH = datetime(1899, 12, 30)

def datetime_fromdelphi(dvalue):
    return DELPHI_EPOCH + timedelta(days=dvalue)

def datetime_todelphi(dt):
    try:
        return (dt - DELPHI_EPOCH) / timedelta(days=1)
    except TypeError:
        # Python 2.7 / Python 3.1 or older don't support division
        delta = dt - DELPHI_EPOCH
        return delta.days + (delta.seconds + delta.microseconds / 1000000.0) / 24 / 3600

This just uses an adjusted version of the equivalency documented for timedelta.total_seconds() to get the exact number of days as a floating point number.

Demo:

>>> datetime_fromdelphi(43191.68205925926)
datetime.datetime(2018, 4, 1, 16, 22, 9, 920000)
>>> datetime_todelphi(datetime(2018, 4, 1, 16, 22, 9, 920000))
43191.682059259256

Upvotes: 3

Related Questions