Pergunta

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.

Foi útil?

Solução

Change the

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

to

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

.Net 4 allows you to use custom format strings with Timespan. You can find a full reference of available format specifiers at the MSDN Custom TimeSpan Format Strings page.

You need to escape the ":" character with a "\" (which itself must be escaped unless you're using a verbatim string).

This excerpt from the MSDN Custom TimeSpan Format Strings page explains about escaping the ":" and "." characters in a format string:

The custom TimeSpan format specifiers do not include placeholder separator symbols, such as the symbols that separate days from hours, hours from minutes, or seconds from fractional seconds. Instead, these symbols must be included in the custom format string as string literals. For example, "dd.hh:mm" defines a period (.) as the separator between days and hours, and a colon (:) as the separator between hours and minutes.

Outras dicas

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));

UPDATE: This applies to .NET 3.5 and earlier, .NET 4 does support formatting TimeSpans.

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.

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

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

you can do this:

dt.Subtract(TimeSpan.FromMilliseconds(dt.Millisecond)).ToString();

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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top