Recent

Author Topic: HH:MM:SS to second conversion problem  (Read 3133 times)

Vodnik

  • Full Member
  • ***
  • Posts: 210
HH:MM:SS to second conversion problem
« on: March 20, 2018, 10:11:24 pm »
Hello!
I'm using the following code to convert HH:MM:SS to seconds:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.DateTimePicker1Change(Sender: TObject);
  2. begin
  3.   Label1.Caption := 'Seconds: '+  IntToStr(Trunc(Frac(DateTimePicker1.Time)*3600*24));
  4. end;
  5.  

The example project attached. When I increase or decrease seconds in DateTimePicker, values in Label do not always change accordingly. Most amazing is that sometimes this work, sometimes not. I even managed to make two identical DateTimePicker controls in one form, one working fine, while another not. Seems this depends upon initial Time value set to DateTimePicker at design time. But after full rebuild of a project this effect disappear, both controls have problems.

Is it my mistake or what?

Bart

  • Hero Member
  • *****
  • Posts: 5275
    • Bart en Mariska's Webstek
Re: HH:MM:SS to second conversion problem
« Reply #1 on: March 20, 2018, 10:18:41 pm »
Why don't you use DecodeTime() to get the hours, minutes and seconds (it'll disregard the date part) then do result := 24*60*hours + 60*minutes + seconds.

Bart

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: HH:MM:SS to second conversion problem
« Reply #2 on: March 20, 2018, 11:17:03 pm »
Rounding issue  most likely...

 I've been using the CURRENCY type lately, it seems to take care of those issues by rounding after X-number of digits.

Move the Time into a CURRENTCY type and do all the math on that , see what happens.
The only true wisdom is knowing you know nothing

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: HH:MM:SS to second conversion problem
« Reply #3 on: March 20, 2018, 11:47:51 pm »
Better would be to use existing routines, rather than reinvent the wheel.

Code: Pascal  [Select][+][-]
  1. procedure TForm1.DateTimePicker1Change(Sender: TObject);
  2. begin
  3.   Label1.Caption := Format('seconds: %d', [DateTimeToTimeStamp(DateTimePicker1.Time).Time div 1000]);
  4. end;

Vodnik

  • Full Member
  • ***
  • Posts: 210
Re: HH:MM:SS to second conversion problem
« Reply #4 on: March 21, 2018, 11:58:44 am »
Why don't you use DecodeTime() to get the hours, minutes and seconds (it'll disregard the date part) then do result := 24*60*hours + 60*minutes + seconds.
Bart,
I was looking for possible solutins, have found a hot discussion here:
https://www.experts-exchange.com/questions/27026661/How-do-I-convert-04-05-04-to-seconds.html
and have chosen this method because of productivity. I'm working with database and this procedure may be called for each record.

Better would be to use existing routines, rather than reinvent the wheel.
Code: Pascal  [Select][+][-]
  1. procedure TForm1.DateTimePicker1Change(Sender: TObject);
  2. begin
  3.   Label1.Caption := Format('seconds: %d', [DateTimeToTimeStamp(DateTimePicker1.Time).Time div 1000]);
  4. end;
howardpc,
Searching for the wheel with Google brought me first to DATEUTILS unit, where I didn't find smth to fit my requirement, rather than to SYSUTILS...
Your code works fine, thanks a lot!

wp

  • Hero Member
  • *****
  • Posts: 11855
Re: HH:MM:SS to second conversion problem
« Reply #5 on: March 21, 2018, 12:28:04 pm »
Hello!
I'm using the following code to convert HH:MM:SS to seconds:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.DateTimePicker1Change(Sender: TObject);
  2. begin
  3.   Label1.Caption := 'Seconds: '+  IntToStr(Trunc(Frac(DateTimePicker1.Time)*3600*24));
  4. end;
  5.  
The units of TDateTime, TDate, TTime are full days; the fractional part is the time. Therefore, extracting the time by frac(time) is correct, and multiplication by the number of seconds per day (24*60*60) as well.

But then you convert this floating point value to an integer by calling trunc. In case of the 5 seconds the result of the floating point calculation is 4.999999999 (many nines). Trunc chops off the decimals and returns a 4. You'll get the correct value if you use round which returns the nearest integer.
Code: Pascal  [Select][+][-]
  1. procedure TForm1.DateTimePicker1Change(Sender: TObject);
  2. begin
  3.   Label1.Caption := 'Seconds: '+  IntToStr(Round(Frac(DateTimePicker1.Time)*3600*24));
  4. end;
  5.  

Vodnik

  • Full Member
  • ***
  • Posts: 210
Re: HH:MM:SS to second conversion problem
« Reply #6 on: March 21, 2018, 05:42:31 pm »
WP, thank you for excellent explanation!
It is clear now.

 

TinyPortal © 2005-2018