Thread View: borland.public.delphi.nativeapi.win32
8 messages
8 total messages
Started by D-Fan
Mon, 04 Aug 2008 07:27
Adding time to the a tdatetime
Author: D-Fan
Date: Mon, 04 Aug 2008 07:27
Date: Mon, 04 Aug 2008 07:27
2 lines
990 bytes
990 bytes
What is the best way to add minutes, hours, and or days to a tdatetime variable?
Re: Adding time to the a tdatetime
Author: Descartes
Date: Mon, 04 Aug 2008 07:41
Date: Mon, 04 Aug 2008 07:41
21 lines
1235 bytes
1235 bytes
"D-Fan" wrote: > What is the best way to add minutes, hours, and or days to a > tdatetime variable? D-Fan, Check out IncMilliSecond IncSecond IncMinute IncHour IncDay IncWeek IncYear in unit DateUtils Regards Descartes
Re: Adding time to the a tdatetime
Author: John Herbster
Date: Mon, 04 Aug 2008 11:01
Date: Mon, 04 Aug 2008 11:01
43 lines
2261 bytes
2261 bytes
> "D-Fan" wrote:
>> What is the best way to add minutes, hours,
>> and or days to a TDateTime variable?
"Descartes" wrote
> Check out
> IncMilliSecond
> IncSecond
> IncMinute
> IncHour
> IncDay
> IncWeek
> IncYear
> in unit DateUtils
D-Fan and Descartes,
Of course many of the routines are sub-optimal or broken
(at least in D7). Many of the Inc* functions accumulate
errors. For example
procedure TForm1.Button3Click(Sender: TObject);
var DT: TDateTime; i: integer;
begin
DT := 40000;
For i := 1 to 24 do DT := IncHour(DT,1);
If DT = 40001
then ShowMessage('EQ')
else ShowMessage(FloatToStr(DT-40001));
end;
will increment DT to a little *less* than a day.
A better way is to convert and round the DT to milliseconds,
add the increment and convert back to DT.
You can find code for converting to DT to milliseconds
and back in this QualityCentral report:
Report No: 56957 Status: Open
A Fix for DateUtils Date-Time Compare Functions
http://qc.codegear.com/wc/qcmain.aspx?d=56957
QCWIN:Defect_No=56957
(Look in the comments or attachments.)
Rgds, JohnH
Re: Adding time to the a tdatetime
Author: D-Fan
Date: Mon, 04 Aug 2008 14:46
Date: Mon, 04 Aug 2008 14:46
43 lines
2298 bytes
2298 bytes
John Herbster wrote:
>> "D-Fan" wrote:
>>> What is the best way to add minutes, hours, and or days to a
>>> TDateTime variable?
>
> "Descartes" wrote
>> Check out
>> IncMilliSecond
>> IncSecond
>> IncMinute
>> IncHour
>> IncDay
>> IncWeek
>> IncYear
>> in unit DateUtils
>
> D-Fan and Descartes,
>
> Of course many of the routines are sub-optimal or broken
> (at least in D7). Many of the Inc* functions accumulate errors. For
> example
> procedure TForm1.Button3Click(Sender: TObject);
> var DT: TDateTime; i: integer;
> begin
> DT := 40000;
> For i := 1 to 24 do DT := IncHour(DT,1);
> If DT = 40001
> then ShowMessage('EQ')
> else ShowMessage(FloatToStr(DT-40001));
> end;
> will increment DT to a little *less* than a day.
>
> A better way is to convert and round the DT to milliseconds, add the
> increment and convert back to DT.
> You can find code for converting to DT to milliseconds and back in this
> QualityCentral report: Report No: 56957 Status: Open
> A Fix for DateUtils Date-Time Compare Functions
> http://qc.codegear.com/wc/qcmain.aspx?d=56957
> QCWIN:Defect_No=56957
> (Look in the comments or attachments.)
>
> Rgds, JohnH
Thanks for your response.
Re: Adding time to the a tdatetime
Author: Descartes
Date: Mon, 04 Aug 2008 16:40
Date: Mon, 04 Aug 2008 16:40
58 lines
3142 bytes
3142 bytes
John, I have a great respect for your thoughts about TDateTime and calculations in general with floats. Reading your writings, I've learned at least to be cautios and to take into consideration the limits and the inexactness of floats. However, I would like to put the OPs question in perspective to avoid that he or anybody else gets scared and goes into unnecessary complicated measures in trying to achieve their goal. > Of course many of the routines are sub-optimal or broken > (at least in D7). "Of course"? ;-) > Many of the Inc* functions accumulate errors. Of course! Adding inexact values repeatedly will do just that (except in the rare case when the errors cancel out each other). > will increment DT to a little *less* than a day. Your example produces an error of -5 nanoseconds I made a test using IncMinute 365 * 24 * 60 times (1 year). The error was 103 milliseconds. But why would somebody want to do that? > A better way is to convert and round the DT to milliseconds, add the > increment and convert back to DT. OP wanted to add minutes, hours and days. Although he did not say so, one can assume that he deals with ordinary dates and times with a resolution down to seconds, but not milliseconds. Looking at the errors produced with the standard inc* routines in this perspective, I don't think it's worth to bother with conversion to/from milliseconds. A more severe problem with TDateTime is that the pitfalls with negative values (datetimes before 31.12.1899) are not documented at all! > You can find code for converting to DT to milliseconds and back in > this QualityCentral report: Report No: 56957 Status: Open > A Fix for DateUtils Date-Time Compare Functions > http://qc.codegear.com/wc/qcmain.aspx?d=56957 > QCWIN:Defect_No=56957 > (Look in the comments or attachments.) Seems to be a very good report. I'll check it later in depth and vote for it (maybe ;-)) No offence, best regards Descartes 1794744326139 milliseconds old a few minutes ago ;-)
Re: Adding time to the a tdatetime
Author: John Herbster
Date: Mon, 04 Aug 2008 18:32
Date: Mon, 04 Aug 2008 18:32
95 lines
4611 bytes
4611 bytes
>> Of course many of the routines are sub-optimal or broken
>> (at least in D7).
"Descartes" wrote
> "Of course"? ;-)
Descartes,
Yes, DateUtils.pas has had many problems, most of
which are still not fixed. Check QualityCentral!
>> Many of the Inc* functions *accumulate* errors.
> Of course! Adding inexact values repeatedly will do
> just that (except in the rare case when the errors
> cancel out each other).
>> will increment DT to a little *less* than a day.
> Your example produces an error of -5 nanoseconds
Which is more than enough to throw the final increment
into the wrong day.
What we need, of course, is a way to do exact arithmetic
with days, hour, minutes, and seconds. This would be
easily possible with time variables of that could store
time exactly to the minute, second, thousandth of a
second. But as long as programmers are happy with inexact
time measurement and arithmetic, it will not happen.
My
>> A Fix for DateUtils Date-Time Compare Functions
>> http://qc.codegear.com/wc/qcmain.aspx?d=56957
is a attempt to at least allow time calculations that
will be as exact as possible.
>> A better way is to convert and round the DT to milliseconds,
>> add the increment and convert back to DT.
> OP wanted to add minutes, hours and days. Although he did not
> say so, one can assume that he deals with ordinary dates and
> times with a resolution down to seconds, but not milliseconds.
> Looking at the errors produced with the standard inc* routines
> in this perspective, I don't think it's worth to bother with
> conversion to/from milliseconds.
But if he follows your advice, when he discovers that adding
a minutes 60 times does not give the same result as adding
an hour, he will be back to the well again asking what's wrong.
> A more severe problem with TDateTime is that the pitfalls
> with negative values (datetimes before 31.12.1899) are not
> documented at all!
TDateTime type is documented in D7's Help, though not
very well.
My conversions to and from milliseconds hide all of the
pre-31.12.1899 nastiness by using the nearly perfect
DateTimeToTimeStamp and TimeStampToDateTime routines.
>> You can find code for converting to DT to milliseconds and
>> back in this QualityCentral report:
>> Report No: 56957 Status: Open
>> A Fix for DateUtils Date-Time Compare Functions
>> http://qc.codegear.com/wc/qcmain.aspx?d=56957
>> QCWIN:Defect_No=56957
>> (Look in the comments or attachments.)
> Seems to be a very good report. I'll check it later in depth
> and vote for it (maybe ;-))
Thank you.
Regards, JohnH
PS: D7's DateUtils gives wrong result for the last call to
EncodeDateTime in this test (time part got wrong sign):
procedure TForm1.Button4Click(Sender: TObject);
var s: string; dt: TDateTime;
begin
s := FormatDateTime('yyyy-mm-dd_HH:nn:ss.zzz', 0.00);
Memo1.Lines.Add(s);
s := FormatDateTime('yyyy-mm-dd_HH:nn:ss.zzz', 2.75);
Memo1.Lines.Add(s);
s := FormatDateTime('yyyy-mm-dd_HH:nn:ss.zzz',-1.25);
Memo1.Lines.Add(s);
s := FormatDateTime('yyyy-mm-dd_HH:nn:ss.zzz',35065);
Memo1.Lines.Add(s);
dt := EncodeDateTime(1899,12,29,06,00,00,000);
Memo1.Lines.Add('EncodeDateTime(1899,12,29,06,00,00,000) =');
s := FormatDateTime(' yyyy-mm-dd_HH:nn:ss.zzz',dt);
Memo1.Lines.Add(s); {D7's DateUtils.EncodeDateTime has error.}
end;
Re: Adding time to the a tdatetime
Author: Pieter Zijlstra
Date: Mon, 04 Aug 2008 19:38
Date: Mon, 04 Aug 2008 19:38
49 lines
2421 bytes
2421 bytes
John Herbster wrote:
> procedure TForm1.Button4Click(Sender: TObject);
> var s: string; dt: TDateTime;
> begin
> s := FormatDateTime('yyyy-mm-dd_HH:nn:ss.zzz', 0.00);
> Memo1.Lines.Add(s);
> s := FormatDateTime('yyyy-mm-dd_HH:nn:ss.zzz', 2.75);
> Memo1.Lines.Add(s);
> s := FormatDateTime('yyyy-mm-dd_HH:nn:ss.zzz',-1.25);
> Memo1.Lines.Add(s);
> s := FormatDateTime('yyyy-mm-dd_HH:nn:ss.zzz',35065);
> Memo1.Lines.Add(s);
> dt := EncodeDateTime(1899,12,29,06,00,00,000);
> Memo1.Lines.Add('EncodeDateTime(1899,12,29,06,00,00,000) =');
> s := FormatDateTime(' yyyy-mm-dd_HH:nn:ss.zzz',dt);
> Memo1.Lines.Add(s); {D7's DateUtils.EncodeDateTime has error.}
> end;
Can't remember if I already tested this one before, but here we go :)
D7
1899-12-30_00:00:00.000
1900-01-01_18:00:00.000
1899-12-29_06:00:00.000
1996-01-01_00:00:00.000
EncodeDateTime(1899,12,29,06,00,00,000) =
1899-12-30_18:00:00.000
D2006
1899-12-30_00:00:00.000
1900-01-01_18:00:00.000
1899-12-29_06:00:00.000
1996-01-01_00:00:00.000
EncodeDateTime(1899,12,29,06,00,00,000) =
1899-12-29_06:00:00.000
D2007
1899-12-30_00:00:00.000
1900-01-01_18:00:00.000
1899-12-29_06:00:00.000
1996-01-01_00:00:00.000
EncodeDateTime(1899,12,29,06,00,00,000) =
1899-12-29_06:00:00.000
Seems to be fixed in the later versions.
--
Pieter
Re: Adding time to the a tdatetime
Author: John Herbster
Date: Mon, 04 Aug 2008 19:56
Date: Mon, 04 Aug 2008 19:56
1 lines
1232 bytes
1232 bytes
Pieter, Thanks, JohnH
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads