Reputation: 10358
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.
Upvotes: 33
Views: 24420
Reputation: 317
Similar to Luke's answer:
String span = "123:45";
Int32 colon = span.IndexOf(':');
TimeSpan timeSpan = new TimeSpan(Int32.Parse(span.Substring(0, colon)),
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).
Upvotes: 5
Reputation: 61
Based on Jan's Answer
.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;
}
TimeSpanHelper Convert TimeSpan to over 24 hours number. TimeSpan Converter, Rule for TextBox.
Upvotes: 1
Reputation: 333
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");
Upvotes: 1
Reputation: 269388
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
Upvotes: 38
Reputation: 8794
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...
Upvotes: 4
Reputation: 109015
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.
Upvotes: 0