Wish DateUtils .Period type total values

Jeffrey Cameron

Well-Known Member
Licensed User
Longtime User
It would be nice if the .Period data type from the DateUtils library had the total values for each of the periods in the type (TotalMinutes, TotalHours, TotalSeconds, etc.) as Vb.NET does.

And, yes, I know I could do something like:
B4X:
plMinutes = poPeriod.Minutes + (poPeriod.Hours * 60) + (poPeriod.Months * 43800) + (poPeriod.Years * 525600)
I'm just lazy
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
And, yes, I know I could do something like:
That's far from being correct.

It is not possible to convert a period to hours or any other time interval without a specific time instance. With a time instance you can call AddPeriod and then calculate the difference measured in milliseconds. From this value you can calculate the seconds, hours and minutes.
 

Jeffrey Cameron

Well-Known Member
Licensed User
Longtime User
The "ballpark" value I was citing above was just an example that you can get the totals (just subtracting the two long values will give you total milliseconds, you can do any kind of math you want from that point).

Since you're already computing the period in DateUtils, you have access to all of the information needed. I was just hoping you could extend the type definition to include the sundry totals that are available; similar to those in the TimeSpan structure in Vb.NET:
B4X:
' VB.NET CODE : Define two dates.
Dim date1 As Date = #1/1/2010 8:00:15AM#
Dim date2 As Date = #8/18/2010 1:30:30PM# ' Calculate the interval between the two dates.
Dim interval As TimeSpan = date2 - date1
Console.WriteLine("{0} - {1} = {2}", date2, date1, interval.ToString())
' Display individual properties of the resulting TimeSpan object.
Console.WriteLine(" {0,-35} {1,20}", "Value of Days Component:", interval.Days)
Console.WriteLine(" {0,-35} {1,20}", "Total Number of Days:", interval.TotalDays)
Console.WriteLine(" {0,-35} {1,20}", "Value of Hours Component:", interval.Hours)
Console.WriteLine(" {0,-35} {1,20}", "Total Number of Hours:", interval.TotalHours)
Console.WriteLine(" {0,-35} {1,20}", "Value of Minutes Component:", interval.Minutes)
Console.WriteLine(" {0,-35} {1,20}", "Total Number of Minutes:", interval.TotalMinutes)
Console.WriteLine(" {0,-35} {1,20:N0}", "Value of Seconds Component:", interval.Seconds)
Console.WriteLine(" {0,-35} {1,20:N0}", "Total Number of Seconds:", interval.TotalSeconds)
Console.WriteLine(" {0,-35} {1,20:N0}", "Value of Milliseconds Component:", interval.Milliseconds)
Console.WriteLine(" {0,-35} {1,20:N0}", "Total Number of Milliseconds:", interval.TotalMilliseconds)
Console.WriteLine(" {0,-35} {1,20:N0}", "Ticks:", interval.Ticks)
' The example displays the following output: ' 8/18/2010 1:30:30 PM - 1/1/2010 8:00:15 AM = 229.05:30:15
' Value of Days Component: 229
' Total Number of Days: 229.229340277778
' Value of Hours Component: 5
' Total Number of Hours: 5501.50416666667
' Value of Minutes Component: 30
' Total Number of Minutes: 330090.25
' Value of Seconds Component: 15
' Total Number of Seconds: 19,805,415
' Value of Milliseconds Component: 0
' Total Number of Milliseconds: 19,805,415,000
' Ticks: 198,054,150,000,000
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
.Net is wrong as it ignores DST changes (and probably other things as well). It is not possible to correctly convert a period (or .Net TimeSpan) to other units unless you tie it to a specific date.

See this example:
1. Set your computer time zone to Jerusalem. DST changed on March 24 (from GMT + 2 to GMT + 3). This means that on March 24 there were only 23 hours.
B4J code:
B4X:
Dim dt1 As Long = DateTime.DateTimeParse("03/24/2017", "00:00:00")
Dim dt2 As Long = DateTime.DateTimeParse("03/25/2017", "00:00:00")
Dim hoursBetween As Double = (dt2 - dt1) / DateTime.TicksPerHour
Log(hoursBetween) 'correctly prints 23
.Net:
B4X:
DateTime dt = DateTime.Parse("3/24/2017 0:00:00 AM");
  DateTime dt2 = DateTime.Parse("3/25/2017 0:00:00 AM");
  TimeSpan ts = dt2 - dt;
  Console.WriteLine(ts.TotalHours);
Incorrectly prints 24.
 

Jeffrey Cameron

Well-Known Member
Licensed User
Longtime User
You are correct in .NET, as the normal date/time interaction is always in reference to your current timezone, you have to manually account for the DST days if you are going to do the computations locally (c.f. Timezone.GetDaylightChanges(int Year) function).

However, in .NET it is quite simple to just convert to UTC prior to your calculation:
B4X:
Dim ptPreDST As Date = DateTime.Parse("3/12/2017 00:00:00 AM")  'DST day north america
Dim ptPostDST As Date = DateTime.Parse("3/13/2017 00:00:00 AM")
Dim poTS As TimeSpan = ptPostDST.ToUniversalTime.Subtract(ptPreDST.ToUniversalTime)
Debug.Print("total hours = " & poTS.TotalHours)
Will correctly print 23 hours.
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…