TimeSpan的自定义字符串格式

时间:2010-08-20 09:33:09

标签: c# .net timespan date-format

我想用这种方式在C#中格式化TimeSpans:

xxx天(s)yyy hours(s)zzz minute(s)

条件:

  1. 应截断额外秒数

  2. 天是我想要的最大单位。我希望34天显示为34天而不是1个月4天等。

  3. 如果时间跨度不到一天,我不希望这一天出现。同样,如果跨度小于1小时,我只想显示分钟部分。

  4. 有什么方法可以使用内置格式字符串来实现这一点,或者除了编写自己的函数之外别无他法?

    编辑:目前正在使用我自己的功能。它需要TimeSpan在几分钟内作为输入(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);
            }
    

4 个答案:

答案 0 :(得分:6)

在.NET 4.0之前,TimeSpan根本没有格式化选项,您必须通过Ticks属性将其转换为DateTime。在DateTime.String(格式)格式化选项中没有任何远程关闭,你必须自己编写它。

在.NET 4.0中,TimeSpan获得了ToString(格式)覆盖。自定义格式字符串的描述为here。您的第3个要求是需要代码。

答案 1 :(得分:5)

在.NET 3.5及更早版本中,您需要编写自己的函数。

在.NET 4支持中添加了格式TimeSpan的格式,有关详细信息,请参阅TimeSpan.ToString(string)

答案 2 :(得分: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();
    }
}

答案 3 :(得分: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()功能,但它的工作非常好。