Calculation of travel allowances per second / Cálculo de dietas de viaje por segundo - Forum

Forum Navigation
You need to log in to create posts and topics.

Calculation of travel allowances per second / Cálculo de dietas de viaje por segundo

Let's see if someone can help me with this problem.

In a company, an operator goes on a trip abroad. For leaving the country, he charges a diet that varies according to the month.

  • If the month has 30 days or less (February), the per diem is €81.28
  • If the month has 31 days, the per diem is €80.16

I want to know how much he charges per second from the day he leaves until the present moment.

For example, if he leaves on a trip on July 08, 2021 at 07:00:00, I need to know how much he has earned so far by adding what he has earned in each second since he left.

Calculating the seconds between two dates is easy. The problem here is to calculate how much each second is worth according to the month.

In the example, it would be necessary to add what an operator charges for each second from 07:00:00 on July 08, 2021 until the end of the month (which has 31 days), then it would be necessary to add what he charges in each second of the August (31 days), September (30 days), October (31 days), November (30 days), December (31 days) and until now, in January (31 days).

Any ideas?

-----------------------------------------------------------------------------------------------------

A ver si alguien es capaz de echarme una mano con este problema.

En una empresa, un operario sale de viaje al extranjero. Por salir del país, cobra una dieta que varía según el mes.

  • Si el mes tiene 30 días o menos (Febrero), la dieta es de 81,28€
  • Si el mes tiene 31 días, la dieta es de 80,16€

Yo quiero saber cuanto cobra por segundo desde el día que se va hasta el momento actual.

Por ejemplo, si sale de viaje el día 08 de julio de 2021 a las 07:00:00 necesito saber cuanto ha cobrado hasta ahora mismo sumando lo que ha cobrado en cada segundo desde que se fue.

Calcular los segundos entre dos fechas es fácil. El problema aquí es calcular cuanto vale cada segundo según el mes.

En el ejemplo, habría que sumar lo que cobra un operario por cada segundo desde las 07:00:00 del 08 de julio de 2021 hasta final del mes (que tiene 31 días), luego habría que sumar lo que cobra en cada segundo del mes de agosto (31 días), los de septiembre (30 días), octubre (31 días), noviembre (30 días), diciembre (31 días) y hasta ahora mismo, en enero (31 días).

Alguna idea?

@cn_iceman

I am not sure why the per diem is lower for months with the most days ... perhaps a typo ? ... but let us use your numbers for now.

Adding the per diem numbers for whole months is easy.

What I can not tell is how partial months are handled ?

a) in your example, is the per diem for July (31 days) €80.16 or a fraction of it that is proportional to the seconds from July 08 7 am to midnight July 31 ?

b) at the other end, is the per diem a portion of the time from o0:00:00 am January 01 to ...

- the current time ?
- midnight today ?
- midnight at the end of this month ?

I look forward to your response.

CN_Iceman has reacted to this post.
CN_Iceman

Hi @gaev

The money that the operator earns per day is correct. Months with 31 days charge a little less. This is due to a calculation that is obtained from a percentage of his monthly salary. It's not a typo.

Adding the per diem numbers for whole months is easy.

Of course, it is very simple. If I want to calculate how much an operator earns in a second of a month with 31 days, the calculation would be:

€80.16 / 24 hours = €3.34 per hour
€3.34 / 60 minutes = €0.05566667 per minute
€0.05566667 / 60 seconds = €0.00092778 per second

The same to calculate how much the operator earn per second in a month with 30 or fewer days:

€81.28 / 24 hours = €3.38666667 per hour
€3.38666667 / 60 minutes = €0.05644444 per minute
€0.05644444 / 60 seconds = €0.00094074 per second

What I can not tell is how partial months are handled ?

Now that I know how much he earns per second, I have to calculate from the start of the trip until now, at this very moment, how much money he has accumulated, adding what he has earned every second.

The operation has to be in real time. That is, a subroutine that is updated every second.

The real problem is that you have to tell the subroutine that the seconds of July, August, October, December and January are worth "x" and that the seconds of September and November are worth "y". All this added up gives me as a result the accumulated money that the operator is earning since he left on his trip until now, at this precise second.

The idea is to have an Application running in real time, in which every second tells you how much money you have earned since you left on your trip.

b) at the other end, is the per diem a portion of the time from o0:00:00 am January 01 to ...

- the current time ?
- midnight today ?
- midnight at the end of this month ?

The travel allowance (per diem) is what the operator earns each day, from 00:00:00 to 23:59:59.

I don't know if I have explained myself well now.

Thanks for trying to help me.

@cn_iceman

Thank you for the details.

The travel allowance (per diem) is what the operator earns each day, from 00:00:00 to 23:59:59.
I don't know if I have explained myself well now.

I am still unsure about the partial (first and last) months ... is the amount for partial days 'a fraction of the daily rate' or 'the full rate for those days' ?

Continuing with your example, can you show a similar calculation for ...

- July ? i.e. is it €0.00092778 times "the number of seconds from 7:00:00 on July/08 to midnight on July/31 ... or the full day rate for the first (partial) day ?

- the current (partial) month ? i.e. from 00:00:00 of January/01 to the current date/time ... or the full day rate for today ?

a) the calculation for full months is straightforward; have a list of the months along with the days (or the total number of seconds) in that month ... for each month, do a running total of amount and seconds.

b) for partial months, assuming that the amount is proportionate with the number of seconds ...

- calculate the number of eligible seconds in that month (this is probably where you need some help)
- accumulate this number of seconds
- multiply this number of seconds by the 'per second' rate for this month, to arrive at the amount for this month
- accumulate this amount

Now, divide the accumulated amount by the accumulated seconds.

 

If the amounts are not proportionate to the partial days (i.e. daily rate for partial days), let us know.

Also, if you need assistance with calculation of seconds in a partial month, let us know.

CN_Iceman has reacted to this post.
CN_Iceman

Hi again @gaev

I am still unsure about the partial (first and last) months ... is the amount for partial days 'a fraction of the daily rate' or 'the full rate for those days' ?

The operator will earn the same amount every day according to the month. Even if the day is not complete.

A very clear example here could be that if the operator leaves for a trip at 23:59 of the current day, he would earn it in full, even if he only worked 1 minute of that day... even 1 second.

This may seem silly, but it is virtually impossible to work for only 1 minute, because he does not control the vehicle he is traveling in. I'm talking about a ship. The boat leaves the port at 07:00.

Clarify that whether you leave at 07:00 or 14:00, the operator already earns 1 full day.

Continuing with your example, can you show a similar calculation for ...

- July ? i.e. is it €0.00092778 times "the number of seconds from 7:00:00 on July/08 to midnight on July/31 ... or the full day rate for the first (partial) day ?

- the current (partial) month ? i.e. from 00:00:00 of January/01 to the current date/time ... or the full day rate for today ?

a) the calculation for full months is straightforward; have a list of the months along with the days (or the total number of seconds) in that month ... for each month, do a running total of amount and seconds.

Let's make a calculation of how much you will charge on the day of departure.

We know that it is July, and that this month has 31 days, therefore it should charge €80.16 per day.

Logical conclusion, today the operator will earn €80.16... that's for sure. Now let's see if it's 07:00:00 how much he has won in seconds.

As I put in the example above, we know that the operator will earn €0.00092778 every second:

€80.16 / 24 hours = €3.34 per hour
€3.34 / 60 minutes = €0.05566667 per minute
€0.05566667 / 60 seconds = €0.00092778 per second

If the trip starts at 07:00:00 we should calculate how many seconds have elapsed from 00:00:00 of that day, until 07:00:00 of the same day and multiply them by €0.00092778

7 hours * 60 minutes * 60 seconds = 25200 seconds.
25200 seconds * €0.00092778 = €23.38 (rounding)

In this way, when I start the stopwatch at 07:00:00, the operator would already have €23.38 earned in his pocket.

b) for partial months, assuming that the amount is proportionate with the number of seconds ...

- calculate the number of eligible seconds in that month (this is probably where you need some help)
- accumulate this number of seconds
- multiply this number of seconds by the 'per second' rate for this month, to arrive at the amount for this month
- accumulate this amount

Now, divide the accumulated amount by the accumulated seconds.

If the amounts are not proportionate to the partial days (i.e. daily rate for partial days), let us know.

Here, I do not understand very well what you want to tell me.

 

Also, if you need assistance with calculation of seconds in a partial month, let us know.

I can calculate how many seconds there are between hours, no problem.
I can calculate how many seconds there are from 07:00:00 on July 08 (day of departure) to the current moment.

The problem is that I don't see how to tell the program that some seconds have the value of €0.00092778 (if the month has 31 days) and instead other seconds have the value of €0.00094074 (if the month has 30 or fewer days) .

I really appreciate you trying to help me.

@cn_iceman

The operator will earn the same amount every day according to the month. Even if the day is not complete.

Thank you again for the clarification

Here, I do not understand very well what you want to tell me.

It was not meant to seek clarification, but suggested logic for the way to do the calculation.

I can calculate how many seconds there are between hours, no problem.
I can calculate how many seconds there are from 07:00:00 on July 08 (day of departure) to the current moment.

OK

The problem is that I don't see how to tell the program that some seconds have the value of €0.00092778 (if the month has 31 days) and instead other seconds have the value of €0.00094074 (if the month has 30 or fewer days).

As I eluded in the logic in my earlier post, it would be best to loop from month to month, and accumulate seconds and amounts as you progress.

Further, it would be best to deploy a small database (neoDBPro ?) that is pre-populated with the following fields ...

Year+Month, DaysInMonth, RatePerDay

... and use it as you cycle through the months ... slightly different logic for partial (first, last) months ... once you get the accumulated days and amounts, it is simple to calculate amount per second.

Let me know if you want details of the logic.

luishp and CN_Iceman have reacted to this post.
luishpCN_Iceman

@gaev

Hi again.

That approach with a database seems fine to me. I can prepare a Database without problem, but... what if the program is executed later in time? That is, I can generate a database that tells me how many days each month has, but I cannot make an infinite database.

I have a plugin with a command that can tell me how many days each month has (I think David Esperalta's npUtil).

Anyway, with the idea of ​​the Database you have given me a clue. I think that from the beginning I have been trying to do the calculations by accumulating the money obtained according to what it charges per second according to the month, when in reality, I must prioritize the days of the month and then calculate the seconds. I have to investigate here.

Let's see, if I run the program mentally, it would be something like this:

I give the program a start date and time: July 08, 2021 at 07:00:00... as the end date is the current time, January 31, 2022 at 19:15:00 or so.

(At this point, I was calculating the number of seconds from the Start Date to the End Date... I now think that is not the correct way.)

I guess the process would be something like:
- How many days does the starting month have? 31
- How much does the start month charge? €80.16 per day.
- How many days are left until the end of the month? 24
- We increase by 1 the month. August. How many days does it have? 31
- How much do you charge for the month of August? €80.16 per day.
- ......
- So on until reaching the current month.
- How many days does the current month have? 31
- How much do you charge the current month? €80.16 per day.

I think that it would be necessary to control when it goes from month 12 (December) to month 1 (January).

I don't know... I have to try.

@cn_iceman

That is, I can generate a database that tells me how many days each month has, but I cannot make an infinite database.

Two ways to address this ...

a) Set it up for 5 to 10 years (60 to 120 months) ... then update every 4 to 9 years years.

b) do not include the year ... months in a year are '31' or '30 or less' every year

I think that it would be necessary to control when it goes from month 12 (December) to month 1 (January).

Using your example (July 2021 to January 2022), setup ...

Loop "0" "[numberOfCycles" "[relativeMonthNumber]" ... 7 months less 1
   Math "[FirstMonth]+[relativeMonthNumber]" "0" "[thisMonth]"
   If "[thisMonth]" "=" "13"
      Math "[thisMonth]-12" "0" "[thisMonth]"
   EndIf
   ... lookup record for [thisMonth]
   etc. etc.
EndLoop

a) you will have to calculate the "[numberOfCycles]" in the Loop (6 in your example)

b) gets more complicated if you are going to cycle through more than 12 months ... does it ever get this long ?

 

 

luishp, Vadim and CN_Iceman have reacted to this post.
luishpVadimCN_Iceman

Hello @gaev

Impossible to answer before... today is being a crazy day.

Well, I have reviewed your proposal and I like it. I think I can have something clear on the matter. As soon as I can, I'll do some tests and I'll report here how it goes, but I think we have it.

Again thank you very much for the help.

Te adjunto mi PUB con la solución te he desarrollado (las fechas iniciales he puesto un año bisiesto y he visto hace bien el incremento fechas).

Debes usar el PlugIn de David Esperalta "npUtil".

También he puesto un Excel para verificar el Cálculo.

Uploaded files:
  • You need to login to have access to uploads.
luishp, Vadim and CN_Iceman have reacted to this post.
luishpVadimCN_Iceman

Muchas gracias @rafamacor

Esta tarde lo pruebo en casa y te digo, pero seguro que funciona. Esta comunidad de VisualNEO es fantástica, siempre hay alguien ayudando.

Os debo unas cervezas!

 

@cn_iceman el PUB está comentado, pero aún así te detallo lo que hace:

Va analizando desde la fecha inicial hasta la final a día a día si el día es de un mes de 31 o de menos días y va sumando la dieta correspondiente

Luego analiza la fecha inicial y ve si corresponde a un mes de 31 o menos y le quita la parte proporcional desde el comienzo del día hasta la hora inicial

Por último hace lo mismo con al fecha final quitándole lo que resta de día hasta media noche

 

Total= dietas de días enteros de meses de 31, 3o, 29,28  - comienzo del día inicial - lo que resta del día final

Hola @rafamacor

Casi lo tenemos!!! jejejeje...

A ver, necesito que la rutina se ejecute cada segundo, así que he puesto un Timer que llama a la rutina cada segundo. La fecha y hora final tienen que ser el momento actual, así que he hecho que las variables [DIA_FINAL] y [HORA_FINAL] se actualicen automáticamente tomando la fecha y hora actuales del reloj del sistema y añadiéndoles un 0 (cero) a la izquierda si es necesario (tanto para la fecha como para la hora).

Funciona perfectamente si le pongo como fecha inicial cualquiera dentro de 2022. El cálculo es perfecto.

En cambio, si pongo como fecha de inicio una fecha anterior al año en curso, por ejemplo 07/10/2021, al contar, la variable [DIA_VA] se queda en 01/01/2022 siempre y falta dinero por sumar.

A ver si doy con el problema.

De todas formas, muchísimas gracias tanto a ti como a @gaev. Lo de las cervezas sigue en pié.

Un saludo.

 

@cn_iceman, te adjunto nuevo PUB,  le he puesto un Timer para que cada 3 segundos calcule las Dietas.

Uploaded files:
  • You need to login to have access to uploads.

Hola @rafamacor

Si, yo también le puse un Timer. Mejor con el de 3 segundos.

Sigue fallando lo que te comentaba antes. Incluso si le pones como fecha de inicio 01/01/2022, no salen los cálculos. La variable [DIA_VA] se queda en 01/01/2022 siempre y falta dinero por sumar.

Sigo investigando.

@cn_iceman, a mí me funcionan el ejemplo inicial como este con el Timer bien (como veras [DIA_VA] llega hasta hoy como tiene que hacerlo, no sé que puede estar ocurriendo.

Te adjunto captura de la PUB con las variables en tiempo ejecución/depuración y de la comprobación del Excel.

Uploaded files:
  • You need to login to have access to uploads.
Vadim has reacted to this post.
Vadim

Hola de nuevo @rafamacor

No tengo ni idea de lo que ha pasado, pero hoy todo funciona perfectamente. La variable [DIA_VA] ayer se quedaba en 01/01/2022 y hoy no.

Te juro que no entiendo nada. He intentado volver a reproducir el error, pero sin éxito. He probado varias fechas de este año, del año pasado, incluso más lejos y funciona perfectamente. Me tiene mosqueado lo de que ayer no funcionase bien.

Voy a integrar tu rutina en mi programa y a añadirle lo que cobran otros operarios (según su posición en la empresa), pero no creo que haya problema.

Muchas gracias por la ayuda. Gracias a ti también @gaev

 

@gaev

@rafamacor

Programa funcionando perfectamente. Ya está entregado al usuario que lo pidió.

Es gratis ¿eh? jajajaja

Le he puesto un contador a 5 segundos, ya que tiene que actualizar los datos de bastante gente.

Creo que el error fue debido a un cambio que hice en la forma de contar el tiempo... Cambié npSecondsBetween por npMillisecondsBetween porque he puesto una variable que muestra los días, horas, minutos y segundos transcurridos desde el inicio.

Aproveché una subrutina que tenía por ahí hecha, para controlar tiempos de procesos (que suelen ser de horas o minutos), y parece ser que si hay días... hace cosas raras... incluso da error, al intentar convertir un número de milisegundos muy grande...

Bueno, pues ya está. Podemos dar el tema por concluido.

Agradezco nuevamente la ayuda recibida.

Un saludo.