I have 3 variables of type DateTime or string type, in the form hh:mm:ss.
For example:
dT1="00:00:00"
dT2="20:59:59"
dT3="18:04:21"
How can I perform the following comparison?
dT1<= dT3 <= dT2 ??
Your example show String not DateTime. I put your strings in and array called TimeStrings. Then I created a List of TimeSpan. Looping through the strings I split each string on the colon, then created a new TimeSpan and added it to the list. I used the .Max method of the list to get the highest value in the list.
Private Sub OpCode()
'Constructor TimeSpan(Int32, Int32, Int32)
Dim dT1 = "00:00:00"
Dim dT2 = "20:59:59"
Dim dT3 = "18:04:21"
Dim TimeStrings = {dT1, dT2, dT3}
Dim Spans As New List(Of TimeSpan)
For Each s In TimeStrings
Dim Splits = s.Split(":"c)
Dim span As New TimeSpan(CInt(Splits(0)), CInt(Splits(1)), CInt(Splits(2)))
Spans.Add(span)
Next
Dim HighestValue = Spans.Max
MessageBox.Show(HighestValue.ToString)
End Sub
You can use the TimeSpan.Parse(), ParseExact(), TryParse() or TryParseExact() to convert the string to a TimeSpan value. The comparison is straightforward after that:
Add your string values to a collection (an Array or List of strings).
Dim dTs As String() = {"00:00:00", "23:59:59", "20:59:59", "23:10:21", "18:04:21"}
Dim max As TimeSpan = dTs.Select(
Function(s) TimeSpan.ParseExact(s, "hh\:mm\:ss", CultureInfo.InvariantCulture)).Max()
max will be 23:59:59
Of course you can order the TimeSpan value, in ascending order here:
Dim orderedTimeSpans =
dTs.Select(Function(s) TimeSpan.ParseExact(s, "hh\:mm\:ss", CultureInfo.InvariantCulture)).
OrderBy(Function(ts) ts).ToList()
orderedTimeSpans.ForEach(Sub(ts) Console.WriteLine(ts))
Which prints:
00:00:00
18:04:21
20:59:59
23:10:21
23:59:59
With TryParseExact(), if you're not sure whether the format is may not be correct (possibly, because the source of the values is not reliable - User input, for example):
Dim parsed As TimeSpan
Dim max As TimeSpan =
dTs.Select(Function(s) TimeSpan.TryParseExact(s, "hh\:mm\:ss",
CultureInfo.InvariantCulture, parsed)).Max(Function(t) parsed)
This also returns 23:59:59.
If one of the values cannot be parsed, it won't be evaluated by the Max() method.
E.g., if this is the input string "23.59:59", InvariantCulture and the format specified won't allow to return a valid TimeSpan, so the max value will be 23:10:21 instead.
The same, using TryParseExact(), but in extended form (using a loop):
Dim maxValue As TimeSpan = New TimeSpan()
Dim parsed As TimeSpan = New TimeSpan()
For Each value As String In dTs
If TimeSpan.TryParseExact(value, "hh\:mm\:ss", CultureInfo.InvariantCulture, parsed) Then
maxValue = If(TimeSpan.Compare(maxValue, parsed) > 0, maxValue, parsed)
End If
Next
You can try something like this:
Dim dT1 As DateTime = New DateTime(2020, 1, 1, 0, 0, 0) ' 00:00:00
Dim dT2 As DateTime = New DateTime(2020, 1, 1, 20, 59, 59) ' 20:59:59
Dim dT3 As DateTime = New DateTime(2020, 1, 1, 18, 04, 21) ' 18:04:21
If dT1 <= dT3 <= dT2 Then
'your code
End If
Hope, it helps :)
Related
I need to get a local timezone datetime from the following XML elements:
<TransactionDate>20191202</TransactionDate>
<TransactionTime>234026</TransactionTime>
<TransactionTimezone>UTC-06:00:00</TransactionTimezone>
My local UTC offset is -05:00:00. After getting TransactionDate and TransactionTime into td and tt Date variables, I can build a Datetime like this:
Dim ldDate As New Date(td.Year, td.Month, td.Day, tt.Hour, tt.Minute, tt.Second)
I could parse out the '-06' from TransactionTimeZone and determine that I need to add 1 hour to ldDate, but there must be a more elegant way. Any ideas?
I wrote a small procedure that returns a DateTime in the local TimeZone from a DateTime in an originating TimeZone:
Public Function P_ConvertToLocalDatetime(ByVal aOriginDateTime As Date,
ByVal aOriginTimeZone As String,
ByRef aLocalDateTime As Date) As Boolean
Try
Dim liHour As Integer = CInt(Strings.Mid(aOriginTimeZone, 4, 3))
Dim liMinute As Integer = CInt(Strings.Mid(aOriginTimeZone, 8, 2))
Dim liSecond As Integer = CInt(Strings.Right(aOriginTimeZone, 2))
With aOriginDateTime
Dim offset As New DateTimeOffset(.Year, .Month, .Day, .Hour, .Minute, .Second, New TimeSpan(liHour, liMinute, liSecond))
aLocalDateTime = offset.LocalDateTime
End With
Return True
Catch ex As Exception
Return False
End Try
End Function
I'm calling it with this:
Dim lLocalDateTime as Date
If Not P_ConvertToLocalDatetime(aTransactionDatetime,
aTransactionTimezone,
aLocalDateTime) Then
Throw New Exception("Unable to convert TransactionDatetime to local time")
End If
... where aTransactionTimezone is of type String with a value like "UTC-6:00:00".
If you have transactions from all the world this might help you to use as a base and working on to improve.
Private Function FromWorldTimeToMyLocalTime(noSpacesDateTimeTransaction As String, transactionZoneString As String) As Date
Dim transactionDtTime As Date = Date.ParseExact(noSpacesDateTimeTransaction, "yyyyMMddHHmmss", Globalization.CultureInfo.InvariantCulture)
Return DateAndTime.DateAdd(DateInterval.Hour, TimeZoneInfo.FindSystemTimeZoneById(transactionZoneString).BaseUtcOffset.TotalHours, transactionDtTime)
End Function
Usage (Here the example shows a transaction is done by Hawai):
‘Here is your complete string as you have in your xml tags (date + time) it’s presumed the transaction is come by Hawai
Dim myDateTimeFromTransactionTime As String = FromWorldTimeToMyLocalTime("20191202234026", "Hawaiian Standard Time").ToString
Console.WriteLine("MyTime from transaction is " & myDateTimeFromTransactionTime)
To get all timezone infos you can use this to have an idea.
Dim timeZones As ReadOnlyCollection(Of TimeZoneInfo) = TimeZoneInfo.GetSystemTimeZones()
For Each timeZoneInfo As TimeZoneInfo In timeZones
Console.WriteLine(CStr(timeZoneInfo.Id) & " " & CStr(timeZoneInfo.BaseUtcOffset.TotalHours))
Next
How can i sort the string date in list of string?
Input :
2019/5/9, 2019/5/13, 2019/5/14,2019/5/17,2019/5/19,2019/5/15,2019/5/18
Expected Output :
2019/5/9, 2019/5/13, 2019/5/14,2019/5/15,2019/5/16,2019/5/17,2019/5/18
My Code :
Dim Mytargetlist As String = ""
Dim list As New List(Of String)
Mytargetlist = p(1) + "/" + p(2) + "/" + p(3)
list.Add(Mytargetlist)
'list.Sort()
Dim result As List(Of String) = list.Distinct().ToList
If Session("mydata") Is Nothing Then
Session("mydata") = New ArrayList
End If
TryCast(Session("mydata"), ArrayList).Add(result.ToArray())
If you want to sort a List of dates , why not using a List(of Dates) ?
Dim list As new List(of Date)
list.add(New Date(2019,5,9))
list.add(New Date(2019,5,9))
list.add(New Date(2019,5,01))
list.add(New Date(2019,5,25))
list.add(New Date(2019,5,13))
list.add(New Date(2019,5,30))
list.add(New Date(2019,5,9))
list.Sort()
Dim myFormat = "dd/MM/yyyy"
For Each item As Date In list
Console.WriteLine(item.ToString(myFormat))
Next
Output:
01/05/2019
09/05/2019
09/05/2019
09/05/2019
13/05/2019
25/05/2019
30/05/2019
To answer the question as asked, you can call the overload of Sort that takes a Comparison(Of T) delegate and provide a Lambda that compares Strings as Dates:
list.Sort(Function(s1, s2)
Dim d1 As Date
Dim d2 As Date
If Date.TryParse(s1, d1) AndAlso Date.TryParse(s2, d2) Then
'Both values convert so compare chronologically.
Return d1.CompareTo(d2)
End If
'At least one value does not convert so consider them equivalent.
Return 0
End Function)
That converts each value to an actual Date for the purposes of comparison. If you want to do something specific when only one value converts successfully, e.g. invalid values always come last, you can implement that too.
That said, unless you have a very good reason for storing dates in Strings, you really ought to be using Date values in the first place.
Please help me first before giving me a bad feedback.
I need to add two time from text box. But when I'm adding it only the minute was adding and not the hours.
Dim dt As DateTime = TxtDTEAP.Text
Dim wt As DateTime = TxtWTEAP.Text
Dim totalspan As New TimeSpan
Dim result As New DateTime
result = dt.AddMinutes(wt.Minute)
Me.TxtTRTEAP.Text = result
For example, the txtWTEAP.Text = 1:30 and txtDTEAP.Text = 2:50 the result should be 4:20 but the result showing on this code is 1:20 only.
Thank you so much!
Split the strings in the TextBoxes into an array. The first element will contain the hours and the second element will contain the minutes. The c following the split character tells the compiler this is a char not a string.
Use the constructor of the TimeSpan structure to create TimeSpans. The constructor takes 3 arguments, Hours as Integer, Minutes as Integer and Seconds as Integer.
Finally, we can do the addition.
Then display the result using .ToString with a format string. The \ is and escape character so it doesn't think the : is something else.
Private Sub GetTotalTime()
Dim parseTime1() As String = TxtDTEAP.Text.Split(":"c)
Dim parseTime2() As String = TxtWTEAP.Text.Split(":"c)
Dim dt As TimeSpan = New TimeSpan(CInt(parseTime1(0)), CInt(parseTime1(1)), 0)
Dim wt As TimeSpan = New TimeSpan(CInt(parseTime2(0)), CInt(parseTime2(1)), 0)
Dim result As TimeSpan = dt + wt
TxtTRTEAP.Text = result.ToString("h\:mm")
End Sub
I have 2 aspx calendar(AbsenceStartDateCal & AbsenceEndDateCal) which will pass the date value to textbox with .cs codes as follow:
Protected Sub AbsenceEndDateCal_SelectionChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles AbsenceEndDateCal.SelectionChanged
Dim date2 As DateTime = New System.DateTime
date2 = AbsenceEndDateCal.SelectedDate
tbAbsenceEndDate.Text = date2.ToString("dd/MM/yyyy")
End Sub
In my pageload, i want to count no.of days to display as a label btw the 2 textbox value. I tried with the following code but it doesn't work with this error "String was not recognized as a valid DateTime."
Dim startDate As DateTime = Convert.ToDateTime(tbAbsenceStartDate.Text)
Dim endDate As DateTime = Convert.ToDateTime(tbAbsenceEndDate.Text)
Dim ts As New TimeSpan
ts = endDate.Subtract(startDate)
lblnoOfDays.Text = ts.Days
So i am not sure cos im new to VB. Any help would be greatly appreciated.
You can use ParseExact method and specify the formatting you want.
You get invalid formatting because you are probably trying to set day or month values which exceed the range defined under the current formatting.
Example:
Dim startDateString = "12/01/2015"
Dim endDateString = "14/01/2015"
Dim startDate = DateTime.ParseExact(startDateString, "dd/mm/yyyy", CultureInfo.InvariantCulture)
Dim endDate = DateTime.ParseExact(endDateString, "dd/mm/yyyy", CultureInfo.InvariantCulture)
Dim ts As New TimeSpan
ts = endDate.Subtract(startDate)
Dim dayDiff = ts.Days
For converting number of seconds to DateTime, in VB .NET, I use the following code:
Dim startDate As New DateTime(1970, 1, 1)
Dim targetDate As DateTime
Dim noOfSeconds As Integer = DataInSeconds
targetDate = startDate.AddSeconds(noOfSeconds)
where DataInSeconds is an Integer containing the number of seconds (starting from 1/1/1970)
This works good. But I don't know how make the inverse conversion. (from DateTime to number of seconds). Anyone can help me?
When you subtract DateTime instances from each other, you get a TimeSpan - you can use this to get the number of seconds:
Dim startDate As New DateTime(1970, 1, 1)
Dim noOfSeconds As Integer
noOfSeconds = (currentDate - startDate).TotalSeconds
1/1/1970 is the Unix epoch. Beware that it is a UTC date, you cannot ignore that in conversions. Thus:
Module DateConversion
Public ReadOnly Property Epoch() As DateTime
Get
Return New DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
End Get
End Property
Public Function FromUnix(ByVal seconds As Integer, local As Boolean) As DateTime
Dim dt = Epoch.AddSeconds(seconds)
If local Then dt = dt.ToLocalTime
Return dt
End Function
Public Function ToUnix(ByVal dt As DateTime) As Integer
If dt.Kind = DateTimeKind.Local Then dt = dt.ToUniversalTime
Return CInt((dt - Epoch).TotalSeconds)
End Function
End Module
Watch out for ToUnix(), the DateTimeKind may be unspecified, as it was in your snippet. Consider using DateTimeOffset instead to make it unambiguous. And be sure to do something reasonable in 2038 when all of this comes tumbling down.
Label1.Text = New DateTime(1970, 1, 1, 0, 0, 0,
DateTimeKind.Utc).AddSeconds(CLng(TextBox1.Text) / 1000)
Make a textbox and a button and a label, put this code into the button and depending if you're using microseconds (keep the /1000) or seconds (delete the /1000) will show you the date/time etc.
Public Function Date2Unix(ByVal vDate As Date) As Long
Return (vDate - #1970/01/01#).TotalSeconds
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
MsgBox(Date2Unix(Now()))
End Sub