3

I created a TimeSpan this way

TimeSpan ts = new Timespan();

// Do some addition and subtraction on it

Then I am saving it to a file using this

string.Format("{0}:{1}:{2}:{3}", ts.Hours, ts.Minutes, ts.Seconds, ts.MilliSeconds);

Various values returned from it are like this

0:0:4:410
0:0:1:425
0:0:1:802
0:0:1:509
0:0:1:674
0:0:1:628
0:0:2:76

How to convert it back to TimeSpan.

I am using

TimeSpan.ParseExact("0:0:4:410", "h:m:s:fff", null); 

but it is giving me error Input String is not in correct format.

Where am I wrong?

Bridge
  • 29,818
  • 9
  • 60
  • 82
Nikhil Agrawal
  • 47,018
  • 22
  • 121
  • 208
  • 1
    By the way, I'm pretty sure `0:0:2:76` would produce a FormatException anyway, as it doesn't match `h:m:s:fff` (need a leading zero in there!) – Bridge Aug 20 '12 at 11:46
  • Usually I'd always pair `ToString` and `ParseExact` and use the same format string for both. Not a hack-job with format strings on one end and format-string-based parsing on the other. – Joey Aug 20 '12 at 11:47
  • 1
    You are trying to improve your answer [over here](http://stackoverflow.com/a/12036070/142637), aren't you? :-) – sloth Aug 20 '12 at 11:49
  • @BigYellowCactus: Yes and at the same time improving my C# knowledge. – Nikhil Agrawal Aug 20 '12 at 11:53
  • 1
    @NikhilAgrawal So, +1 from me for trying to get better – sloth Aug 20 '12 at 11:57
  • possible duplicate of [Why does TimeSpan.ParseExact not work](http://stackoverflow.com/questions/11719055/why-does-timespan-parseexact-not-work) – Rawling Aug 20 '12 at 12:10

3 Answers3

9

I believe you need to parse the colons, basically. I would also suggest using the invariant culture instead of the current thread culture:

var ts = TimeSpan.ParseExact("0:0:4:410", @"h\:m\:s\:fff",
                             CultureInfo.InvariantCulture);

From the documentation:

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.

I would also suggest using a format of h:mm:ss.fff instead - I believe this would be clearer than your current format. Note that you can use the format directly instead of your currently formatting approach:

const string TimeSpanFormat = @"h\:mm\:ss\.fff";

string text = ts.ToString(TimeSpanFormat, CultureInfo.InvariantCulture);
...
TimeSpan parsed = TimeSpan.ParseExact(text, TimeSpanFormat,
                                      CultureInfo.InvariantCulture);
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • What about `"0:0:2:76"`? Will this `"@"h\:m\:s\:fff"` suffice or will it give error? – Nikhil Agrawal Aug 20 '12 at 11:51
  • 1
    @NikhilAgrawal: You could have answered that question yourself by now, coudln't you? (The answer is no, that won't parse. You'd need 076 or 760.) – Jon Skeet Aug 20 '12 at 11:59
  • @Rawling: Indeed, although with the OP's current way of formatting, that would give the wrong answer (76 milliseconds would then be parsed as 760). Basically the current approach to formatting is a thoroughly bad idea. – Jon Skeet Aug 20 '12 at 12:15
  • Fair enough, I just noted "doesn't throw an exception" without checking "gives the right answer" :) – Rawling Aug 20 '12 at 12:16
1

you will have to escape the colons : when you are doing the parse

TimeSpan.ParseExact("0:0:4:410", @"h\:m\:s\:fff", null)

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.

was bitten some time back

Community
  • 1
  • 1
V4Vendetta
  • 37,194
  • 9
  • 78
  • 82
1

Try this:

TimeSpan timeSpan = TimeSpan.ParseExact("0:0:4:410", @"h\:m\:s\:fff", null);
Kapil Khandelwal
  • 15,958
  • 2
  • 45
  • 52