我需要在C#中将字符串“26h44m3s”解析为TimeSpan。我找不到可以处理它的.NET中实现的任何东西。那么如何以干净的方式完成它呢?这有什么现有的设施吗?
我从Twitch API端点GetVideos上的“duration”属性接收字符串。
答案 0 :(得分:4)
您可以使用正则表达式解析而不使用任何外部依赖项来执行此操作:
public static TimeSpan ParseTwitchTime(string input)
{
var m = Regex.Match(input, @"^((?<hours>\d+)h)?((?<minutes>\d+)m)?((?<seconds>\d+)s)?$", RegexOptions.ExplicitCapture | RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.RightToLeft);
int hs = m.Groups["hours"].Success ? int.Parse(m.Groups["hours"].Value) : 0;
int ms = m.Groups["minutes"].Success ? int.Parse(m.Groups["minutes"].Value) : 0;
int ss = m.Groups["seconds"].Success ? int.Parse(m.Groups["seconds"].Value) : 0;
return TimeSpan.FromSeconds(hs*60*60 + ms*60 + ss);
}
用法:
var d = ParseTwitchTime("100h");
d = ParseTwitchTime("23m1000s");
d = ParseTwitchTime("12345h678s");
PS:RightToLeft选项仅用于正则表达式性能而不影响输出结果(如果没有它,则会回溯很多)。
答案 1 :(得分:2)
您可以使用Noda Time进行解析,解析为Duration
。您可以然后将其转换为TimeSpan
- 或者您可以在任何地方使用Noda Time并获得更好的体验:)
示例代码:
using System;
using NodaTime;
using NodaTime.Text;
class Program
{
static void Main()
{
string text = "26h44m3s";
var pattern = DurationPattern.CreateWithInvariantCulture("H'h'm'm's's'");
var duration = pattern.Parse(text).Value;
Console.WriteLine(duration);
var ts = duration.ToTimeSpan();
Console.WriteLine(ts);
}
}
如果您有多个需要匹配的模式,则可以创建复合模式 - 尽管您需要明确列出所有模式。这是一个例子:
using System;
using System.Linq;
using NodaTime;
using NodaTime.Text;
class Program
{
static void Main()
{
string[] formats =
{
"H'h'm'm's's'", "H'h'm'm'", "M'm's's'", "H'h'", "M'm'", "S's'"
};
var patterns = formats.Select(DurationPattern.CreateWithInvariantCulture);
var builder = new CompositePatternBuilder<Duration>();
foreach (var pattern in patterns)
{
// The second parameter is used to choose which pattern is
// used for formatting. Let's ignore it for now.
builder.Add(pattern, _ => true);
}
var composite = builder.Build();
string[] values = { "26h8m", "26h", "15s", "56m47s" };
foreach (var value in values)
{
Console.WriteLine(composite.Parse(value).Value);
}
}
}