Good day all. Firstly, please forgive such a stupid question. I am 54 years old and have only a few months ago started with vb.net after I lost my job in aviation due to covid. This is all new to me and I had a choice of either lying down or trying to get back on my feet. A mate recommended vb.net and not C# as I am new to this whole programming thing. I have a few friends that are helping me get small jobs doing desktop programs. I have a possible new client that would like to have a small program that calculates hours for her staff. Yes, excel can do it but she wants a program.
What I am trying to do is calculate two times. It works fine, except when the later time is the next day. For example: Shift is from 22:00 till 06:00, the shift must read 08:00 hours. Currently I am getting -16 hours. I have googled but I am having a really hard time with this.
Below is the code for the button. Please forgive the primitive coding
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim TimeOn As DateTime = DateTime.Parse(MaskedTextBox1.Text)
Dim TimeOff As DateTime = DateTime.Parse(MaskedTextBox2.Text)
Dim timeDiff As TimeSpan = TimeOff.Subtract(TimeOn)
' Here I need to figure out how to calculate the time if
' TimeOff is the next day. Eg. Shift is 22:00 till 06:00
' the answer should be 08:00 (8 hours)
TextBox1.Text = (timeDiff.ToString)
End Sub
End Class
My guess is that your inputs are "hh:mm" aren't they? That's the problem... you're only dealing with time... no dates... so there's no context that the end time is the next day... when you parse a time into a date time, with no date, it defaults to 1/1/1899 (or something like that) ... so your TimeOn = "1/1/1899 22:00:00.000" and TimeOff = "1/1/1899 06:00:00.000" ... and the difference according to your calculation is -16hours.
So you need to give it dates as well as a time. TimeOn = "8/25/2020 22:00:00.000" and TimeOff = "8/26/2020 06:00:00.000" would give you the right result.
Hoe you do that is up to you, but there is a DateTimePicker control that is available... for entering dates and times...
My guess is that your inputs are "hh:mm" aren't they? That's the problem... you're only dealing with time... no dates... so there's no context that the end time is the next day... when you parse a time into a date time, with no date, it defaults to 1/1/1899 (or something like that) ... so your TimeOn = "1/1/1899 22:00:00.000" and TimeOff = "1/1/1899 06:00:00.000" ... and the difference according to your calculation is -16hours.
So you need to give it dates as well as a time. TimeOn = "8/25/2020 22:00:00.000" and TimeOff = "8/26/2020 06:00:00.000" would give you the right result.
Hoe you do that is up to you, but there is a DateTimePicker control that is available... for entering dates and times...
-tg
Thank you so much. That makes perfect sense (the date issue). I will try it out a bit later and get back to you. Thank you for taking the time to reply. It is highly appreciated.
Kind Regards,
Dmitri
An alternative way to do it is to just assume that a shift is a positive amount of time, less than 24 hours. You can then add 24 hours until the value is positive:
Code:
...
Dim timeDiff As TimeSpan = TimeOff.Subtract(TimeOn)
Do While timeDiff.Hours < 0
timeDiff.Add(New TimeSpan(24, 0, 0))
Loop
TextBox1.Text = (timeDiff.ToString)
...
Note that this is less "correct" than tg's suggestion, but potentially better for the user.
An alternative way to do it is to just assume that a shift is a positive amount of time, less than 24 hours. You can then add 24 hours until the value is positive:
Code:
...
Dim timeDiff As TimeSpan = TimeOff.Subtract(TimeOn)
Do While timeDiff.Hours < 0
timeDiff.Add(New TimeSpan(24, 0, 0))
Loop
TextBox1.Text = (timeDiff.ToString)
...
Note that this is less "correct" than tg's suggestion, but potentially better for the user.
Thanks for this. I will be keeping these in notes. You folks must have been doing this for years and started young. I do appreciate the kind assistance.
Does this thread need to be closed and if so how as I cannot see anywhere to mark this as solved.
Also, quit calling yourself old. You're making me feel bad.
I once thought I was one of the older people on this forum, but now I know I'm not. I'm only a year back of you, too.
Also, let me say that VB is a fine choice, but C# would be, as well. Once you know one, moving to the other wouldn't be terribly difficult. The syntax is different, but the structure would all be the same.
Also, quit calling yourself old. You're making me feel bad.
I once thought I was one of the older people on this forum, but now I know I'm not. I'm only a year back of you, too.
Also, let me say that VB is a fine choice, but C# would be, as well. Once you know one, moving to the other wouldn't be terribly difficult. The syntax is different, but the structure would all be the same.
Thanks. I am hoping that things get back to "normal" again in the next year or so and then maybe I can get my old job back, but the entire world has gone pear shaped. I like the feeling of learning something new, but it is difficult switching a mindset of 25 plus years to programming.
Dim startTime As New DateTime(2020, 8, 27, 22, 0, 0) ' 22:00 today
Dim endTime As New DateTime(2020, 8, 28, 6, 0, 0) ' 6:00 tomorrow
Dim duration As TimeSpan = endTime - startTime 'Subtract start time from end time
MsgBox("Totalhours :" & duration.TotalHours)
and welcome to the VBforums
to hunt a species to extinction is not logical !
since 2010 the number of Tigers are rising again in 2016 - 3900 were counted. with Baby Callas it's 3901, my wife and I had 2-3 months the privilege of raising a Baby Tiger.
Also, quit calling yourself old. You're making me feel bad.
I once thought I was one of the older people on this forum, but now I know I'm not. I'm only a year back of you, too.
Also, let me say that VB is a fine choice, but C# would be, as well. Once you know one, moving to the other wouldn't be terribly difficult. The syntax is different, but the structure would all be the same.
"Is young any man who forgot to grow old because he had much better things to do in life", Peter Ustinov
The best friend of any programmer is a search engine
"Don't wish it was easier, wish you were better. Don't wish for less problems, wish for more skills. Don't wish for less challenges, wish for more wisdom" (J. Rohn)
“They did not know it was impossible so they did it” (Mark Twain)
Thanks for this. I will be keeping these in notes. You folks must have been doing this for years and started young. I do appreciate the kind assistance.
Does this thread need to be closed and if so how as I cannot see anywhere to mark this as solved.
Once again, many thanks and kind regards,
Dmitri
I tried this code. If both times are the same day, it works. If the end time is the next day, my program hangs.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim TimeOn As DateTime = DateTime.Parse(MaskedTextBox1.Text)
Dim TimeOff As DateTime = DateTime.Parse(MaskedTextBox2.Text)
Dim timeDiff As TimeSpan = TimeOff.Subtract(TimeOn)
Do While timeDiff.Hours < 0
timeDiff.Add(New TimeSpan(24, 0, 0))
Loop
' Here I need to figure out how to calculate the time if
' TimeOff is the next day. Eg. Shift is 22:00 till 06:00
' the answer should be 08:00 (8 hours)
Thank you so much. That makes perfect sense (the date issue). I will try it out a bit later and get back to you. Thank you for taking the time to reply. It is highly appreciated.
Kind Regards,
Dmitri
I like this. The issue that I need to solve is that I need to enter the time manually. I changed a few of the datetimepicker options (short, time, custom) but I just cannot seem to find where I add the time.
Old habits die hard... C# is structurally similar to vb.net but has a less intuitive (IMHO) syntax. Anyone who really wants to try something mind bendingly different should try writing what you would normally write using some form of BASIC in a functional programming language. At least a mostly functional one such as FSharp. Makes for good thought experiments. :-)
Thank you and apologies for late reply. I will implement that shortly and get back to you. I will also google to see what the difference is between the two. Would you know of any good ebooks that I can download. I have checked many site but the beginners books are way over my head.
Sometimes it is good to try several, even in parallel, to get different perspectives on the topics, and have something to compare, contrast and corroborate what you read.
Last edited by passel; Aug 28th, 2020 at 07:51 AM.
"Anyone can do any amount of work, provided it isn't the work he is supposed to be doing at that moment" Robert Benchley, 1930
Thank you and apologies for late reply. I will implement that shortly and get back to you. I will also google to see what the difference is between the two. Would you know of any good ebooks that I can download. I have checked many site but the beginners books are way over my head.
Regards,
Dmitri
Thank you so much. It works. I am trying to format the answer for HH:mm but if I do not come right I will have to ask for assistance again, but I would like to try this out for myself first.
Regards,
Dmitri
I have tried to format the label to display the resulting hours in HH:mm
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim TimeOn As DateTime = DateTime.Parse(MaskedTextBox1.Text)
Dim TimeOff As DateTime = DateTime.Parse(MaskedTextBox2.Text)
Dim timeDiff As TimeSpan = TimeOff.Subtract(TimeOn)
' TextBox1.Text = (timeDiff.TotalHours)
Do While timeDiff.Hours < 0
timeDiff += New TimeSpan(24, 0, 0)
Loop
' I need the label to display HH:mm of the total time
Label1.Text = (timeDiff.TotalHours).ToString("HH:mm")
End Sub
The issue I am having is that the label does not display the hours but displays HH:mm. I have searched but the only results that I find on the net is for c# or ASP
If I do Label1.Text = (timeDiff.ToString("HH:mm")) it throws an error of incorrect format. Even when I to ("HH:mm tt")
If someone could show me a tutorial on how to do this. I looked at homeandlearn as well as java links that were provided but could not find any solution to this.
Apologies for a simple question.
Regards,
Dmitri
Private Sub SurroundingSub()
Dim ts1 As TimeSpan = New TimeSpan(14, 3, 17)
Console.WriteLine(ts1.ToString("d\.hh\:mm\:ss"))
Dim ts2 As TimeSpan = New TimeSpan(3, 4, 3, 17)
Console.WriteLine(ts2.ToString("d\.hh\:mm\:ss"))
End Sub
Now I just need to figure out how to implement this is my situation.
Everything works regarding the time and formatting. I am now trying to get some restrictions on user input. I have checked the docs at MS and found that this works:
Private Sub MskSunOn_KeyPress(sender As Object, e As KeyPressEventArgs) Handles MskSunOn.KeyPress
If (e.KeyChar < "0" OrElse e.KeyChar > "9") AndAlso e.KeyChar <> ControlChars.Back Then
e.Handled = True
End If
End Sub
I need to prevent the user from using the TAB button until the entire masked text box (HH:mm) is filled in. If you tab before all the characters are entered, you get an error.
I checked that the Keychar for tab is 11. I tried inserting this in the above code as well but I can still tab out of the Msk without any values or only a few values filled in.
What kind of error? There are many similar questions with as many different answers. Try Googling "vb.net prevent texbox from losing focus".
I need both maskedtextboxes filled in with the times, or I get an error. If you tab out of the first box without entering the time and move to the second box, the calculation is incorrect and it throws an error. I have so far gotten it to work with only numerals. Now if I can just get this leaving the box before completion, I will be one very happy individual
I need both maskedtextboxes filled in with the times, or I get an error. If you tab out of the first box without entering the time and move to the second box, the calculation is incorrect and it throws an error. I have so far gotten it to work with only numerals. Now if I can just get this leaving the box before completion, I will be one very happy individual
Have you considered simply validating the resulting input when the user tries to leave the control and force them to enter something that is valid, for example:
Code:
Private Sub MaskedTextBox1_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles MaskedTextBox1.Validating
Dim time As DateTime
If DateTime.TryParse(MaskedTextBox1.Text, time) = False Then
e.Cancel = True
MessageBox.Show(Me, "Invalid time", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
End Sub
Have you considered simply validating the resulting input when the user tries to leave the control and force them to enter something that is valid, for example:
Code:
Private Sub MaskedTextBox1_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles MaskedTextBox1.Validating
Dim time As DateTime
If DateTime.TryParse(MaskedTextBox1.Text, time) = False Then
e.Cancel = True
MessageBox.Show(Me, "Invalid time", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
End Sub
I tried validating but as mentioned I am very very new to programming and still getting to grips with the syntax etc. I write down what I want to accomplish and how I want to. It is the implementation that I need to get to grips with. Thank you for your feedback. I will try this shortly and revert back.
Hi folks. Thanks for all your help. I now have a weird situation where I add up all the hours and I get a result that makes no sense. As soon as the total hours reaches 24, the result shows 1:00:00:00 I have attached the screenshot as well as my code below:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim Span1 As TimeSpan = TimeSpan.Parse(TxtSunHrs.Text)
Dim Span2 As TimeSpan = TimeSpan.Parse(TxtMonHrs.Text)
Dim Span3 As TimeSpan = TimeSpan.Parse(TxtTueHrs.Text)
Dim Span4 As TimeSpan = TimeSpan.Parse(TxtWedHrs.Text)
Dim Span5 As TimeSpan = TimeSpan.Parse(TxtThuHrs.Text)
Dim Span6 As TimeSpan = TimeSpan.Parse(TxtFriHrs.Text)
Dim Span7 As TimeSpan = TimeSpan.Parse(TxtSatHrs.Text)
Dim TotalTime As TimeSpan = Span1 + Span2 + Span3 + Span4 + Span5 + Span6 + +Span7
TxtTTLHrs.Text = TotalTime.ToString
Here is one of the textboxes to get the hours for Sunday (txtsunhrs)
Private Sub MaskedTextBox2_Leave(sender As Object, e As EventArgs) Handles MskSunOff.Leave
Dim TimeOn As DateTime = DateTime.Parse(MskSunOn.Text)
Dim TimeOff As DateTime = DateTime.Parse(MskSunOff.Text)
Dim timeDiff As TimeSpan = TimeOff.Subtract(TimeOn)
Do While timeDiff.Hours < 0
timeDiff += New TimeSpan(24, 0, 0)
Loop
TxtSunHrs.Text = (timeDiff.ToString("hh\:mm"))
End Sub
What on Earth am I doing wrong?
Regards,
Dmitri
Last edited by DmitriDumas; Aug 31st, 2020 at 02:03 AM.
Hi folks. I managed to figure it out. I changed TxtTTLHrs.Text = TotalTime.ToString to
TxtTTLHrs.Text = TotalTime.ToHours and it works. I actually need the time in hours and minutes format. If someone could give me a clue on how to do that.
I have to say that the help I have received here is amazing
I have looked at that page before and am doing so again. I am especially looking at the hh specifier, but am struggling to get the format correctly. I will keep working on it.
I have looked at that page before and am doing so again. I am especially looking at the hh specifier, but am struggling to get the format correctly. I will keep working on it.
I tried that and it did not work. I then copied and pasted your code and it worked. I feel like a total idiot because I did not have the point before the fff. I do apologise for that and thanks again. I have tried your formatting, however I am still getting incorrect total once the total exceeds 24 hours for the week. Would you be able to assist with that?
Regards,
Dmitri
Last edited by DmitriDumas; Sep 1st, 2020 at 01:49 AM.
Dim time1 As TimeSpan = TimeSpan.Parse("1.18:00:00")
TextBox2.Text = String.Format("{0:n0}:{1:d2}:{2:d2}", time1.TotalHours, time1.Minutes, time1.Seconds)
to hunt a species to extinction is not logical !
since 2010 the number of Tigers are rising again in 2016 - 3900 were counted. with Baby Callas it's 3901, my wife and I had 2-3 months the privilege of raising a Baby Tiger.
Dim time1 As TimeSpan = TimeSpan.Parse("1.18:00:00")
TextBox2.Text = String.Format("{0:n0}:{1:d2}:{2:d2}", time1.TotalHours, time1.Minutes, time1.Seconds)
Thank you. I tried that, however the total amount of hours does not show the correct total. I have tried this:
If TotalTime.Hours < 24 Then
TxtTTLHrs.Text = TotalTime.TotalHours.ToString("hh\:mm\:ss\.fff")
End If
This displays hh\:mm\:ss\.fff in the textbox. If I take out the .ToString("hh\:mm\:ss\.fff"), then it shows the correct number of hours, but only the hours.
I just need the hours (which it shows) and the minutes which it does not show, eg 70:00.
Thank you. I tried that, however the total amount of hours does not show the correct total. I have tried this:
If TotalTime.Hours < 24 Then
TxtTTLHrs.Text = TotalTime.TotalHours.ToString("hh\:mm\:ss\.fff")
End If
This displays hh\:mm\:ss\.fff in the textbox. If I take out the .ToString("hh\:mm\:ss\.fff"), then it shows the correct number of hours, but only the hours.
I just need the hours (which it shows) and the minutes which it does not show, eg 70:00.
Regards,
Dmitri
show us the Times you are using
to hunt a species to extinction is not logical !
since 2010 the number of Tigers are rising again in 2016 - 3900 were counted. with Baby Callas it's 3901, my wife and I had 2-3 months the privilege of raising a Baby Tiger.
Private Sub MaskedTextBox2_Leave(sender As Object, e As EventArgs) Handles MskSunOff.Leave
Dim TimeOn As DateTime = DateTime.Parse(MskSunOn.Text)
Dim TimeOff As DateTime = DateTime.Parse(MskSunOff.Text)
Dim timeDiff As TimeSpan = TimeOff.Subtract(TimeOn)
Do While timeDiff.Hours < 0
timeDiff += New TimeSpan(24, 0, 0)
Loop
TxtSunHrs.Text = (timeDiff.ToString("hh\:mm"))
End Sub
When I leave this textbox the total hours of the day gets inserted into a textbox for the total hours of the day. This is done for 7 days
To get the total hours for the week:
Dim Span1 As TimeSpan = TimeSpan.Parse(TxtSunHrs.Text)
Dim Span2 As TimeSpan = TimeSpan.Parse(TxtMonHrs.Text)
Dim Span3 As TimeSpan = TimeSpan.Parse(TxtTueHrs.Text)
Dim Span4 As TimeSpan = TimeSpan.Parse(TxtWedHrs.Text)
Dim Span5 As TimeSpan = TimeSpan.Parse(TxtThuHrs.Text)
Dim Span6 As TimeSpan = TimeSpan.Parse(TxtFriHrs.Text)
Dim Span7 As TimeSpan = TimeSpan.Parse(TxtSatHrs.Text)
Dim TotalTime As TimeSpan = Span1 + Span2 + Span3 + Span4 + Span5 + Span6 + +Span7
'------------------
' Trying to get the correct time display after 24 hours total
'------------------
'TxtTTLHrs.Text = TotalTime.TotalHours
' TxtTTLHrs.Text = TotalTime.ToString("hh\:mm\:ss\.fff")
If TotalTime.Hours < 24 Then
TxtTTLHrs.Text = TotalTime.TotalHours '.ToString("hh\:mm\:ss\.fff")
End If
End Sub
I have commented out '.ToString("hh\:mm\:ss\.fff") because it displays hh\:mm\:ss\.fff
If I only use TxtTTLHrs.Text = TotalTime.TotalHours it gives the hours in hh format, eg 70
those are not Times
I mean...
12:00 to 16:23
22:00 to 06:12 = nightshift
06:00 to 14:00
etc...
I would also suggest to use a Datatable with a Datagridview rather that Textboxes
but that is up to you
if you use a Datatable you could then also use a Database to store those
weekly working times
to hunt a species to extinction is not logical !
since 2010 the number of Tigers are rising again in 2016 - 3900 were counted. with Baby Callas it's 3901, my wife and I had 2-3 months the privilege of raising a Baby Tiger.