2010-08-20 101 views
4

我想以這種方式來格式化C#的時間跨度:自定義字符串格式

XXX天(S)YYY小時(S)ZZZ分鐘

條件:

  1. 額外秒數應該被截斷

  2. 天(s)是我想要的最大單位。我想34天出現34天,而不是1個月4天等。

  3. 如果時間跨度少於一天,我不希望一天的部分出現。同樣,如果跨度小於1小時,我只需要顯示分鐘部分。

有沒有什麼辦法可以做到這一點使用內置的格式字符串或沒有辦法,除了寫我自己的功能?

編輯:目前使用我自己的這個功能。這需要時間跨度以分鐘爲輸入(TimeSpan.TotalMinutes)

private static string GetTimeStringFromMinutes(double p) 
     { 
      var minutes = (int) p; 
      int hours = minutes/60; 
      minutes = minutes % 60; 
      int days = hours/24; 
      hours = hours%24; 
      string dayPart = days + " day(s) "; 
      string hoursPart = hours + " hour(s) "; 
      string minutesPart = minutes + " minute(s)"; 
      if (days != 0) 
       return (dayPart + hoursPart + minutesPart); 
      if (hours != 0) 
       return (hoursPart + minutesPart); 
      return (minutesPart); 
     } 
+0

我只是好奇......如果天數大於零但小時數爲零會發生什麼?例如,你會顯示「XX天,0小時,YY分鐘」還是顯示「XX天,YY分鐘」?你的代碼似乎是做前者的。 – 2010-08-20 10:39:14

+0

是的,在這種情況下,我希望顯示0小時.. – 2010-08-20 11:10:12

回答

6

TimeSpan在.NET 4.0之前根本沒有任何格式化選項,您必須通過Ticks屬性將其轉換爲DateTime。儘管沒有在DateTime.String(格式)格式化選項中遠程關閉,但您必須親自編寫它。

在.NET 4.0中,TimeSpan獲取了ToString(格式)覆蓋。自定義格式字符串描述here。你的第三個需求將需要代碼。

+0

+1提到在.NET 4.0之前沒有TimeSpan格式。我不知道,並且當我不能在.NET 2.0項目中使用它時,我會浪費時間來弄清楚我需要什麼格式字符串。 – Jim 2013-07-19 18:01:40

5

在.NET 3.5和更早的版本,你需要編寫自己的功能。

在.NET 4中增加了對格式化TimeSpan的支持,請參閱TimeSpan.ToString(string)瞭解詳細信息。

2

不幸的是,.Net中沒有任何東西直接可用。至於我自己,我已經解決了這個問題是這樣的:

public static class TimeSpanExtensions 
{ 
    public static string ToDetailedString(this TimeSpan timeSpan) 
    { 
     if (timeSpan == null) 
      throw new ArgumentNullException("timeSpan"); 

     var sb = new StringBuilder(30); 

     var current = timeSpan.ToDaysString(); 

     if (!String.IsNullOrEmpty(current)) 
      sb.Append(current); 

     current = timeSpan.ToHoursString(); 

     if (!String.IsNullOrEmpty(current)) 
     { 
      if (sb.Length > 0) 
       sb.Append(" "); 

      sb.Append(current); 
     } 

     current = timeSpan.ToMinutesString(); 

     if (!String.IsNullOrEmpty(current)) 
     { 
      if (sb.Length > 0) 
       sb.Append(" "); 

      sb.Append(current); 
     } 

     return sb.ToString(); 
    } 

    public static string ToDaysString(this TimeSpan timeSpan) 
    { 
     if (timeSpan == null) 
      throw new ArgumentNullException("timeSpan"); 

     int days = (int)timeSpan.TotalDays; 

     switch (days) 
     { 
      case 0: 
       return String.Empty; 
      case 1: 
       return "1 day"; 
      default: 
       return days + " days"; 
     } 
    } 

    public static string ToHoursString(this TimeSpan timeSpan) 
    { 
     if (timeSpan == null) 
      throw new ArgumentNullException("timeSpan"); 

     switch (timeSpan.Hours) 
     { 
      case 0: 
       return String.Empty; 
      case 1: 
       return "1 hour"; 
      default: 
       return timeSpan.Hours + " hours"; 
     } 
    } 

    public static string ToMinutesString(this TimeSpan timeSpan) 
    { 
     if (timeSpan == null) 
      throw new ArgumentNullException("timeSpan"); 

     switch (timeSpan.Minutes) 
     { 
      case 0: 
       return String.Empty; 
      case 1: 
       return "1 minute"; 
      default: 
       return timeSpan.Minutes + " minutes"; 
     } 
    } 
} 

也許這不是最優雅的解決方案,我認爲這是可以做到特別是在ToDetailedString()功能有所改善,但它的作品精美絕倫。

+0

我現在也在使用我自己的方法,這需要Timespan在幾分鐘內作爲輸入...編輯以包含在我的問題中 – 2010-08-20 10:28:33

3

至少在.NET 3.5中沒有任何內置的方式來滿足您的需求。這是一個擴展TimeSpan以提供所需功能的類。

public static class TimeSpanEx 
{ 
    public static string FormattedString(this TimeSpan ts) 
    { 
     int days = (int)ts.TotalDays; 
     int hrs = (int)ts.Hours; 
     int mins = (int)ts.Minutes; 
     StringBuilder sb = new StringBuilder(); 

     if (days > 0) 
     { 
      sb.Append(days.ToString() + (days == 1 ? " day, " : " days, ")); 
     } 

     if (hrs > 0 || days > 0) 
     { 
      sb.Append(hrs.ToString() + (hrs == 1 ? " hour, " : " hours, ")); 
     } 

     sb.Append(mins.ToString() + (mins == 1 ? " min" : " mins")); 

     return sb.ToString(); 
    } 
}