How to parse string with hours greater than 24 to TimeSpan?

前端 未结 5 1624
一生所求
一生所求 2020-11-29 07:58

How to parse string like 30:15 to TimeSpan in C#? 30:15 means 30 hours and 15 minutes.

string span = \"30:15\";
TimeSpan ts = TimeSpan.FromHours(
    Convert         


        
相关标签:
5条回答
  • 2020-11-29 08:32

    I'm using a simple method that I devised a long time ago and just posted today to my blog:

    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);
        }
    }
    

    This can handle a lot more situations than the simpler solutions provided before, but has its own shortcomings. I discuss it further here.

    Now, if you're in .NET 4 you can shorten the ToTimeSpan implementation to:

    public static TimeSpan ToTimeSpan(this string s)
    {
        return TimeSpan.FromMilliseconds(s.Split('.', ':')
            .Zip(weights, (d, w) => Convert.ToInt64(d) * w).Sum());
    }
    

    You can even make it an one-liner if you don't mind using horizontal screen state...

    0 讨论(0)
  • 2020-11-29 08:32

    Similar to Lukes answer, with a lot more code and room for improvement. BUT it deals with negatives Hours ("-30:15") aswell, so maybe it can help someone.

    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);
            }
    

    usage

    double result = GetTotalHours("30:15");
    double result2 = GetTotalHours("-30:15");
    
    0 讨论(0)
  • 2020-11-29 08:33

    If you're certain that the format will always be "HH:mm" then try something like this:

    string span = "35:15";
    TimeSpan ts = new TimeSpan(int.Parse(span.Split(':')[0]),    // hours
                               int.Parse(span.Split(':')[1]),    // minutes
                               0);                               // seconds
    
    0 讨论(0)
  • 2020-11-29 08:33

    Normally one would use TimeSpan.ParseExact where a specific format is required. But the only hours formats that can be specified are as parts of days (see Custom TimeSpan Format Strings).

    Therefore you will need to do the work yourself:

    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);
    

    (But with some error checking.)

    The three integer constructor of timespan allows hours >= 24 overflowing into the days count.

    0 讨论(0)
  • 2020-11-29 08:53

    Similar to Luke's answer:

    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);
    

    Obviously it assumes the original string is well-formed (composed of two parts separated by colon and parsable to an integer number).

    0 讨论(0)
提交回复
热议问题