views:

167

answers:

6

I want to display the elapsed time between two dates in a string.

Let's say I have the following code:

DateTime date1 = DateTime.Now();
System.Threading.Thread.Sleep(2500);
DateTime date2 = DateTime.Now();

TimeSpan elapsed = date2.substract(date1);
Console.WriteLine("> {0:hh:mm:ss}", elapsed);

What I expect:

> 00:00:03

What I get:

> 00:00:02.5002500

Is there a way to use the String.Format function to only return full seconds?
I also tried to remove the decimal places with:

elapsed = elapsed.Substract(TimeSpan.FromMiliseconds((double)Timespan.Miliseconds);

But that doesn't work either since elapsed.Miliseconds returns 500 as an Integer.

+1  A: 

After looking at a few ways of doing this, I'm unfortunately left with an ugly answer. You can't really use Ticks, as it doesn't return the format properly, but the following will work:

DateTime date1 = DateTime.Now;
System.Threading.Thread.Sleep(2500);
DateTime date2 = DateTime.Now;

TimeSpan elapsed = date2.Subtract(date1);

string[] Split = elapsed.ToString().Split('.');

string m = Split[0]; // Returns 00:00:02
Kyle Rozendo
A nice solution, too (And probably the most efficient regarding performance).
SchlaWiener
A: 

There are following custom format specifiers y (year), M (month), d (day), h (hour 12), H (hour 24), m (minute), s (second), f (second fraction), F (second fraction, trailing zeroes are trimmed), t (P.M or A.M) and z (time zone).

Following examples demonstrate how are the format specifiers rewritten to the output. [C#]

// create date time 2008-03-09 16:05:07.123


DateTime dt = new DateTime(2008, 3, 9, 16, 5, 7, 123);

String.Format("{0:y yy yyy yyyy}", dt);  // "8 08 008 2008"   year

String.Format("{0:M MM MMM MMMM}", dt);  // "3 03 Mar March"  month

String.Format("{0:d dd ddd dddd}", dt);  // "9 09 Sun Sunday" day

String.Format("{0:h hh H HH}",     dt);  // "4 04 16 16"      hour 12/24

String.Format("{0:m mm}",          dt);  // "5 05"            minute

String.Format("{0:s ss}",          dt);  // "7 07"            second

String.Format("{0:f ff fff ffff}", dt);  // "1 12 123 1230"   sec.fraction

String.Format("{0:F FF FFF FFFF}", dt);  // "1 12 123 123"    without zeroes

String.Format("{0:t tt}",          dt);  // "P PM"            A.M. or P.M.

String.Format("{0:z zz zzz}",      dt);  // "-6 -06 -06:00"   time zone
Eploo
The OP is looking to format a *TimeSpan*, not a *DateTime*.
Iain Galloway
+5  A: 

Unfortunately it's not possible to format a TimeSpan in the same way as a DateTime value. You can however do a quick conversion because both TimeSpan and DateTime store their value as ticks (in the Ticks property).

In your code that would look like this:

Console.WriteLine("> {0:hh:mm:ss}", new DateTime(elapsed.Ticks));
Marnix van Valen
I believe you want `HH:mm:ss` for this to be correct. Neat trick though, +1 from me
fearofawhackplanet
Great solution (since my Timespan will never be greater than 24h) and fearofawhackplanet is right: `HH:mm:ss` makes more sense.
SchlaWiener
A: 

Hmm, this is nasty (as it turns out) - at least prior to .NET 4.0

If you go here: http://msdn.microsoft.com/en-us/library/1ecy8h51(v=VS.90).aspx it will tell you that there is no format overload for a timespan and that you have to do it by hand e.g.:

     span.Hours.ToString("00") + ":" + 
     span.Minutes.ToString("00") + ":" + 
     span.Seconds.ToString("00") + "."

This appears - at least from the documentation - to be fixed in .NET 4.0

Murph
A: 

The TimeSpan class has Hours, Minutes and Seconds properties which return each time part individually. So you could try:

String.Format(CultureInfo.CurrentCulture, "{0}:{1}:{2}", elapsed.Hours, elapsed.Minutes, elapsed.Seconds)

To get the format you want.

There may be a more optimal way, but I haven't found it yet.

Dr Herbie
A: 

Change the

Console.WriteLine("> {0:hh:mm:ss}", elapsed);

to

Console.WriteLine("> {0:hh\\:mm\\:ss}", elapsed);

See the MSDN Custom TimeSpan Format Strings page for details.

DoctaJonez