65

I have two textboxes. One for a clock in time and one for clock out. The times will be put in this format:

Hours:Minutes

Lets say I have clocked in at 7:00 AM and clocked out at 2:00 PM.

With my current code, I get a difference of 2 hours, but it should be 7 hours. How would I do that in C#. I was going to convert to the 24 hour, by letting the user select AM or PM, but I got confused.

So, basically, how would I calculate the difference of hours between the two times?

I tried this, but got 2 hours and not 7 when I plugged in the numbers.

DateTime startTime = Convert.ToDateTime(textBox1.Text);
DateTime endtime = Convert.ToDateTime(textBox2.Text);

TimeSpan duration = startTime - endtime;
atk
  • 9,244
  • 3
  • 32
  • 32
Hunter Mitchell
  • 7,063
  • 18
  • 69
  • 116
  • 5
    What is the exact content of your text boxes? – Zdeslav Vojkovic Sep 20 '12 at 21:45
  • 1
    You're checking that the times have parsed correctly? That is, you've verified the values of `startTime` and `endTime`? – John Sep 20 '12 at 21:46
  • 2
    well users are supposed to put in ... 7:00 (any time) into the textboxes – Hunter Mitchell Sep 20 '12 at 21:46
  • 2
    I don't understand how you know whether "2:00" is AM or PM. Also, what culture do you use (which locale)? Btw it should be `duration = end - start`, not the other way around – Zdeslav Vojkovic Sep 20 '12 at 21:50
  • Using "7:00" ; "7:00am" ; "7:00 am" ; "7:00AM" ; "7:00 AM" all work just fine. I'm curious to see exactly what textBox1.Text is since I cannot duplicate your issue. – user1424311 Sep 20 '12 at 21:51
  • 2
    is there any chance that one of your text boxes is by default set to "00:00" and that you either use the wrong one in the code, or somehowe overwrite the value (e.g. during validation)? This would explain `02:00 - 00:00 => 2 h` – Zdeslav Vojkovic Sep 20 '12 at 21:59

6 Answers6

112
string startTime = "7:00 AM";
string endTime = "2:00 PM";

TimeSpan duration = DateTime.Parse(endTime).Subtract(DateTime.Parse(startTime));

Console.WriteLine(duration);
Console.ReadKey();

Will output: 07:00:00.

It also works if the user input military time:

string startTime = "7:00";
string endTime = "14:00";

TimeSpan duration = DateTime.Parse(endTime).Subtract(DateTime.Parse(startTime));

Console.WriteLine(duration);
Console.ReadKey();

Outputs: 07:00:00.

To change the format: duration.ToString(@"hh\:mm")

More info at: http://msdn.microsoft.com/en-us/library/ee372287.aspx

Addendum:

Over the years it has somewhat bothered me that this is the most popular answer I have ever given; the original answer never actually explained why the OP's code didn't work despite the fact that it is perfectly valid. The only reason it gets so many votes is because the post comes up on Google when people search for a combination of the terms "C#", "timespan", and "between".

Kittoes0124
  • 4,930
  • 3
  • 26
  • 47
  • 9
    `TimeSpan duration = endtime - startTime;` works too in this example. – user1424311 Sep 20 '12 at 21:48
  • @EliteGamer See this documentation on [time format strings](http://msdn.microsoft.com/en-us/library/az4se3k1.aspx). – Dan J Sep 20 '12 at 21:56
  • 2
    @EliteGamer, how does this answer your question? – Zdeslav Vojkovic Sep 20 '12 at 22:15
  • 2
    It still doesn't explain how the result was 2 hours as the code is essentially the same as his (with changed order of endTime and startTime) – Zdeslav Vojkovic Sep 20 '12 at 22:22
  • It's not working with following case string startTime = "8:00 PM"; string endTime = "12:00 PM"; – Abdulsalam Elsharif Jan 19 '19 at 14:26
  • @AbdulsalamElsharif What would you expect as a result? The time value of 12:00 (12:00 PM) is indeed eight hours behind the time value of 20:00 (8:00 PM)... – Kittoes0124 Jan 19 '19 at 15:20
  • @AbdulsalamElsharif Nevermind, I suppose he just messed something up while testing to end up with that kind of bogus result. There are other explanations involving time zones that -might- explain but I've never been one to speculate about such things... – Kittoes0124 Jan 19 '19 at 15:44
20

You could use the TimeSpan constructor which takes a long for Ticks:

 TimeSpan duration = new TimeSpan(endtime.Ticks - startTime.Ticks);
Tim Lehner
  • 14,813
  • 4
  • 59
  • 76
4

Two points:

  1. Check your inputs. I can't imagine a situation where you'd get 2 hours by subtracting the time values you're talking about. If I do this:

        DateTime startTime = Convert.ToDateTime("7:00 AM");
        DateTime endtime = Convert.ToDateTime("2:00 PM");
        TimeSpan duration = startTime - endtime;
    

    ... I get -07:00:00 as the result. And even if I forget to provide the AM/PM value:

        DateTime startTime = Convert.ToDateTime("7:00");
        DateTime endtime = Convert.ToDateTime("2:00");
        TimeSpan duration = startTime - endtime;
    

    ... I get 05:00:00. So either your inputs don't contain the values you have listed or you are in a machine environment where they are begin parsed in an unexpected way. Or you're not actually getting the results you are reporting.

  2. To find the difference between a start and end time, you need to do endTime - startTime, not the other way around.

StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315
2

If i rotate trough sorted list of times (like schedule list) at some point i need to get interval between last and first times , and so far i come to this solution:

  TimeSpan t1 = TimeSpan.Parse("23:00");
  TimeSpan t2 = TimeSpan.Parse("3:10");
  double _24h = (new TimeSpan(24, 0, 0)).TotalMilliseconds;
  double diff = t2.TotalMilliseconds - t1.TotalMilliseconds;
  if (diff < 0) diff += _24h;
  Console.WriteLine(TimeSpan.FromMilliseconds(diff)); // output: 04:10:00
troll-e
  • 21
  • 3
  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Nov 09 '21 at 20:30
0

Another way ( longer ) In VB.net [ Say 2300 Start and 0700 Finish next day ]

If tsStart > tsFinish Then

                            ' Take Hours difference and adjust accordingly
                            tsDifference = New TimeSpan((24 - tsStart.Hours) + tsFinish.Hours, 0, 0)

                            ' Add Minutes to Difference
                            tsDifference = tsDifference.Add(New TimeSpan(0, Math.Abs(tsStart.Minutes - tsFinish.Minutes), 0))


                            ' Add Seonds to Difference
                            tsDifference = tsDifference.Add(New TimeSpan(0, 0, Math.Abs(tsStart.Seconds - tsFinish.Seconds)))
SMA
  • 74
  • 2
0

With .NET Core 6 consider TimeOnly

.NET Fiddle example

using System;                       
public class Program
{
    public static void Main()
    {
        TimeOnly endTime = new(14, 0, 0);
        TimeOnly startTime = new(7, 0, 0);
        Console.WriteLine((endTime - startTime).ToString(@"hh\:mm"));
        Console.WriteLine((endTime - startTime));
    }
}

We get 07:00 and 07:00:00

Karen Payne
  • 4,341
  • 2
  • 14
  • 31