Convert Delphi Formatted Date Time to regular DateTime via PHP

Hi,

I am converting a script written in ASP to PHP. It reads a file created in Delphi. One particular function converts the Delphi-formatted times (e.g. 38837.0129173727) to a string of normal date time format (DD/MM/YYYY HH:MM:SS).

Here is the script

function ConvertDateTime(DelphiDateTime,DateTime)
      Days = Int(DelphiDateTime)
       Fraction = DelphiDateTime - Days
      Seconds = Fraction / (1/24/60/60)
      DateTime = CStr(DateAdd("d",Days,"30/12/1899 00:00:00"))
      DateTime = CStr(DateAdd("s",Seconds,DateTime))      
End Function

I am trying to convert this to PHP but really have no idea how delphi times are formatted in the first place. This function seems odd because the two arguments are exactly the same and are both the same delphi datetime values to be converted.

I've converted to PHP as

function ConvertDateTime($DelphiTime,$DateTime) {
      $Days = intval($DelphiTime);
      $Fraction = $DelphiTime - $Days;
      $Seconds = $Fraction / (1/24/60/60);
      $DateTime = strval(DateAdd("d",$Days,"30/12/1899 00:00:00"));
      $DateTime = strval(DateAdd("s",$Seconds,$DateTime));
      return $DateTime;
}

But when I pass echo ConvertDateTime(38837.0129173727,38837.0129173727) I get

Warning: mktime(): Windows does not support negative values for this function in ...

I am using a standard DateAdd function in PHP

function DateAdd($interval, $number, $date) {

    $date_time_array = getdate($date);
    $hours = $date_time_array['hours'];
    $minutes = $date_time_array['minutes'];
    $seconds = $date_time_array['seconds'];
    $month = $date_time_array['mon'];
    $day = $date_time_array['mday'];
    $year = $date_time_array['year'];

    switch ($interval) {
   
        case 'yyyy':
            $year+=$number;
            break;
        case 'q':
            $year+=($number*3);
            break;
        case 'm':
            $month+=$number;
            break;
        case 'y':
        case 'd':
        case 'w':
            $day+=$number;
            break;
        case 'ww':
            $day+=($number*7);
            break;
        case 'h':
            $hours+=$number;
            break;
        case 'n':
            $minutes+=$number;
            break;
        case 's':
            $seconds+=$number;
            break;            
    }
       $timestamp= mktime($hours,$minutes,$seconds,$month,$day,$year);
    return $timestamp;
}

How are these delphi times actually formatted and how might I use this knowledge to develop a script to convert them using PHP?


jbregAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

dr_dedoCommented:
how is date time calculate in delphi ?? what date/time does 38837.0129173727 represents ??
0
jbregAuthor Commented:
No idea. That's part of the question, I will ask in the Delphi Area.
0
Eddie ShipmanAll-around developerCommented:
From the Delphi help file:
"The integral part of a Delphi TDateTime value is the number of days that have
passed since 12/30/1899. The fractional part of the TDateTime value is fraction
of a 24 hour day that has elapsed."

The value 38837.0129173727  = 30-04-2006 00:18:36
0
Cloud Class® Course: SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

Eddie ShipmanAll-around developerCommented:
Have you echo'ed the variables in your DateAdd function?
Seems to be returning incorrect results.

DelphiTime:38837.0129174
Days:38837
Fraction:0.0129173726964
Seconds:1116.06100097
Hours:19
Mins:0
Secs:30
Mon:12
Day:364
Year:1969
DateTime:-61
Hours:18
Mins:58
Secs:59
Mon:12
Day:364
Year:1969
DateTime:-1


0
Eddie ShipmanAll-around developerCommented:
How the question really should read is:
"I have a floating point variable that corresponds to a timestamp where the integral part
is the number of days that have passed since 12/30/1899 and the fractional part is
fraction of a 24 hour day that has elapsed. How do I convert this to a PHP timestamp?"

Remember, you can subtract 25569 to make the value begin at 1/1/1970 for PHP timestamp
values.

0
dr_dedoCommented:
all credit goes to the delphi hero :)

this code would print 30-04-2006 0:18:36
<?
$d = 38837.0129173727;
$days = intval($d)-25568;
$fraction = ''+38837.0129173727;
$fraction = substr($fraction,strpos($fraction,'.'));
$sec = $fraction * 24*60*60;
$date = date('d-m-Y G:i:s',mktime(0,0,$sec,1,$days,1970));
echo $date;
?>
0
dr_dedoCommented:
it would be better if in the form of a function

<?
$d = 38837.0129173727;
echo convert ($d);

//====== convert =========================
function convert ($delphiDate){
  $days = intval($delphiDate)-25568;
  $fraction = ''+$delphiDate;
  $fraction = substr($fraction,strpos($fraction,'.'));
  $sec = $fraction * 24*60*60;
  $date = date('d-m-Y G:i:s',mktime(0,0,$sec,1,$days,1970));
  return $date;
}
//======================================
?>
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Eddie ShipmanAll-around developerCommented:
I was really trying to get that algorithm figured out. couldn't quite get it.
Good work, dr_dedo.

But can you explain why
25569.000001111 = 01/01/1970 00:00:00
and
25569.000000000 = 27-11-1903 17:31:44

0
Eddie ShipmanAll-around developerCommented:
I think it's cool how mktime automatically added the number of days to 1970.
0
dr_dedoCommented:
guess point split with EddieShipman is fair
wish questioner didn't abandon that question !
0
Eddie ShipmanAll-around developerCommented:
OK, but give dr_dedo 2/3 as he is the one that came up with the algorithm. I only provided the info
on how Delphi DateTime is designed.
0
hujiCommented:
I'm not sure if we can assign unequal shares of points in cleanup process, but I'll discuss this with the cleanup admin and let you know.
0
Eddie ShipmanAll-around developerCommented:
The OP could split them for you if he's listening.
0
hujiCommented:
I verified what I thought about splitting the points with cleanup admin, and yes, the shares going to experts are always equal. We cannot assign unequal points to experts involved, while the asker can.
I will leave the final decision to be made by a moderator.
Regards,
Huji
0
dr_dedoCommented:
equal points are OK !!
EddieShipman didn't do less than me here !!!!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.