Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: DateTimeToFileDate Bug


This question is answered.


Permlink Replies: 3 - Last Post: Mar 22, 2018 10:24 AM Last Post By: Remy Lebeau (Te... Threads: [ Previous | Next ]
Allan Fernandes

Posts: 76
Registered: 9/30/00
DateTimeToFileDate Bug  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 20, 2018 10:37 PM
A Compression software that I am using stores time in Long format and I am forced to use it.
There seems to be a bug in Delphi's date handling even if Milliseconds are 000.
The bug amplifies if seconds are 58 or 59
Please advice

Step-1
FileAge(wFileName ,wFileDtTm);
DecodeTime(wFileDtTm,hr,mn,sc,msc) ;

Step-2
nLong:=DateTimeToFileDate(wFileDtTm) ;
DecodeTime(FileDateToDateTime(nLong),hr,mn,sc,msc) ;

Step-3
oLong:=FileAge(wFileName);
DecodeTime(FileDateToDateTime(oLong),hr,mn,sc,msc) ;

Step-1        Step-2                              Step-3			   (OLong-NLong)
mn:sc:msc     nLong		mn:sc:msc	  oLong		mn:sc:msc	
 
14:54:000    1282695643  	14:54:000         1282695643  	14:54:000		0
 
11:08:492    1218740580 	11:08:000         1218740581  	11:10:000		1
 
40:59:880    1249670429  	40:58:000         1249670432  	41:00:000		3
 
54:25:000    1282696908  	54:24:000         1282696909  	54:26:000		1
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: DateTimeToFileDate Bug  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 21, 2018 8:15 AM   in response to: Allan Fernandes in response to: Allan Fernandes
Allan Fernandes wrote:

A Compression software that I am using stores time in Long format and
I am forced to use it. There seems to be a bug in Delphi's date
handling even if Milliseconds are 000. The bug amplifies if seconds
are 58 or 59 Please advice

It is not a bug. The DOS date/time format is not a precise format. It
has no miliseconds at all, and seconds are divided by 2 (see the
documentation for the FileTimeToDosDateTime() function on MSDN for the
exact format:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms724274.aspx).
So, when you convert a file's date/time to DOS format via
DateTimeToFileDate() or the deprecated FileAge(), there is a loss of
precision, which is mirrored in FileDateToDateTime(). That is what you
are seeing.

--
Remy Lebeau (TeamB)
Allan Fernandes

Posts: 76
Registered: 9/30/00
Re: DateTimeToFileDate Bug  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 22, 2018 5:23 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Hi,

Is there any other method to store the datetime in Long format and retain the precision to the second.

This is to do with a Compression utility written in Delphi whose source code I have.
The Central Directory expects the date separately and time separately in Long format.

Regards
Allan

Remy Lebeau (TeamB) wrote:
Allan Fernandes wrote:

A Compression software that I am using stores time in Long format and
I am forced to use it. There seems to be a bug in Delphi's date
handling even if Milliseconds are 000. The bug amplifies if seconds
are 58 or 59 Please advice

It is not a bug. The DOS date/time format is not a precise format. It
has no miliseconds at all, and seconds are divided by 2 (see the
documentation for the FileTimeToDosDateTime() function on MSDN for the
exact format:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms724274.aspx).
So, when you convert a file's date/time to DOS format via
DateTimeToFileDate() or the deprecated FileAge(), there is a loss of
precision, which is mirrored in FileDateToDateTime(). That is what you
are seeing.

--
Remy Lebeau (TeamB)
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: DateTimeToFileDate Bug
Correct
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 22, 2018 10:24 AM   in response to: Allan Fernandes in response to: Allan Fernandes
Allan Fernandes wrote:

Is there any other method to store the datetime in Long format and
retain the precision to the second.

Rather than store the individual date/time components, you could store
an offset from a given epoch.

For example, Unix timestamps are expressed as the number of seconds
that have elapsed since January 1 1970 00:00:00 UTC. The RTL does have
DateTimeToUnix() and UnixToDateTime() functions, though the Unix times
are expressed as Int64 instead of Integer (as 32-bit Unix timestamps
can't exceed January 19 2038 03:14:08 UTC).

This is to do with a Compression utility written in Delphi whose
source code I have.

That means you are limited to whatever date/time format the compression
library expects you to use. Does it use DOS timestamps, Unix
timestamps, or something else? You have the source code, how does it
use the Date and Time values?

The Central Directory expects the date separately and time separately
in Long format.

You didn't say that earlier. You made it sound like you have to store
both Date and Time into a single Long. A DOS timestamp can do that,
but with lose of precision. But separating Date and Time into separate
Longs makes a big difference, because that gives you much more bits to
work with. You can bit-stuff the components of a TDate into a Long,
and bit-stuff the componnets of a TTime (down to milliseconds) into a
Long. Or you could convert a TDateTime to Unix Int64 and then split
its bits into 2 Longs. Or, since TDateTime is an 8-byte Double to
begin wtih, you could simply type-cast it to Int64 and split its bits
into 2 Longs.

--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02