How to get duration between two times in vb .NET - vb.net

I have two times that I want to get the duration between them.
For example, 00:00:05,967 --> 00:00:08,285 that duration becomes 2.318
Thank you all for helping me.

Use TimeSpan
Dim t1 As New TimeSpan(0, 0, 0, 5, 967)
Dim t2 As New TimeSpan(0, 0, 0, 8, 285)
Console.WriteLine(t2 - t1)

Related

Does DateTime include second leap function?

In this article: Are .Net's DateTime methods capable of recognising a Leap Second?, the writer gets the answer "It (DateTime) does not include the number of ticks that are attributable to leap seconds."
However, the following code shows that .Net DateTime supports leap seconds. Could any expert explain why?
Dim GPS_Time_Base_Point As DateTime = New DateTime(1980, 1, 6, 0, 0, 0, DateTimeKind.Unspecified)
Dim A_test_time As DateTime = New DateTime(2019, 4, 16, 18, 29, 0, DateTimeKind.Unspecified)
Dim TimeSpan As TimeSpan = A_test_time - GPS_Time_Base_Point
Dim GPS_Time_At_LIGO_for_2019_4_16_18_29_0 As UInt64 = 1239474558 'https://www.andrews.edu/~tzs/timeconv/timeconvert.php
Dim DifSeconds As Integer = TimeSpan.TotalSeconds - 1239474558
Debug.Print(" Second dif:" + CDbl(DifSeconds).ToString)
The output is "Second dif:-18", which is just equal to the leap second dif for gpstime - UTC time.

MS Access 2013 - Getting unfounded Division by zero error

I have a routine that writes totals to textboxes to prevent expensive 'Dlookup' processing time.
Some of the totals produce a percentage rate so depend on a denominator.
The error seems to be due to lag of some sort because the denominators are never blank or zero. For example, as long as there are values in this database - which there are always an abundance of, these denominators will never be zero.
At any rate, here is the line that gets the error ( I get an error 11)
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim rsSP As DAO.Recordset
Set db = CurrentDb
--->Set rs = db.OpenRecordset("TOTALS_FINAL", dbOpenSnapshot)
What can I do to trap this error? It only happens occasionally and when I tell the use to restart the database (which frees up some resources) it usually corrects the problem.
Here is the SQL for TOTALS final
SELECT
"Total Program" AS BL
,TOTALS_COB_ALL_TOTALS.AFP_ AS AFP
,TOTALS_COB_ALL_TOTALS.ALLT_ AS ALLT
,TOTALS_COB_ALL_TOTALS.SP_C_ AS SP_C
,TOTALS_COB_ALL_TOTALS.SP_O_ AS SP_O
,TOTALS_COB_ALL_TOTALS.COMMITS_ AS COMMITS
,TOTALS_COB_ALL_TOTALS.OBS_ AS OBS
,TOTALS_COB_ALL_TOTALS.RA_ AS RA
,IIF([SP_C_] = 0, 0, [COMMITS_] / [SP_C_]) AS COM_SP_RATE
,IIF([SP_O_] = 0, 0, [OBS_] / [SP_O_]) AS OBS_SP_RATE
,IIF(Nz([AFP_], 0) = 0, 0, Nz([OBS_], 0) / [AFP_]) AS OB_AFP_RATE
,TOTALS_COB_ALL_TOTALS.UNC_ AS UNC
,TOTALS_COB_ALL_TOTALS.AVL_ AS AVL
,TOTALS_COB_ALL_TOTALS.ACW_ AS ACW
,7999 AS SO
FROM
TOTALS_COB_ALL_TOTALS;
The query right before it just collects totals that are used to produce the final percentages
The reason is, that IIf always evaluates both expressions even though only one is used.
So use a "double-iif" that divides by one and not zero:
,IIF([SP_C_] = 0, 0, [COMMITS_] / IIf([SP_C_] = 0, 1, [SP_C_])) AS COM_SP_RATE
,IIF([SP_O_] = 0, 0, [OBS_] / IIf([SP_O_] = 0, 1, [SP_O_])) AS OBS_SP_RATE
,IIF(Nz([AFP_], 0) = 0, 0, [OBS_] / IIf(Nz([AFP_], 0) = 0, 1, [AFP_]) AS OB_AFP_RATE

VB.NET get average from a range of values from a sortedlist (sortedlist.average)

I have a sortedlist like this;
public MeasuredValues as SortedList(Of DateTime, Double)
I throw in a bunch of values. For example;
MeasuredValues.add(New DateTime(2010, 1, 1),33)
MeasuredValues.add(New DateTime(2011, 1, 1),13)
MeasuredValues.add(New DateTime(2012, 1, 1),233)
MeasuredValues.add(New DateTime(2013, 1, 1),331)
MeasuredValues.add(New DateTime(2014, 1, 1),732)
MeasuredValues.add(New DateTime(2015, 1, 1),123)
Now I want to get the avarage of this values, say from 2011 to 2013. (ofcourse my real situation has much more values)
I've seen the sortedlist has a extension method called 'Avarage' ; https://msdn.microsoft.com/en-us/library/bb534965(v=vs.110).aspx
But I can't find any clear examples. I like VB.NET, but C# examples are also welcome...
I know I need to implement a function, but I don't know how. MSDN does not supply any example. Also, is this the best/fastest way to do it?, or is there a better alternative...
Thanks in advance...
Update:
I've tried this;
Dim MyAverage As Double = MeasuredValues.Average(Function(measure) CDate(measure.Key) >= ThisStepBeginTime And CDate(measure.Key) <= ThisStepEndTime)
But it only delivers a occasional -0,1
This 'one-line functions' are new for me, what am I doing wrong?
Update 2:
My example was a over simplefied example of the real problem. I'm trying to draw a graph, where every pixel represents a timespan. Like this;
For XCounter As Integer = 0 To MyBase.Width
Dim ThisStepBeginTime As DateTime = First.AddTicks(XCounter * TimeStep.Ticks)
Dim ThisStepEndTime As DateTime = First.AddTicks((XCounter + 1) * TimeStep.Ticks)
For Each MySerie In Me.AllSeries.Values
Dim MyAverage As Double = MySerie.Where(Function(measure) CDate(measure.Key) >= ThisStepBeginTime And CDate(measure.Key) <= ThisStepEndTime).Average(Function(measure) measure.Value)
e.Graphics.DrawLine(Pens.Red, XCounter, CInt((Me.Height / MySerie.HighestValue) * MyAverage), XCounter, 0)
Next
Next
This results in;
Sequence contains no elements
Because some of the steps don't have a value....
I think you can filter the list first and then get the average:
MeasuredValues _
.Where(Function(measure) cDate(measure.Key) >= dateFrom And cDate(measure.Key) <= dateTo) _
.Average(Function(measure) measure.Value)
REGARDING UPDATE 2:
If I understand the new issue corrently, you're getting an error on the Average if Where returns no elements. I know you can add .DefaultIfEmpty in between however I don't know how that would affect the Average function:
MeasuredValues _
.Where(Function(measure) cDate(measure.Key) >= dateFrom And cDate(measure.Key) <= dateTo) _
.DefaultIfEmpty() _
.Average(Function(measure) measure.Value)
I'm expecting the DefaultIfEmpty to return an empty element Of(DateTime, double) and thus averaging to 0

How To Declare / Store "12:00:00 AM" in a DateTime Variable? (Through military time)

I have this code:
Dim twelve_AMToday As DateTime = New DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 24, 0, 0)
But it says "Hour, Minute, and Second parameters describe an un-representable DateTime."
Of course 23, 59, 59 is read as 11:59:59 PM. I've tried 0, 0, 0 but then gives me the date only.
Thanks for any help!
You get it when you use Today
Dim twelve_AMToday As DateTime = Today
If you want to add days put this code under it.
twelve_AMToday = twelve_AMToday.AddYears(0).AddMonths(0).AddDays(1)
Try this
Dim twelve_AMToday As DateTime = New DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0)
Dim s As String = twelve_AMToday.ToLongDateString & " " & twelve_AMToday.ToLongTimeString
What you see in the debugger will be the same for the datetime, but once the datetime is converted to a string you will see that it does have the time you want. If the time is all zeroes the debugger doesn't show the time for datetimes, but it is there.

finding a time range using case statement

good evening everyone...
could anyone help me on this?
With a "time value", eg. 08:00:00...
i want to find the range that this value falls in using case statement...
i am not good in using the time format...
anyone can help?
This is just an example: (the code is not working...is just an example)
datime = Now().ToString("hh:mm:ss")
Select Case datime
Case "08:00:00" To "09:00:00"
lblRange.Text = i.ToString()
Case "09:00:01" To "09:14:59"
lblRange.Text = (i - 0.25).ToString()
Case "09:15:00" To "09:29:59"
lblRange.Text = (i - 0.5).ToString()
If you don't follow Tim's advice you can use this
Dim timeToCheck As DateTime = #7:10:00 PM#
Select Case timeToCheck.TimeOfDay
Case New TimeSpan(8, 0, 0) To New TimeSpan(9, 0, 0)
Stop
Case New TimeSpan(9, 0, 1) To New TimeSpan(9, 14, 59)
Stop
Case New TimeSpan(9, 15, 0) To New TimeSpan(9, 29, 59)
Stop
Case New TimeSpan(19, 0, 0) To New TimeSpan(19, 14, 59)
Stop
Case Else
Stop
End Select
You do NOT want to use strings.
In this case i wouldn't use the Select...Case statement, it should be used with simple conditions only. You can use an If-Else instead.
But since you're actually checking if a given time is between a range you could also use following code which uses LINQ.
First you need to define a collection which holds all ranges. You can use a List(Of YourClass) or even an array of an anoymous type:
Dim ranges = {
New With {.Start = TimeSpan.FromHours(8), .End = TimeSpan.FromHours(9)},
New With {.Start = New TimeSpan(9, 0, 1), .End = New TimeSpan(9, 14, 59)},
New With {.Start = New TimeSpan(9, 15, 0), .End = New TimeSpan(9, 29, 59)}
}
You want to compare TimeSpans, you get the current time by Date.Now.TimeOfDay.
Dim now As TimeSpan = Date.Now.TimeOfDay
Dim matchingRange = ranges.
FirstOrDefault(Function(r) now >= r.Start AndAlso now <= r.End)
Enumerable.FirstOrDefault returns the first where the time is in range or Nothing otherwise.
If matchingRange IsNot Nothing Then
lblRange.Text = String.Format("Between {0} and {1}",
matchingRange.Start,
matchingRange.End)
End If