TotalHours function error handling - c#

I have two textboxes for each day of the week which allow a user to enter a start time and an end time in this format (hh:mm) (24 hour clock). For example, if a user enters 1:35 in the first textbox for Monday and 3:30 in the second textbox for Monday and press the 'Calculate' button, it will return the decimal 1.92. It runs and returns the result to a label, but I'm having some problems with my error handling.
If a textbox is left empty it will throw an error when ran and display "String was not recognized as a valid TimeSpan." How can I fix this so if a user doesn't enter a time it will either assume '0' or not run the code with that particular set of empty textboxes?
//Monday
TimeSpan Mon1In = TimeSpan.Parse(TextBoxInMon1.Text);
TimeSpan Mon1Out = TimeSpan.Parse(TextBoxOutMon1.Text);
MonLabel1.Text = (Mon1Out - Mon1In).TotalHours.ToString("f2");
//Tuesday
TimeSpan Tues1In = TimeSpan.Parse(TextBoxInTues1.Text);
TimeSpan Tues1Out = TimeSpan.Parse(TextBoxOutTues1.Text);
TuesLabel1.Text = (Tues1Out - Tues1In).TotalHours.ToString("f2");
//Wednesday
TimeSpan Wed1In = TimeSpan.Parse(TextBoxInWed1.Text);
TimeSpan Wed1Out = TimeSpan.Parse(TextBoxOutWed1.Text);
WedLabel1.Text = (Wed1Out - Wed1In).TotalHours.ToString("f2");
all the way to Friday.

You should use TimeSpan.TryParseMSDN where the out param is the value you would like and if the tryparse fails you set the TimeSpan to 00:00:00.
//Monday
TimeSpan Mon1In,Mon1Out;
if(!TimeSpan.TryParse(TextBoxInMon1.Text,out Mon1In)) Mon1In = default(TimeSpan);
if(!TimeSpan.TryParse(TextBoxOutMon1.Text,out Mon1Out)) Mon1Out = default(TimeSpan);
MonLabel1.Text = (Mon1Out - Mon1In).TotalHours.ToString("f2");

Related

Calculation with DateTime and TimeSpan in C#

I need to make a calculation of passed and remaining time of an operation in C#.
I have the start of the operation saved in a string format of HH:MM:SS
I have a default time length of the operation in a string format of HH:MM:SS
Now I would like to calculate:
The remaining time / extra time: For example if the operation is still below the default length, it should display -HH:MM:SS, and if the operation took longer than the default time, it should display +HH:MM:SS
If the operation took longer, I would also like to have a double value of HH,MM in % style. For example: 3hours and 30 minutes should be displayed as 3,5
Both results to be displayed next to each other.
I know I have to translate the string values into DateTime and/or TimeSpan values to do calculations, but currently I have no idea how to calculate since the first operation for example would not give me a negative value, but just get back in time [22:30:00 of yesterday].
Try this..
var start = "17:05:11"; // Pass this as a parameter
var startTime = DateTime.Parse(start);
var defaultDuration = TimeSpan.FromMinutes(2);
TimeSpan operationDuration = startTime - DateTime.Now;
TimeSpan diff = defaultDuration - operationDuration;
if (operationDuration > defaultDuration)
{
Console.Out.WriteLine($"+{diff.Hours}:{diff.Minutes}:{diff.Seconds}");
}
else
{
Console.Out.WriteLine($"-{diff.Hours}:{diff.Minutes}:{diff.Seconds}");
Console.Out.WriteLine($"{diff.Hours},{Math.Round(((double)(diff.Minutes * 100 / 60)),0, MidpointRounding.AwayFromZero)}");//example: 3hours and 30 minutes should be displayed as 3,5
}
At first save the default time as TimeSpan. Then you can take DateTime.Now and save it when the operation starts. Take another DateTime.Now later when it finished. After this point you can calculate the TimeSpan for the current operation. Then you can calculate the difference from these two TimeSpans as another TimeSpan. It can be positive or negativ and with these values you can do whatever you want.
TimeSpan defaultDuration = new TimeSpan(3, 30, 0);
DateTime begin = DateTime.Now;
//Do some work
DateTime end = DateTime.Now;
TimeSpan thisDuration = end - begin;
Console.WriteLine("Default: " + defaultDuration.ToString("hh\\:mm\\:ss"));
Console.WriteLine("This time: " + thisDuration.ToString("hh\\:mm\\:ss"));
Console.Write("Difference: ");
if (thisDuration > defaultDuration)
Console.Write("-");
Console.WriteLine((thisDuration - defaultDuration).ToString("hh\\:mm\\:ss"));

Looping 24 hour clock time difference

I created a time calculator so someone can enter a start time in a textbox and an end time in another textbox in 24 hour time format and it will calculate the difference and show it in a label.
How can I make my code do the same thing but with a loop? I'm just looking to make the code shorter instead of having a block of code for each day of the week, shown below is just the Monday and Tuesday code.
//Monday
TimeSpan Mon1In, Mon1Out;
if (!TimeSpan.TryParse(TextBoxInMon1.Text, out Mon1In))
Mon1In = default(TimeSpan);
if (!TimeSpan.TryParse(TextBoxOutMon1.Text, out Mon1Out))
Mon1Out = default(TimeSpan);
MonLabel1.Text = (Mon1Out - Mon1In).TotalHours.ToString("f2");
//Tuesday
TimeSpan Tues1In, Tues1Out;
if (!TimeSpan.TryParse(TextBoxInTues1.Text, out Tues1In))
Tues1In = default(TimeSpan);
if (!TimeSpan.TryParse(TextBoxOutTues1.Text, out Tues1Out))
Tues1Out = default(TimeSpan);
TuesLabel1.Text = (Tues1Out - Tues1In).TotalHours.ToString("f2");
You can just make a function. This is called refactoring.
private void GetTimeValues(TextBox txtIn, TextBox txtOut,
out TimeSpan inTime, out Timespan outTime)
{
if (!TimeSpan.TryParse(txtIn.Text, out inTime))
inTime = default(TimeSpan);
if (!TimeSpan.TryParse(txtOut.Text, out outTime))
outTime = default(TimeSpan);
}
Then call the function and set your label.
TimeSpan Mon1In, Mon1Out;
GetTimeValues(TextBoxInMon1, TextBoxOutMon1, out Mon1In, out Mon1Out);
MonLabel1.Text = (Mon1Out - Mon1In).TotalHours.ToString("f2");
You should probably use a more descriptive function name, this was just the first thing I thought of.
You could also include the label logic inside the function as well, just thread the information along in the same fashion.

DateTime.ToString FormatException error

I want to do a timer and print the value in a label. I do:
label1.Text = (DateTime.Now - startDate).ToString("HH:mm:ss");
But I receive a FormatException error. What's wrong in my code?
DateTime.Now - startDate returns a TimeSpan not a DateTime.
You need to escape colons with backslash and use lowercase hh in TimeSpan.ToString:
TimeSpan diff = DateTime.Now - startDate;
label1.Text = diff.ToString("hh\\:mm\\:ss");
But note that the hour will never exceed 23 hours, the maximum value is 23:59:59. If you want to show also the days you have to use a format like "dd\\:hh\\:mm\\:ss".
label1.Text = DateTime.Compare(Convert.ToDateTime(startDate.Text), Convert.ToDateTime(ToDate.Text,"hh\\:mm\\:ss"));

C# WPF Time Until xx

I am trying to display the time remaining until a time specified by the user. I want to show Hours, Minutes, Seconds, and maybe milliseconds until the specified time.
DateTime remaining = DateTime.Parse("2/24/2014 18:00:00 pm");
DateTime startDate = DateTime.Now;
TimeSpan t = remaining - startDate;
string countdown = string.Format("{0}:{1}:{2}:{3}", t.Days, t.Hours, t.Minutes, t.Seconds);
CountDown.Content = countdown;
Visual Studio says I need to parse the string to take in the date before setting it to a DateTime object.
So do I need to create a new string, then parse it to a string, and then set the string to a DateTime object?
Update:
The actual error message I am receiving is:
System.FormatException was unhandled HResult=-2146233033
Message=String was not recognized as a valid DateTime. Source=mscorlib
If I understand the question correctly, you just want:
DateTime target = new DateTime(2014, 2, 24, 18, 0, 0);
TimeSpan remaining = target - DateTime.Now;
There's no need to parse a string just to get a DateTime value, if you already know the year/month/day etc you want.
However, you've also talked about "a time specified by the user". If that date/time is being specified as a string, then yes, you'll need to parse it. Ideally, it would be specified by some sort of date/time picker control, in which case you should just be able to get an appropriate DateTime value. Avoid string conversions unless you really need them.
This should get you going:
DateTime remaining = DateTime.Parse("2/24/2014 18:00:00 pm");
DateTime startDate = DateTime.Now;
TimeSpan t = remaining - startDate;
DateTime difference = new DateTime(t.Ticks);
CountDown.Content = difference;

Determining how long a trip takes in minutes

Have the user enter an arrival time such in the format 3:30 PM
Then ask the user how long it takes to get to their destination.
I then need to display the time they need to leave in order to arrive to their destination on time.
I have this so far
Console.WriteLine("Enter the arrival time <e.g. 3:30 PM>:");
DateTime time = Convert.ToDateTime(Console.ReadLine());
Console.WriteLine("How long is the trip time in minutes:");
string date = Console.ReadLine();
DateTime durationOfTrip = DateTime.Parse(date);
TimeSpan diff = time.Subtract(durationOfTrip);
Console.WriteLine(diff);
Console.ReadLine();
I get this error
An unhandled exception of type System.FormatException occurred in mscorlib.dll
Additional information: String was not recognized as a valid DateTime.
I suspect you're trying to parse the string "3:30 PM" into an instance of DateTime. You'll need to use a custom parse string:
string arrivalInput = Console.ReadLine();
var arrival =
DateTime.ParseExact(
arrivalTimeInput,
"hh:mm tt",
CultureInfo.InvariantCulture
);
This will parse the time, but it will set the date component to today.
Unfortunately, there is just no clean encapsulation of time only in the framework.
Then your next problem is
string date = Console.ReadLine();
DateTime durationOfTrip = DateTime.Parse(date);
where you're trying to parse something like "30" into a DateTime. That's clearly not going to fly. You told the user to enter the input in minutes, so convert the input to an instance of TimeSpan:
string durationInput = Console.ReadLine();
var duration = new TimeSpan(0, Int32.Parse(durationInput), 0);
or
var duration = TimeSpan.ParseExact(s, "mm", CultureInfo.InvariantCulture);
Then, what you need to do is subtract duration from arrival, this will give you a new instance of DateTime, and then you need to use an appropriate format string to only output the time.
Note that I've given your variable names slightly more meaningful names. The name date for the user input trip duration was particularly unclear.
An average user would enter an integer number ("time in minutes"), and you're trying to parse this into a DateTime structure. How would .NET know what these numbers mean? They might as well be milliseconds.
The first step would probably be parsing the input to an int, and then using the AddMinutes() method JMK mentioned to apply the minutes to the already created DateTime time.

Categories

Resources