-4

我想解析 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

因此,如果天数以上有差异,它将解析天数,如果小时数以上有差异,它将解析小时数,依此类推。如果有不同年份,我仍然希望它解析为天数(天数差异 +(365*year))

C# 对此有什么功能吗?

DateTime dt1
DateTime dt2

TimeSpan span = dt1- dt2;

并按上述方式解析 TimeSpan(2 个 DateTimes 之间的差异)

4

4 回答 4

2

这可能会有所帮助:

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

TryParseExact如果您担心yourString有时可能是非法的,还有。有关详细信息,请参阅自定义 TimeSpan 格式字符串

编辑: Asker 澄清说他确实想要“格式化”,而不是“解析”,所以我的回答可能不相关。不知道这个答案还有什么问题。

现在,这是一个(未经测试的)解决方案。零部分被删除,不仅在最重要的部分为零时,而且在“中间”( 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));        
}
于 2012-12-30T00:04:42.553 回答
2

这比预期的要困难:

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;
    }
}
于 2012-12-30T00:09:46.553 回答
1
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" : "");
}
于 2012-12-29T23:58:45.410 回答
1

如果您的输入如下:

312 Days 21 Hours 16 Minutes 5 Seconds

答案是否定的。您必须自己解析字符串并初始化 DateTime 变量。简单明了的 c# DateTime 教程

初始化后,您可以轻松地在这些日期时间之间进行减法。日期时间差异的链接

如果您想使用以前的样式再次打印出差异:

312 Days 21 Hours 16 Minutes 5 Seconds

从 DateTimeDifference 中获取 Days、Month 等很容易,例如:

DateTime yourDateTime = foo;
int month = yourDateTime.Month;
于 2012-12-30T00:06:25.173 回答