Operation with Delphi hours

Asked

Viewed 1,536 times

5

I was manipulating hours in Delphi and I came across the following situation:

CASE 1

horafinal := strtotime('08:00');
horaInicial := strtotime('17:00');

horaInicial := horaInicial - horafinal; //09:00
horafinal := horafinal - horafinal; //00:00

diferenca := horafinal - horaIncial; // 09:00

CASE 2

horafinal := strtotime('08:00');
horaInicial := strtotime('17:00');

horaInicial := horaInicial - horafinal; //09:00
horafinal := strtotime('23:59') + strtotime('00:01'); //00:00

diferenca := horafinal - horaIncial; // 15:00

CASE 3

horafinal := strtotime('08:00');
horaInicial := strtotime('17:00');

horaInicial := horaInicial - horafinal; //09:00
horafinal := strtotime('00:00'); //00:00

diferenca := horafinal - horaIncial; // 15:00

In my understanding this occurs, because internally he must use a datetime. Case 1 hour = today 00:00 and in Case 2 Tomorrow 00:00 and Case 3 hour = Tomorrow 00:00

Is this thinking correct? How does Delphi work with hours? Because in case 3 Delphi behaves like Case 2 and not like case 1?

  • 2

    I don’t understand what the problem is?

  • The Delphi you are using has Unit dateutils ? There are functions there that facilitate, and much, the treatment of dates.

  • @user3435518 hehe Yes, and I’m using in my project. I just went to fix a bug and checked this behavior and got curious.

  • What you have to see is that in Delphi (or Freepascal) the dates are stored as a double type, where what is left of the floating point is treated as date and what is right is treated as time. The specific coding used to do this generates a series of artifacts that are a compromise between what is most accurate and what is most efficient on the computer. You probably bumped into one of those "artifacts".

1 answer

7


Well, in all three cases you used a variable horaInicial and then horaIncial. I will assume that the i missing is a silly typing error only and not a different variable.

Behold on this page these details:

The date is set to 30 Dec 1899, one day short of the 19th century.

Warning : the date value is set to 1 day short of the end of the 19th century. Exactly Why is unclear.

Translating into Portuguese:

The date is set to 30 Dec 1899, a day before the end of the 19th century.

Care : the value of the date is set to one day before the end of the 19th century. It is unclear why.

Behold this other:

It appears that the Reason for Delphi Starting at 30 Dec 1899 is to make it as compatible as possible with Excel while at the same time not Adopting Excel’s incorrectness about Dates.

Because Tdatetime is Actually a double, you can perform calculations on it as if it Were a number. This is Useful for calculations such as the Difference between two Dates.

Translating into Portuguese:

It seems that the reason for Delphi to start on 30 Dec 1899 is to make it as compatible with Excel as possible without however adopting the incorrect Excel about dates.

Since Tdatetime is actually a double, you can perform calculations on it as if it were a number. This is useful for calculations such as differences between two dates.

That is, a TDateTime is a double where the whole part is a number of days since 12/30/1899 and the fractional part are fractions of days (hours, minutes, seconds, etc).

We will replace your variables with a, b, c and d to understand what’s going on and track the value of doubles:

In your case 1, how the question was originally:

a := strtotime('08:00'); // Valor double: 8/24
b := strtotime('17:00'); // Valor double: 17/24

c := a - a; // 00:00 // Zero
d := b - c; // 09:00 // 17/24 - 0 = 17/24. Definitivamente não é 09:00!

diferenca := c - d; // -17/24, ou seja, 17 horas antes da meia-noite do dia 30/12/1899, portanto 09:00 do dia 29/12/1899.

In case 1, as the question is now:

a := strtotime('08:00'); // Valor double: 8/24
b := strtotime('17:00'); // Valor double: 17/24

c := b - a; // 09:00 // 17/24 - 8/24 = 9/24
d := a - a; // 00:00

diferenca := d - c; // -9/24, ou seja, 9 horas antes da meia-noite do dia 30/12/1899, portanto 15:00 do dia 29/12/1899.

In case 2:

a := strtotime('08:00'); // Valor double: 8/24
b := strtotime('17:00'); // Valor double: 17/24

c := b - a; // 09:00 // 17/24 - 8/24 = 9/24
d := strtotime('23:59') + strtotime('00:01'); // 00:00 // Mas no dia 31/12/1899. Valor double: 1.

diferenca := d - c; // 15:00 // Isso dá (1 - 9/24) = 15/24, ou seja, 15:00 do dia 30/12/1899.

In case 3:

a := strtotime('08:00'); // Valor double: 8/24
b := strtotime('17:00'); // Valor double: 17/24

c := b - a; // 09:00 // 17/24 - 8/24 = 9/24
d := strtotime('00:00'); // 00:00

diferenca := d - c; // 15:00 // Isso dá (0 - 9/24) = -9/24, ou seja, 9 horas antes da meia-noite do dia 30/12/1899, portanto 15:00 do dia 29/12/1899.

Completion: The way the question is right now, all three cases give a 15:00 answer. However in case 1 of the question as it was originally, the result was 9:00 because you were doing operations in a different way.

  • Sorry, when I checked the values were really wrong, because the order was different from my original code.

  • @Priscilaalmeida You have touched the question a lot. Calm down I already update the answer.

  • 1

    @Priscilaalmeida Updated response. :)

  • @Priscilaalmeida Reply updated again. :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.