C# 如何解析小时数大于24到TimeSpan的字符串?

C# 如何解析小时数大于24到TimeSpan的字符串?,c#,timespan,C#,Timespan,如何在C#中解析30:15到TimeSpan这样的字符串?30:15意味着30小时15分钟 string span = "30:15"; TimeSpan ts = TimeSpan.FromHours( Convert.ToDouble(span.Split(':')[0])). Add(TimeSpan.FromMinutes( Convert.ToDouble((span.Split(':')[1])))); 这似乎不太优雅 如果您确定格式始终为“HH:mm”,请尝试

如何在C#中解析30:15到TimeSpan这样的字符串?30:15意味着30小时15分钟

string span = "30:15";
TimeSpan ts = TimeSpan.FromHours(
    Convert.ToDouble(span.Split(':')[0])).
  Add(TimeSpan.FromMinutes(
    Convert.ToDouble((span.Split(':')[1]))));

这似乎不太优雅

如果您确定格式始终为“HH:mm”,请尝试以下操作:

string span = "35:15";
TimeSpan ts = new TimeSpan(int.Parse(span.Split(':')[0]),    // hours
                           int.Parse(span.Split(':')[1]),    // minutes
                           0);                               // seconds

在需要特定格式的地方,通常会使用
TimeSpan.ParseExact
。但是,唯一可以指定的小时格式是作为天的一部分(请参阅)

因此,您需要自己完成工作:

string input = "30:24";
var parts = input.Split(':');
var hours = Int32.Parse(parts[0]);
var minutes = Int32.Parse(parts[1]);
var result = new TimeSpan(hours, minutes, 0);
(但需要进行一些错误检查。)


timespan的三个整数构造函数允许小时数>=24溢出到天数计数中。

类似于Luke的答案:

String span = "123:45";
Int32 colon = span.IndexOf(':');
TimeSpan timeSpan = new TimeSpan(Int32.Parse(span.Substring(0, colon - 1)),
                                 Int32.Parse(span.Substring(colon + 1)), 0);

显然,它假定原始字符串格式正确(由冒号分隔的两部分组成,可解析为整数)。

我使用的是一种很早以前设计的简单方法,今天刚刚发布到我的博客上:

public static class TimeSpanExtensions
{
    static int[] weights = { 60 * 60 * 1000, 60 * 1000, 1000, 1 };

    public static TimeSpan ToTimeSpan(this string s)
    {
        string[] parts = s.Split('.', ':');
        long ms = 0;
        for (int i = 0; i < parts.Length && i < weights.Length; i++)
            ms += Convert.ToInt64(parts[i]) * weights[i];
        return TimeSpan.FromMilliseconds(ms);
    }
}

如果您不介意使用水平屏幕状态,您甚至可以将其设置为一行…

类似于Lukes answer,有更多代码和改进空间。但它也会在几个小时(“-30:15”)内处理负面信息,所以也许它可以帮助一些人

public static double GetTotalHours(String s)
    {
        bool isNegative = false;
        if (s.StartsWith("-"))
            isNegative = true;

        String[] splitted = s.Split(':');
        int hours = GetNumbersAsInt(splitted[0]);
        int minutes = GetNumbersAsInt(splitted[1]);

        if (isNegative)
        {
            hours = hours * (-1);
            minutes = minutes * (-1);
        }
        TimeSpan t = new TimeSpan(hours, minutes, 0);
        return t.TotalHours;
    }

public static int GetNumbersAsInt(String input)
        {
            String output = String.Empty;
            Char[] chars = input.ToCharArray(0, input.Length);
            for (int i = 0; i < chars.Length; i++)
            {
                if (Char.IsNumber(chars[i]) == true)
                    output = output + chars[i];
            }
            return int.Parse(output);
        }
基于

.NET 5

    /// <summary>
    /// 1 number : hours    "0" to "0:0:0" ,    "-1" to "-01:00:00"
    /// 2 numbers : hours, minutes    "1:2" to "01:02:00"
    /// 3 numbers : hours, minutes, seconds    "1:2:3" to "01:02:03"
    /// 4 numbers : days, hours, minutes, seconds    "1:2:3:4" to "1.02:03:04"
    /// Any char can be used as separator.    "1,2 3aaaa4" to "1.02:03:04"
    /// </summary>
    /// <param name="timeSpanString"></param>
    /// <param name="ts"></param>
    /// <returns>true : conversion succeeded</returns>
    public static bool GetTimeSpan(string timeSpanString, ref TimeSpan ts)
    {

        bool isNegative = timeSpanString.StartsWith("-"); // "-1:2:3" is true
        var digitsString = Regex.Replace(timeSpanString, "[^0-9]", " "); // "-1:2:3" to " 1 2 3" 
        var s = digitsString.Split(' ', StringSplitOptions.RemoveEmptyEntries); // "1","2","3"

        int days = 0;
        int hours = 0;
        int minutes = 0;
        int seconds = 0;

        switch (s.Length)
        {
            case 1:
                hours = int.Parse(s[0]);
                break;

            case 2:
                hours = int.Parse(s[0]);
                minutes = int.Parse(s[1]);
                break;

            case 3:
                hours = int.Parse(s[0]);
                minutes = int.Parse(s[1]);
                seconds = int.Parse(s[2]);
                break;

            case 4:
                days = int.Parse(s[0]);
                hours = int.Parse(s[1]);
                minutes = int.Parse(s[2]);
                seconds = int.Parse(s[3]);
                break;

            default:
                return false; //no digits or length > 4
        }

        if (isNegative)
        {
            ts = new TimeSpan(-days, -hours, -minutes, -seconds);
        }
        else
        {
            ts = new TimeSpan(days, hours, minutes, seconds);
        }

        return true;
    }
//
///1小时数:小时数“0”至“0:0:0”、“-1”至“-01:00:00”
///2个数字:小时、分钟“1:2”到“01:02:00”
///3个数字:小时、分钟、秒“1:2:3”到“01:02:03”
///4个数字:天、小时、分钟、秒“1:2:3:4”到“1.02:03:04”
///任何字符都可以用作分隔符。“1,2 3AAA4”至“1.02:03:04”
/// 
/// 
/// 
///true:转换成功
公共静态bool GetTimeSpan(字符串TimeSpan字符串,ref TimeSpan ts)
{
bool isNegative=timespan字符串。StartsWith(“-”;/“-1:2:3”为真
var digitstring=Regex.Replace(timespan字符串,[^0-9],”);/“-1:2:3”到“1:2:3”
var s=digitsString.Split(“”,StringSplitOptions.RemoveEmptyEntries);/“1”、“2”、“3”
整数天=0;
整小时=0;
整数分钟=0;
整数秒=0;
开关(s.长度)
{
案例1:
小时=int.Parse(s[0]);
打破
案例2:
小时=int.Parse(s[0]);
分钟=int.Parse(s[1]);
打破
案例3:
小时=int.Parse(s[0]);
分钟=int.Parse(s[1]);
秒=int.Parse(s[2]);
打破
案例4:
天数=int.Parse(s[0]);
小时=int.Parse(s[1]);
分钟=int.Parse(s[2]);
秒=int.Parse(s[3]);
打破
违约:
返回false;//没有数字或长度大于4
}
如果(为负)
{
ts=新的时间跨度(-天、-h、-min、-s);
}
其他的
{
ts=新的时间跨度(天、小时、分钟、秒);
}
返回true;
}

将时间跨度转换为24小时以上的数字。TimeSpan转换器,文本框规则。

我想Luke的一个处理>99,不是吗?@Erik,@jlp:是的,我的处理小时数大于99很好,尽管我最初的答案没有(在我半小时前编辑它之前)。也许埃里克在看老答案。@Luke:是的!正如你在这里回答的;)@ErikBurigo您的解决方案不起作用,如果span是“99:00”,那么您发送到解析函数的字符串将是“9”和“:00”,正如我刚才在代码.net 4.5中测试的那样。代码如下:请看这个(重复)。它需要支持本地化吗?(例如,根据语言设置为30.15)格式将始终为hh:mm,但hh可能恰好大于24。这在负时间跨度下不起作用(-35:15将导致-34:45)c#timespan有效,但如何将此值存储在MSSQL中?时间(7)不起作用,字符串也不会那么好。如果问题与问题中描述的完全一样,那么解决方案是可以的。但如果TimeSpan字符串值类似于“1.06:00:00”,则此解决方案将失败。不幸的是,解释缺陷的链接不起作用。也许这个问题已经在那里讨论过了。@Florian我正在把我的博客转移到一个新的(更好的)主机上,这就是为什么现在它是离线的!它不支持天,只支持小时。所以,如果你想要24+6小时,你必须使用30:00:00。这个想法是为了避免完全使用天数。缺点更多地与不支持负面价值有关。。。
double result = GetTotalHours("30:15");
double result2 = GetTotalHours("-30:15");
    /// <summary>
    /// 1 number : hours    "0" to "0:0:0" ,    "-1" to "-01:00:00"
    /// 2 numbers : hours, minutes    "1:2" to "01:02:00"
    /// 3 numbers : hours, minutes, seconds    "1:2:3" to "01:02:03"
    /// 4 numbers : days, hours, minutes, seconds    "1:2:3:4" to "1.02:03:04"
    /// Any char can be used as separator.    "1,2 3aaaa4" to "1.02:03:04"
    /// </summary>
    /// <param name="timeSpanString"></param>
    /// <param name="ts"></param>
    /// <returns>true : conversion succeeded</returns>
    public static bool GetTimeSpan(string timeSpanString, ref TimeSpan ts)
    {

        bool isNegative = timeSpanString.StartsWith("-"); // "-1:2:3" is true
        var digitsString = Regex.Replace(timeSpanString, "[^0-9]", " "); // "-1:2:3" to " 1 2 3" 
        var s = digitsString.Split(' ', StringSplitOptions.RemoveEmptyEntries); // "1","2","3"

        int days = 0;
        int hours = 0;
        int minutes = 0;
        int seconds = 0;

        switch (s.Length)
        {
            case 1:
                hours = int.Parse(s[0]);
                break;

            case 2:
                hours = int.Parse(s[0]);
                minutes = int.Parse(s[1]);
                break;

            case 3:
                hours = int.Parse(s[0]);
                minutes = int.Parse(s[1]);
                seconds = int.Parse(s[2]);
                break;

            case 4:
                days = int.Parse(s[0]);
                hours = int.Parse(s[1]);
                minutes = int.Parse(s[2]);
                seconds = int.Parse(s[3]);
                break;

            default:
                return false; //no digits or length > 4
        }

        if (isNegative)
        {
            ts = new TimeSpan(-days, -hours, -minutes, -seconds);
        }
        else
        {
            ts = new TimeSpan(days, hours, minutes, seconds);
        }

        return true;
    }