自定义字符串格式
问题描述:
我想以这种方式来格式化C#的时间跨度:自定义字符串格式
XXX天(S)YYY小时(S)ZZZ分钟
条件:
额外秒数应该被截断
天(s)是我想要的最大单位。我想34天出现34天,而不是1个月4天等。
如果时间跨度少于一天,我不希望一天的部分出现。同样,如果跨度小于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);
}
答
不幸的是,.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
答
至少在.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();
}
}
我只是好奇......如果天数大于零但小时数为零会发生什么?例如,你会显示“XX天,0小时,YY分钟”还是显示“XX天,YY分钟”?你的代码似乎是做前者的。 – 2010-08-20 10:39:14
是的,在这种情况下,我希望显示0小时.. – 2010-08-20 11:10:12