Link to home
Start Free TrialLog in
Avatar of smickell
smickellFlag for United Kingdom of Great Britain and Northern Ireland

asked on

Adding/subtracting time values of two Textboxes

Using .NET 2.0
Probably very easy, but I do not know what the advantages are betwee DateTime.Parse and TimeSpan.Parse and what I am doing wrong here, but all I want to do is add or subtract the time values of two textboxes and assign the result to a third textbox. Note: the StartTime and EndTime boxes are formatted as "09:00", "09:30","10:00" etc. (as is the HoursScheduled box)
Basically what I need is:
change start time: if StartTime > EndTime Then EndTime = StartTime + 00:30:00
change end time: if StartTime > EndTime Then StartTime = EndTime - 00:30:00
change hours scheduled: endtime = starttime + hoursscheduled

Code is below. It's an absolute mess and does not calculate the differences correctly. Surely this should be much much simpler? It can be done in one line with old Access VBA.

private void dtpStartTime_SelectionChangeCommitted(object sender, EventArgs e)
        {
            if (DateTime.Parse(dtpStartTime.Text) >= DateTime.Parse(dtpEndTime.Text))
                dtpEndTime.Text = (DateTime.Parse(dtpStartTime.Text).Add(DateTime.Parse("00:30:00"))).ToString();
            dtpHoursScheduled.Text = (DateTime.Parse(dtpEndTime.Text).Subtract(DateTime.Parse(dtpStartTime.Text))).ToString();
        }

private void dtpEndTime_SelectionChangeCommitted(object sender, EventArgs e)
        {
            if (DateTime.Parse(dtpStartTime.Text) >= DateTime.Parse(dtpEndTime.Text))
                dtpStartTime.Text = (DateTime.Parse(dtpEndTime.Text).Subtract(DateTime.Parse("00:30:00"))).ToString();
            dtpHoursScheduled.Text = (DateTime.Parse(dtpEndTime.Text).Subtract(DateTime.Parse(dtpStartTime.Text))).ToString();
        }

private void dtpHoursScheduled_SelectionChangeCommitted(object sender, EventArgs e)
        {
            dtpEndTime.Text = dtpStartTime.Text + dtpHoursScheduled.Text;
        }
Avatar of johnduff
johnduff

you probably want to use TimeSpan because you don't need all the other stuff DateTime brings with it.

change this, and anything similar:
dtpEndTime.Text = (DateTime.Parse(dtpStartTime.Text).Add(DateTime.Parse("00:30:00"))).ToString();

to this:

dtpEndTime.Text = (TimeSpan.Parse(dtpStartTime.Text).AddMinutes(30)).ToString();

should work out.  if it dosn't could you also post the actual problem you are having with the way you are doing it now.

John
Avatar of smickell

ASKER

Thanks for the quick reply johnduff but, if I do use TimeSpan, then I don't have the addMinutes, addHours etc. functions. These only come with DateTime, I was using DateTime to keep my options open.
I am using the AddMinutes function to add and subtract the minutes, so that bit has been simplified.

I've been working on it since, it turns out that the effect I wanted was not occuring because I had it in the _SelectionChangeCommitted event rather than TextChanged. This is it now:

private void dtpHoursScheduled_TextChanged(object sender, EventArgs e)
        {
            dtpEndTime.Text = (DateTime.Parse(dtpStartTime.Text).Add(TimeSpan.Parse(dtpHoursScheduled.Text))).ToString();
            dtpEndTime.FormatString = "t";
        }

private void dtpStartTime_TextChanged(object sender, EventArgs e)
        {
            try
            {
                if (DateTime.Parse(dtpStartTime.Text).CompareTo(DateTime.Parse(dtpEndTime.Text)) >= 0)
                    dtpEndTime.Text = (DateTime.Parse(dtpStartTime.Text).AddMinutes(30)).ToString();
                dtpHoursScheduled.Text = (DateTime.Parse(dtpEndTime.Text).Subtract(DateTime.Parse(dtpStartTime.Text))).ToString();
                dtpEndTime.FormatString = "t";
            }
            catch (Exception ex)
            {
                //MessageBox.Show("Exception: " + ex.Message);
            }
        }

private void dtpEndTime_TextChanged(object sender, EventArgs e)
        {
            if (DateTime.Parse(dtpStartTime.Text).CompareTo(DateTime.Parse(dtpEndTime.Text)) >= 0)
                dtpStartTime.Text = (DateTime.Parse(dtpEndTime.Text).AddMinutes(-30)).ToString();
            dtpHoursScheduled.Text = (DateTime.Parse(dtpEndTime.Text).Subtract(DateTime.Parse(dtpStartTime.Text))).ToString();
            dtpStartTime.FormatString = "t";
        }


So I got it mostly working. The hours are now updating. But there are two problemss that are still occurring:
1) An exception is thrown when I go to select one of my items from the list. The program claims that the time "is not a valid DateTime format". But if I do nothing in the exception handler, I am still able to go ahead, select a value and it writes to the database successfully. What causes the exception?
2) When any of the fields - start, end, total - are modified by one of the above methods, their formatting changes from "09:00" to a full date + time string ie "25/04/2006 09:00:00" - how do I stop this changing?
ASKER CERTIFIED SOLUTION
Avatar of johnduff
johnduff

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I got it working. The toShortTimeString() came in very useful, so thanks johnduff for guiding me in the right direction.
The code still seems quite bloated though:

private void dtpHoursScheduled_TextChanged(object sender, EventArgs e)
        {
            try
            {
                dtpEndTime.Text = (DateTime.Parse(dtpStartTime.Text).Add(TimeSpan.Parse(dtpHoursScheduled.Text))).ToString();
                dtpEndTime.Text = DateTime.Parse(dtpEndTime.Text).ToShortTimeString();
                dtpStartTime.Text = DateTime.Parse(dtpStartTime.Text).ToShortTimeString();
            }
            catch (System.Exception ex)
            {
                string errMsg = ex.Message;
            }
        }

        private void dtpStartTime_TextChanged(object sender, EventArgs e)
        {
            string convertString = "";
            try
            {
                if (DateTime.Parse(dtpStartTime.Text).CompareTo(DateTime.Parse(dtpEndTime.Text)) >= 0)
                    dtpEndTime.Text = DateTime.Parse(dtpStartTime.Text).AddMinutes(30).ToShortTimeString();
                convertString = DateTime.Parse(dtpEndTime.Text).Subtract(DateTime.Parse(dtpStartTime.Text)).ToString();
                convertString = DateTime.Parse(convertString).ToShortTimeString();
                dtpHoursScheduled.Text = convertString;
            }
            catch (System.Exception ex)
            {
                string errMsg = ex.Message;
            }
        }

        private void dtpEndTime_TextChanged(object sender, EventArgs e)
        {
            string convertString = "";
            try
            {
                if (DateTime.Parse(dtpStartTime.Text).CompareTo(DateTime.Parse(dtpEndTime.Text)) >= 0)
                    dtpStartTime.Text = DateTime.Parse(dtpEndTime.Text).AddMinutes(-30).ToShortTimeString();
                convertString = DateTime.Parse(dtpEndTime.Text).Subtract(DateTime.Parse(dtpStartTime.Text)).ToString();
                convertString = DateTime.Parse(convertString).ToShortTimeString();
                this.dtpHoursScheduled.Text = convertString;
            }
            catch (System.Exception ex)
            {
                string errMsg = ex.Message;
            }
        }



There is a reason for me using the following snippet:
convertString = DateTime.Parse(dtpEndTime.Text).Subtract(DateTime.Parse(dtpStartTime.Text)).ToString();
convertString = DateTime.Parse(convertString).ToShortTimeString();
dtpHoursScheduled.Text = convertString;

If I don't use the variable converString and just do the operation on dtpHoursScheduled.Text itself, if I scroll the mousewheel up and down repeatedly in the program it causes a StackOverFlow exception. This way seems to resolve it I think, although I'm still not convinced.
Is the above section of code the only method for this? If no-one offers any suggestions then johnduff's hints will receive the points.