How to Parse String with Hours Greater Than 24 to Timespan

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

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

How to Convert string 07:35 (HH:MM) to TimeSpan

While correct that this will work:

TimeSpan time = TimeSpan.Parse("07:35");

And if you are using it for validation...

TimeSpan time;
if (!TimeSpan.TryParse("07:35", out time))
{
// handle validation error
}

Consider that TimeSpan is primarily intended to work with elapsed time, rather than time-of-day. It will accept values larger than 24 hours, and will accept negative values also.

If you need to validate that the input string is a valid time-of-day (>= 00:00 and < 24:00), then you should consider this instead:

DateTime dt;
if (!DateTime.TryParseExact("07:35", "HH:mm", CultureInfo.InvariantCulture,
DateTimeStyles.None, out dt))
{
// handle validation error
}
TimeSpan time = dt.TimeOfDay;

As an added benefit, this will also parse 12-hour formatted times when an AM or PM is included, as long as you provide the appropriate format string, such as "h:mm tt".

Parse a TimeSpan greater than 24 hours?

I'm not sure it can be done using standard TimeSpan.Parse() method, but you can do that:

public static decimal Hours(string s)
{
decimal r;
if (decimal.TryParse(s, out r))
return r;

var parts = s.Split(':');
return (decimal)new TimeSpan(int.Parse(parts[0]), int.Parse(parts[1]),0).TotalHours;
}

Parsing times above 24 hours in C#

Since you're trying to represent a period of time from an arbitrary point, rather than as a specific date, perhaps you would be better off using the System.TimeSpan class? This allows you to set values of more than 24 hours in the constructor, and can be used with DateTime objects like this:

System.TimeSpan timestamp = new System.TimeSpan(25, 0, 0);
System.DateTime parsedDateTime = new DateTime(0, 0, 0);
parsedDateTime = parsedDateTime.Add(timestamp);
Console.WriteLine(parsedDateTime.ToString("yyyy-MM-dd HH:mm:ss")); //Output as "0001-01-02 01:00:00"

NOTE: Code is untested.

EDIT: In terms of parsing the strings, I can't think of any basic .NET objects that parse strings with values greater than 23 for the hour (since 25 is an invalid hour of the day), but assuming that the format is consistent, you could create a very simple string parsing routine (or even a regular expression) to read the values individually, and load the constructor manually.

Any workaround to TimeSpan.ParseExact with more than 59 seconds?

Ok guys, I ended up with this custom method to do the work.

It's not a method to execute many times in a row because of the huge performance issues it will have, but to parse the introduced data from the front end it's more than acceptable:

    /// <summary>
/// Given a time and a format it creates a <see cref="TimeSpan"/> ignoring the format digit limitations.
/// The format is not validated, so better ensure a correct one is provided ;)
/// </summary>
/// <param name="time"></param>
/// <param name="format"></param>
/// <param name="timeSpan"></param>
/// <returns></returns>
public static bool TryParseTime(string time, string format, out TimeSpan timeSpan)
{
// Regex to match the components of the time format (ss:fff matches ss and fff)
var formatRegex = new Regex(@"(?<=(?<!\\)(?:\\{2})*)(%?([fFsmhd])(\2*))");
var matches = formatRegex.Matches(format);
if (matches.Count > 0)
{
// We build a big regex to extract the values from time
string formatExtractionRegex = string.Empty;
int pivot = 0;
foreach (Match match in matches)
{
if (match.Success)
{
char c = match.Value.ToLower()[0];
formatExtractionRegex += $@"{format.Substring(pivot, match.Index - pivot)}(?<{c}>\d+)";

pivot = match.Index + match.Length;
}
}

var timeParts = new Regex(formatExtractionRegex).Match(time);
int d, h, m, s, f;
int.TryParse(timeParts.Groups["d"].ToString(), out d);
int.TryParse(timeParts.Groups["h"].ToString(), out h);
int.TryParse(timeParts.Groups["m"].ToString(), out m);
int.TryParse(timeParts.Groups["s"].ToString(), out s);
int.TryParse(timeParts.Groups["f"].ToString(), out f);
timeSpan = new TimeSpan(d, h, m, s, f);
return true;
}

timeSpan = default;
return false;
}

The method extracts the data from the time by building a big regex that replaces the digit type for the regex expression \d+, so we select entire digit groups when they are longer than what the format specifies.

If we provide a time 100:100:5000 and a format mm\:ss\:fff, the generated regex will be (?<m>\\d+)\\:(?<s>\\d+)\\:(?<f>\\d+).

Finally we parse the matched groups and we parse them to be given to the TimeSpan Constructor.

Parse TimeSpan 1:00 and 01:00

Solution from @phuzi worked

I now use multiple Formats which it tries to Parse now works like a Charm.

TimeSpan.ParseExact(txtManStunden.Text, new[] { "hh':'mm", "hhh':'mm", "h':'mm", "h", "hh" }, null).TotalHours.ToString("0.00");

I cant Parse Hours Greater than 24 now, any way to fix it withouth breaking the current formating?

Format TimeSpan greater than 24 hour

Well, the simplest thing to do is to format this yourself, e.g.

return string.Format("{0}hr {1}mn {2}sec",
(int) span.TotalHours,
span.Minutes,
span.Seconds);

In VB:

Public Shared Function FormatTimeSpan(span As TimeSpan) As String
Return String.Format("{0}hr {1}mn {2}sec", _
CInt(Math.Truncate(span.TotalHours)), _
span.Minutes, _
span.Seconds)
End Function

I don't know whether any of the TimeSpan formatting in .NET 4 would make this simpler.

Convert 24-hour string value to timespan

Use

TimeSpan span = TimeSpan.ParseExact("1600", new string[] {"hhmm", @"hh\:mm"}, CultureInfo.InvariantCulture);

HH:MM:SS format getting converted to days instead of hours

That is not possible. What you want to enter is absolute hours. There is no format string for parsing that. Hours can only be between 0 and 23.

You will need to parse the input yourself into Int32 variables and pass them to the timespan constructor.



Related Topics



Leave a reply



Submit