Geeks With Blogs
Tex-blog Mobile and other stuff
I was looking for some time a method for formatting TimeSpan in a same way as DateTime, but there is no easy way to do that, and the methods found on google are not applicable to every situation.

One of the more useful methods is to convert TimeSpan to DateTime and format it this way:

TimeSpan ts = TimeSpan.FromMinutes(20);
DateTime dt = DateTime.MinValue.Add(ts);
Console.WriteLine(dt.ToString("dd.HH.mm"));

on output it will print: "01.00.20"

Which is not what someone might want because it shows "01." in front, I would prefer "00." or even nothing if time span is less than one day. Actually if I was to use only time spans that are less then 24 hours, then I would just get rid of "dd." in above format and everything would be ok. But what if you need longer time spans.

One solution is to use string formatting functions:

TimeSpan ts = TimeSpan.FromMinutes(20);
DateTime dt = DateTime.MinValue.Add(ts);
string sres = dt.ToString("dd.HH.mm");
if (ts < TimeSpan.FromDays(1))
  sres = sres.Substring(3);

Console.WriteLine(sres);

This code prints: "00.20"

But now suppose you have no access to formatting code, for example you want to have your TimeSpan-s formatted correctly in DataGrid or by String.Format(). This requires you to create class implementing IFormatProvider and ICustomFormatter, such classes are created when custom formatting is required but there is no acces to source code of class with data (in this case TimeSpan):

public class TimeSpanFormatInfo : IFormatProvider, ICustomFormatter
{

  #region IFormatProvider Members
  public object GetFormat(Type formatType)
  {
    if (formatType != typeof(ICustomFormatter))
      return null;
    return this;
  }

  #endregion

  #region ICustomFormatter Members
  public string Format(string format, object arg, IFormatProvider formatProvider)
  {
    string formattedString;
    if (arg is TimeSpan)
    {
      TimeSpan ts = (TimeSpan)arg;
      DateTime dt = DateTime.MinValue.Add(ts);
      if (ts < TimeSpan.FromDays(1))
      {
        format = format.Replace("d.", "");
        format = format.Replace("d", "");
      }
      formattedString = dt.ToString(format, formatProvider);
    }
    else
      throw new ArgumentNullException();
    return formattedString;
 
}
  #endregion
}

and then you can use:

string sres = String.Format(new TimeSpanFormatInfo(),
                  "{0:"
+ "dd.HH:mm" + "}", TimeSpan.FromMinutes(20));
Console.WriteLine(sres);

Actually I needed above code to make DataGridCustomColumnBase class properly format DataGrid columns with TimeSpan data.

This class can be found in links section here:
http://blogs.msdn.com/netcfteam/archive/2006/04/25/583542.aspx

To be able to use FormatInfo property of this class with TimeSpan data type it is required to modify FormatText() method as follows:

//...

else
if (cellData is IConvertible)     // May be it's IConvertible?
{
    // We'll take that, no problem.
    cellText = ((IConvertible)cellData).ToString(this.FormatInfo); 
}
// NEW CODE BEGINS:
else if (this.FormatInfo != null && !(cellData is IFormattable))
{
  cellText = String.Format(this.FormatInfo, "{0:" + this.Format + "}", cellData);
}
// :NEW CODE ENDS
else
{
    cellText = cellData.ToString();// At this point we'll give up and simply call
                                   // ToString()
}
//...

This is because TimeSpan does not implement IFormattable.

Some more links for writing custom formatters:
http://msdn2.microsoft.com/en-us/library/0asazeez.aspx - "Customizing Format Strings"
http://mark.michaelis.net/weblog/2002/11/18.html Posted on Monday, February 4, 2008 5:47 PM | Back to top


Comments on this post: TimeSpan custom formatter - .NET CF 2.0

# re: TimeSpan custom formatter - .NET CF 2.0
Requesting Gravatar...
TimeSpan duration = TimeSpan.Zero;

string str = String.Format("{0:00}:{1:00}:{2:00}", duration.Hours, duration.Minutes, duration.Seconds);


Value of str:
"00:00:00"
Left by John Bianchi on Jul 16, 2009 2:21 PM

# re: TimeSpan custom formatter - .NET CF 2.0
Requesting Gravatar...
John's solution is more correct. A 25 hour duration using the custom formatter will display as 02:01:00 instead of 01:01:00 as it should.
Left by Skip on Jul 16, 2009 6:04 PM

Your comment:
 (will show your gravatar)


Copyright © Martinez | Powered by: GeeksWithBlogs.net