Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c#

timespan

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.ToDouble(span.Split(':')[0])).
  Add(TimeSpan.FromMinutes(
    Convert.ToDouble((span.Split(':')[1]))));

This does not seem too elegant.

like image 838
jlp Avatar asked Apr 28 '10 09:04

jlp


4 Answers

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
like image 179
LukeH Avatar answered Oct 16 '22 13:10

LukeH


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

like image 21
4 revs, 3 users 67% Avatar answered Oct 16 '22 13:10

4 revs, 3 users 67%


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...

like image 4
Loudenvier Avatar answered Oct 16 '22 13:10

Loudenvier


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");
like image 1
Jan Avatar answered Oct 16 '22 12:10

Jan