我如何解析时差作为这样的字符串
本文关键字:字符串 何解析 时差 | 更新日期: 2023-09-27 17:49:49
我想解析2个DateTime差异,如下所示:
312 Days 21 Hours 16 Minutes 5 Seconds // there is difference > days
21 Hours 16 Minutes 5 Seconds // there is difference > hours
16 Minutes 5 Seconds // there is difference > minutes
5 Seconds // there is difference < minutes
如果有天以上的差异,它将解析天;如果有小时以上的差异,它将解析小时,以此类推。如果存在年份差异,我仍然希望将其解析为天数(days difference + (365*year))
c#有这样的功能吗?
DateTime dt1
DateTime dt2
TimeSpan span = dt1- dt2;
和解析TimeSpan如上(两个DateTimes之间的差异)
这里有一些可能会有所帮助:
string[] formats = {
"d' Days 'h' Hours 'm' Minutes 's' Seconds'",
"h' Hours 'm' Minutes 's' Seconds'",
"m' Minutes 's' Seconds'",
"s' Seconds'",
"d' Days 'h' Hours 'm' Minutes'",
"d' Days 'h' Hours 's' Seconds'",
"d' Days 'm' Minutes 's' Seconds'",
"h' Hours 'm' Minutes'",
"h' Hours 's' Seconds'",
};
var result = TimeSpan.ParseExact(yourString, formats, CultureInfo.CurrentCulture);
如果你担心yourString
有时是非法的,还有TryParseExact
。详情请参见自定义时间跨度格式字符串。
编辑:提问者已经澄清他确实想要"格式化",而不是"解析",所以我的回答可能不相关。我不确定这个答案还有什么问题。
现在,这里有一个(未经测试的)解决方案。除零部分外,除最重要部分为零部分外,除"中间"部分(01:00:01
)为零部分。语法(复数和单数)应该没问题。中间和末尾的空格应该正确。放入static
类(扩展方法):
public static string ToMyString(this TimeSpan ts)
{
if (ts < TimeSpan.Zero)
throw new ArgumentOutOfRangeException();
var parts = new List<string>();
AddPart(parts, ts.Days, "Day");
AddPart(parts, ts.Hours, "Hour");
AddPart(parts, ts.Minutes, "Minute");
AddPart(parts, ts.Seconds, "Second");
if (parts.Count == 0)
return "0";
return string.Join(" ", parts);
}
static void AddPart(List<string> parts, int number, string name)
{
if (number == 1)
parts.Add("1 " + name);
else if (number > 1)
parts.Add(string.Format("{0} {1}s", number, name));
}
这比预期的要困难得多:
List<string> timespanStrings = new List<string>() {
"312 Days 21 Hours 16 Minutes 5 Seconds", "21 Hours 16 Minutes 5 Seconds",
"16 Minutes 5 Seconds", "5 Seconds"
};
List<TimeSpan> timespans = new List<TimeSpan>();
foreach (string tsString in timespanStrings)
{
List<Tuple<int, string>> pairs = new List<Tuple<int, string>>();
var tokens = tsString.Split();
if (tokens.Length % 2 == 0)
{
int duration;
for (int i = 0; i < tokens.Length; i += 2)
{
string dur = tokens[i];
string unit = tokens[i + 1];
if (int.TryParse(dur, out duration))
{
pairs.Add(Tuple.Create(duration, unit));
}
else // invalid string
break;
}
}
// create the TimeSpan from the pair
switch (pairs.Count)
{
case 4: // days
{
var dayPair = pairs.First(p => p.Item2.Equals("Days", StringComparison.OrdinalIgnoreCase));
TimeSpan ts = TimeSpan.FromDays(dayPair.Item1);
var hourPair = pairs.First(p => p.Item2.Equals("Hours", StringComparison.OrdinalIgnoreCase));
TimeSpan tsHour = TimeSpan.FromHours(hourPair.Item1);
var minPair = pairs.First(p => p.Item2.Equals("Minutes", StringComparison.OrdinalIgnoreCase));
TimeSpan tsMin = TimeSpan.FromMinutes(minPair.Item1);
var secPair = pairs.First(p => p.Item2.Equals("Seconds", StringComparison.OrdinalIgnoreCase));
TimeSpan tsSec = TimeSpan.FromSeconds(secPair.Item1);
ts = ts + tsHour + tsMin + tsSec;
timespans.Add(ts);
break;
}
case 3: // hours
{
var hourPair = pairs.First(p => p.Item2.Equals("Hours", StringComparison.OrdinalIgnoreCase));
TimeSpan ts = TimeSpan.FromHours(hourPair.Item1);
var minPair = pairs.First(p => p.Item2.Equals("Minutes", StringComparison.OrdinalIgnoreCase));
TimeSpan tsMin = TimeSpan.FromMinutes(minPair.Item1);
var secPair = pairs.First(p => p.Item2.Equals("Seconds", StringComparison.OrdinalIgnoreCase));
TimeSpan tsSec = TimeSpan.FromSeconds(secPair.Item1);
ts = ts + tsMin + tsSec;
timespans.Add(ts);
break;
}
case 2: // minutes
{
var minPair = pairs.First(p => p.Item2.Equals("Minutes", StringComparison.OrdinalIgnoreCase));
TimeSpan ts = TimeSpan.FromMinutes(minPair.Item1);
var secPair = pairs.First(p => p.Item2.Equals("Seconds", StringComparison.OrdinalIgnoreCase));
TimeSpan tsSec = TimeSpan.FromSeconds(secPair.Item1);
ts = ts + tsSec;
timespans.Add(ts);
break;
}
case 1: // seconds
timespans.Add(TimeSpan.FromSeconds(pairs[0].Item1));
break;
default:
break;
}
}
public static string ToFullString(this TimeSpan timeSpan)
{
return
(timeSpan.Days > 0 ? timeSpan.Days + " Days" : "") +
(timeSpan.Hours > 0 ? " " + timeSpan.Hours + "Hours " : "") +
(timeSpan.Minutes > 0 ? " " + timeSpan.Minutes + "Minutes " : "") +
(timeSpan.Seconds > 0 ? " " + timeSpan.Seconds + "Seconds" : "");
}
如果你的输入是这样的:
312 Days 21 Hours 16 Minutes 5 Seconds
答案是否定的。您必须自己解析字符串并初始化DateTime变量。简单明了的c#日期时间教程。
初始化之后,可以很容易地在这些DateTimes之间做减法。日期时差链接。
如果你想再次打印出与之前样式的差异:
312 Days 21 Hours 16 Minutes 5 Seconds
很容易从DateTimeDifference中获得日期,月份等,例如:
DateTime yourDateTime = foo;
int month = yourDateTime.Month;