Android Question Converting minutes to Days

trueboss323

Active Member
Licensed User
I have a label value 1859 in minutes and I would like to convert it to something like 1 day 6 hours and 59 minutes.
Can anyone help, please?
 

sorex

Expert
Licensed User
B4X:
Dim m As Int
m=1859*DateTime.TicksPerMinute
Log ( Floor(m / DateTime.TicksPerDay) & " " & (Floor(m / DateTime.TicksPerHour ) Mod 24) & " " & ((m / DateTime.TicksPerMinute) Mod 60) )
there might be better options tho
 

Mahares

Well Known Member
Licensed User
How about this using dateutils for a solution. Let us hope Erel gives us his blessing:
B4X:
Dim m As Long = 1859*DateTime.TicksPerMinute
Dim p As Period = dateutils.PeriodBetween(0,m)
Log(p.Days & " day " & p.Hours & " hrs " & p.Minutes & " min")  'yields 1 day 6 hrs 59 min
 

Erel

Administrator
Staff member
Licensed User
For small ranges your code is correct. However there are two mistakes which will break it with larger ranges:
1. The simple one is that you need to use PeriodBetweenInDays instead of PeriodBetween (as we are not interested in months).
2. There is another mistake in this code which is not really significant in this case however in other cases it can be more significant.

To prove it check your code (after you fix point number one) with this value: 24000000
It will not return the correct value. I tested it with timezone set to Israel timezone. Different timezones will behave differently. However you will be able to find incorrect values for all timezones with day light saving periods.

The correct code:
B4X:
Sub Activity_Create(FirstTime As Boolean)
   Log(IncorrectMinutesToNiceString(2400000))
   Log(CorrectMinutesToNiceString(2400000))
End Sub

Sub IncorrectMinutesToNiceString(minutes As Int) As String
   Dim p As Period = dateutils.PeriodBetweenInDays(0,minutes * DateTime.TicksPerMinute)
   Return $"${p.Days} days, ${p.Hours} hours and ${p.minutes} minutes"$
End Sub

Sub CorrectMinutesToNiceString(minutes As Int) As String
   Dim t As Long = minutes * DateTime.TicksPerMinute
   Dim  days, hours, minutes As Int
   days = t / DateTime.TicksPerDay '(24 hours day)
   hours = (t Mod DateTime.TicksPerDay) / DateTime.TicksPerHour
   minutes = (t Mod DateTime.TicksPerHour) / DateTime.TicksPerMinute
   Return $"${days} days, ${hours} hours and ${minutes} minutes"$
End Sub
The explanation:
Dates are complicated.
There are two different concepts related to dates:

- Time instance - A specific point in time: January 1st, 2010 08:00 GMT, another example: 2 days after January 1st, 2010 08:00.
- Period - For example 1000 minutes. A period by itself is not tied to any specific time instance

It is a mistake to tie a period to any specific time instance unless this is what we want to do. Your code implicitly ties the period to 1/1/1970 00:00.
 

Mahares

Well Known Member
Licensed User
To prove it check your code (after you fix point number one) with this value: 24000000
Here is the code using PeriodBetweenInDays and PeriodBetween EST zone: Both yield the same correct result. Where is the problem my friend?
B4X:
Dim m As Long = 24000000
   Dim p As Period = dateutils.PeriodBetween(0,m)
    Log(p.Days & " day " & p.Hours & " hrs " & p.Minutes & " min")  'yields 0 day 6 hrs 40 min
B4X:
Dim m As Long = 24000000
    Dim p As Period = dateutils.PeriodBetweenInDays(0,m)
    Log(p.Days & " day " & p.Hours & " hrs " & p.Minutes & " min")  'yields 0 day 6 hrs 40 min
 
Top