Date and Time Difference in Minutes - vb.net

Is there any way to Display the difference between 2 different times. I currently have 2 buttons.
Sub AddButtonClick(sender As Object, e As EventArgs)
StartTime.Text = DateTime.Now.ToString()
End Sub
This generates the first timestamp
Sub EndBreakClick(sender As Object, e As EventArgs)
EndTime.Text = DateTime.Now.ToString()
DateDiff(DateInterval.Minute, Endtime, StartTime)
End Sub
This generates the second timestamp but the datediff line causes the app to crash as soon as I press the button.

You can rely on TimeSpan:
Dim elapsedTime As TimeSpan = DateTime.Parse(EndTime.Text).Subtract(DateTime.Parse(StartTime.Text))
It behaves as a normal time variable from which you can extract all the information you want. Example:
Dim elapsedMinutesText As String = elapsedTime.Minutes.ToString()
Bear in mind that the code above takes string variables as inputs (the text from your textboxes) because it performs the corresponding conversion: Convert.ToDateTime.
Regarding your code, it refers to EndTime and StartTime and these are not DateTime variables, but TextBoxes. You have to convert them (their text) into DateTime as I am doing above, that is:
DateDiff(DateInterval.Minute, DateTime.Parse(EndTime.Text), DateTime.Parse(StartTime.Text))

The DateDiff function will do it.
label1.text = DateDiff("n", DateTime.Parse(EndTime.Text), DateTime.Parse(StartTime.Text)).ToString
If your app is crashing, did you check the variable you tried to pass to it? It looks like your trying to pass the textbox to it and not the textbox.text.

Sub EndBreakClick(sender As Object, e As EventArgs)
EndTime.Text = DateTime.Now.ToString()
Dim myStartTime As DateTime? = If(DateTime.TryParse(StartTime.Text, myStartTime), myStartTime, Nothing)
Dim myEndTime As DateTime? = If(DateTime.TryParse(EndTime.Text, myEndTime), myEndTime, Nothing)
If myStartTime.HasValue AndAlso myEndTime.HasValue Then
Dim someVariable As Long = DateDiff(DateInterval.Minute, myStartTime.Value, myEndTime.Value)
' DO SOMETHING WITH THAT VARIABLE HERE
Else
' One or both of the textbox values wasn't a valid DateTime. Display an error message or something
End If
End Sub

Related

'Conversion from string "" to type 'Double is not valid.'

Just started doing Visual Basic, and am trying to make a time converter. I'm aware my code may be very inefficient or impractical, but I'm trying to make a part of the program where you type in your number of minutes into the text box as opposed to using the scrollbar. However, when the text box is empty the program crashes and throws the 'Conversion from string "" to type 'Double is not valid.' error. Code is below. The line where the error is shown is highlighted in red.
Public Class timeConverter
Private Sub scrollBar_Scroll(sender As Object, e As ScrollEventArgs) Handles scrollBar.Scroll
Dim minuteBoxInt As Integer 'Declaring variables'
Dim hourBoxInt As Integer
Dim minuteBox2Int As Integer = scrollBar.Value Mod 60
minuteBox.Text = scrollBar.Value() 'The scrollbar value will change with the minute box text'
minuteBoxInt = minuteBox.Text() 'Make the minuteBox associated with the minuteBoxInt variable'
hourBoxInt = Math.Floor(minuteBoxInt / 60) 'Rounds the decimal when the minuteBoxInt reaches 60'
hourBox.Text = hourBoxInt 'Makes the hourBox associated with the hourBoxInt variable'
minuteBox2.Text() = minuteBox2Int 'Makes the minuteBox2 associated with the minuteBox2Int variable'
End Sub
Private Sub minuteBox_TextChanged(sender As Object, e As EventArgs) Handles minuteBox.TextChanged
hourBox.Text = minuteBox.Text() / 60
End Sub
End Class```
To check user input (or lack of input) use .TryParse. Pass it a string and a variable of the type you are looking for. The .Text property of a TextBox is a string and here we have declare a variable, minutes, which will be filled with the parsed value of the string if the parse is successful. .TryParse returns a Boolean so it can be used in an If statement.
Private Sub minuteBox_TextChanged(sender As Object, e As EventArgs) Handles minuteBox.TextChanged
Dim minutes As Integer
If Integer.TryParse(minuteBox.Text, minutes) Then
hourBox.Text = (minutes / 60).ToString
Else
MessageBox.Show("Please make a valid entry in the minutes box.")
End If
End Sub

Case Statement not working with String Literals

Hi all I am trying to learn VB and am having trouble with some code I am using. I would like my program to output a specific number based on if a check box is checked using case statements but my code is not working.
Public Class frmBTPW
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles btncalc.Click
Dim dblhdr As Double
Dim dblfdr As Double
Dim dbltdr As Double
dblhdr = 24
dblfdr = 35
dbltdr = 50
Select Case "Power Wash Rental"
Case "Half Day Rental"
If chkhd.Checked = True Then
txtrc.Text = "poop"
End If
Case "Full Day Rental"
If chkFD.Checked = True Then
txtrc.Text = dblfdr
End If
End Select
End Sub
Private Function Button1_Click() As CheckBox
Throw New NotImplementedException
End Function
End Class
Help would be greatly appreciated.My code isn't outputting anything in the text-box.
Beyond case statements, respectfully I think you should read up on the distinction between a literal value and a variable. "Power Wash Rental" is nothing more than a series of characters, AKA a string: (In this case "P" followed by "o" etc.) Likewise, "Half Day Rental" is a series of characters, "H" followed by "a" etc.)
"Power Wash Rental" is a literal string. So is ""Half Day Rental" and of course they will never match.
Whereas:
Dim A as string
A = TextBox1.text
Now, A is a variable. It is a string which contains whatever series of characters (text) is typed into the textbox.
This is a simple way to do it.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
chkhd.tag = 24 ' store values in the check boxes
chkfd.tag = 35 ' using the tag property
chktd.tag = 50 ' and later add up the values
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles btncalc.Click
dim total as double = 0
total += IF(chkhd.checked, cdbl(chkhd.tag), 0)
total += IF(chkfd.checked, cdbl(chkfd.tag), 0)
total += IF(chktd.checked, cdbl(chktd.tag), 0)
msgbox(total)
End Sub
However, I think you might want radio buttons instead of checkboxes.
Checkboxes can all be checked. Radio buttons can only have one at a time.
This solution allows you to keep your price with the checkbox -- you could do this in the form designer instead of form load.
I would recommend reading up on Case Statements. Currently you will never get anywhere as your using a string to what, nothing. You also do not need a case for this... Also if the first condition is true and the last one is as well, the last one win's for setting the text, didn't know if you had this there for a reason or not?
If chkhd.Checked = True Then
txtrc.Text = "poop"
End If
If chkFD.Checked = True Then
txtrc.Text = dblfdr
End If
As others have stated your Case statement isn't working because you are using string literals to compare "Power Wash Rental" to "Half Day Rental" which will always be false. Plutonix was also correct in saying that a ComboBox for the rental duration should be used. The only reason not to be is if you were calculating cumulative rental days/amounts; however in that situation you should be using some sort of NumericUpDown for your multiplier against a time duration.
Here is an example that should help you get started. You could make the structure into a type of keyed collection or make it a wrapper class for a dictionary object which would make be easier to use in code. The following may not be exactly plug-and-play with your project, however it should help give you some ideas on how to handle the situation.
Option Strict On
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.ComboBox1.Items.AddRange({PowerWashRentals.halfDayText, PowerWashRentals.FullDayText, PowerWashRentals.TwoDayText})
AddHandler ComboBox1.SelectedValueChanged, AddressOf Me.ComboBox1_SelectedChanged
End Sub
Private Sub ComboBox1_SelectedChanged(sender As Object, e As EventArgs)
Dim cBox As ComboBox = DirectCast(sender, ComboBox)
Select Case cBox.SelectedItem.ToString
Case PowerWashRentals.halfDayText
Label1.Text = PowerWashRentals.HalfDayPrice.ToString
Case PowerWashRentals.FullDayText
Label1.Text = PowerWashRentals.FullDayPrice.ToString
Case PowerWashRentals.TwoDayText
Label1.Text = PowerWashRentals.TwoDayPrice.ToString
End Select
End Sub
End Class
Public Structure PowerWashRentals
Public Const HalfDayPrice As Double = 24
Public Const FullDayPrice As Double = 35
Public Const TwoDayPrice As Double = 50
Public Const halfDayText As String = "Half Day Rental"
Public Const FullDayText As String = "Full Day Rental"
Public Const TwoDayText As String = "Two Day Rental"
End Structure

Converting a combobox to int

I'm trying to convert a string from a combobox to a usable integer format
my relevant piece of code:
Dim intDays As Integer
intDays = Convert.ToInt32(cboDays.Text)
lblDays.Text = intDays
After selecting my number for days, the label should change to the value for days selected if it had successfully been converted to an integer but it did not, so I am clearly missing something
If you have your combobox set to DropDownList, then the correct code is:
lblDays.Text = CInt(cboDays.SelectedItem.ToString)
you need to use the combobox SelectedIndexChanged to do this otherwise your code will not get called.
Then your code works.
Double click there to make the event.
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboDays.SelectedIndexChanged
Dim intDays As Integer
intDays = Convert.ToInt32(cboDays.Text)
lblDays.Text = intDays
End Sub
If lstRentalType.SelectedIndex <> -1 Then
'code ......
Else
'msgbox.....
End If

restarting filename iteration

I wanted to restart the iteration when the system clock hits 00:00 or 12:00 MN. I got the iteration code from the answer of this (below) link, and it works perfectly.
Public Sub GetLastNumber(ByVal filePath As String)
Dim lastFileNo As Integer = 1
Dim files() As String = Directory.GetFiles(filePath, "*.txt")
For Each file As String In files
file = Path.GetFileNameWithoutExtension(file)
Dim numbers As MatchCollection = Regex.Matches(file, "(?<num>[\d]+)")
For Each number In numbers
number = CInt(number.ToString())
If number > 0 And number < 1000 And number > lastFileNo Then lastFileNo = number
Next
lastnumber.Text = number
Next
End Sub
I stumbled something that uses a Timer like this one below, but it's giving me an error saying conversion fail "AM" as String to a Date type.
Public Sub DoStuff(ByVal obj As Object)
MessageBox.Show("It's already time", "TIME!", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
Public Sub testT()
Dim tcb As TimerCallback = AddressOf DoStuff
Dim t As Timer
Dim execTime As TimeSpan
Dim dtNow As DateTime = DateTime.Now
Dim hc As Integer = 12
Dim mc As Integer = 0
If TimeOfDay.ToString("tt").Contains("AM") And hc = 12 Then
hc = 0
ElseIf TimeOfDay.ToString("tt").Contains("PM") Then
hc = 12 + (12 - hc)
If hc = 24 Then
hc = 0
End If
End If
Dim dtCandidate As DateTime = New DateTime(dtNow.Year, dtNow.Month, dtNow.Day, hc, mc, 0)
If dtCandidate < dtNow Then
dtCandidate.AddDays(1)
End If
execTime = dtNow.Subtract(dtCandidate)
resultBox.Text = execTime.ToString
t = New Timer(tcb, Nothing, execTime, TimeSpan.Zero)
End Sub
Public Sub realTime_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles realTime.Tick
TimeNow.Text = TimeOfDay.ToString("HH:mm:ss")
testT()
End Sub
Conversion failure was remedied by using TimeOfDay.ToString("tt").Contains("AM/PM"). Un-representable DateTime error was remedied by correcting the ElseIf statements. Since there's no more error, I tried to put the testT function inside a Timer firing at 1000 ms. After system clock hit midnight(00:00), the message box of the DoStuff function showed every second after midnight. How can this be stopped but can still show up the next time the clock hits midnight?
Can somebody help me out?
The code you linked to for the timer is very bad because it is trying to use strings in the manipulation of DateTimes - they are very different things.
I created a new Windows Forms application with only a Label named "TimeNow":
Public Class Form1
Friend WithEvents realTime As Windows.Forms.Timer
Private lastAlarmTime As DateTime
Private alarmTimes As List(Of DateTime)
Private displayTime As String
Public Sub DoStuff()
MessageBox.Show("It's already time", "TIME!", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
Public Sub CheckForAnAlarmTime()
Dim dtNow As DateTime = DateTime.Now()
For Each tt In alarmTimes
' the timer interrupt handler is not necessarily called at exact times. Allow for that.
If tt > lastAlarmTime AndAlso tt < dtNow Then
lastAlarmTime = dtNow
DoStuff()
SetAlarmTimes()
Exit For
End If
Next
End Sub
Public Sub realTime_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles realTime.Tick
Dim candidateDisplayTime As String = DateTime.Now.ToString("HH:mm:ss")
' only update the UI if necessary
If candidateDisplayTime <> displayTime Then
displayTime = candidateDisplayTime
TimeNow.Text = displayTime
End If
CheckForAnAlarmTime()
End Sub
Private Sub SetAlarmTimes()
Dim dtNow As DateTime = DateTime.Now()
alarmTimes = New List(Of DateTime)
alarmTimes.Add(New DateTime(dtNow.Year, dtNow.Month, dtNow.Day, 12, 0, 0))
' Recommendation: do not use exactly midnight without extensive testing, i.e. test over day rollover, month rollover, and year rollover.
' With less testing, use a few milliseconds less than midnight.
alarmTimes.Add(New DateTime(dtNow.Year, dtNow.Month, dtNow.Day, 0, 0, 0).AddMilliseconds(-50))
End Sub
Private Sub SetUpAlarmsTimer()
SetAlarmTimes()
lastAlarmTime = DateTime.Now()
realTime_Tick(Me, EventArgs.Empty)
realTime = New Windows.Forms.Timer()
realTime.Interval = 200 ' 200ms will update it more accurately w.r.t. visual appearance
AddHandler realTime.Tick, AddressOf realTime_Tick
realTime.Start()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
SetUpAlarmsTimer()
End Sub
End Class
Change the alarmTimes to whatever you need to check that the alarm is raised only once per alarmTimes item.
I am not willing to wait until midnight to check if alarmTimes.Add(New DateTime(dtNow.Year, dtNow.Month, dtNow.Day, 0, 0, 0) without the .AddMilliseconds(-50) will work as required, or until the end of the month or year to be absolutely sure. And please don't forget about testing around the end of February when it is a leap year.
The reason for checking against the lastAlarmTime is that it is not certain when a timer event will be raised: for a timer set to tick at 1000ms, you might get two events inside one real second, or none inside one real second. Approximately.
EDIT: You might also want to work in UTC to avoid hassle with daylight savings time changes.

Comparing a datetimepicker with a string

i'm pretty new into coding and visual basic. Today I was assigned to complete a program that i'm having some trouble with. I need to develop an app that allows the user to enter the appointment and the time it needs to be competed, however i need to implement an error check to make sure no two times are the same, this is where i'm running into problems. I'm unsure how i can compare a datetimepicker.value to the listbox text. I'm getting the Conversion from string "" to type Date is not valid error. Any help is much appreciated!
Public Class Form1
Function TimeTaken() As Boolean
Dim app As String = TextBox1.Text
Dim timeofapp As String = DateTimePicker1.Value.ToShortTimeString
If CDate(ListBox2.Text) = CDate(DateTimePicker1.Value) Then
MsgBox("Two appointments are scheduled within the same time frame.", MsgBoxStyle.Exclamation)
TimeTaken = True
Else
TimeTaken = False
ListBox1.Items.Add(app)
ListBox2.Items.Add(timeofapp)
TextBox1.Text = ""
End If
End Function
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
TimeTaken()
End Sub
End Class
"I'm unsure how i can compare a datetimepicker.value to the listbox text"
You need to iterate over all the values stored in the ListBox.Items() property:
Function TimeTaken() As Boolean
Dim AlreadyTaken As Boolean = False ' assume not taken until proven otherwise below
Dim app As String = TextBox1.Text
Dim timeofapp As String = DateTimePicker1.Value.ToShortTimeString
For Each time As String In ListBox2.Items
If time = timeofapp Then
MsgBox("Two appointments are scheduled within the same time frame.", MsgBoxStyle.Exclamation)
AlreadyTaken = True
Exit For
End If
Next
If Not AlreadyTaken Then
ListBox1.Items.Add(app)
ListBox2.Items.Add(timeofapp)
TextBox1.Text = ""
End If
Return AlreadyTaken
End Function