我如何解析时差作为这样的字符串

时间:2012-12-29 23:28:27

标签: c# string parsing datetime datetime-format

我想解析下面的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 *年))

C#对此有什么作用吗?

DateTime dt1
DateTime dt2

TimeSpan span = dt1- dt2;

如上所述解析TimeSpan(2个DateTimes之间的差异)

4 个答案:

答案 0 :(得分: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。有关详细信息,请参阅Custom TimeSpan Format Strings

编辑: 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));        
}

答案 1 :(得分: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;
    }
}

答案 2 :(得分: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" : "");
}

答案 3 :(得分:1)

如果您的输入如下:

312 Days 21 Hours 16 Minutes 5 Seconds

答案是否定的。您必须解析字符串并自己初始化DateTime变量。 Simple and clear DateTime tutorial for c#

初始化后,您可以轻松地在这些DateTime之间进行减法。 Link for DateTime difference

如果您想再次使用之前的风格打印出差异:

312 Days 21 Hours 16 Minutes 5 Seconds

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

DateTime yourDateTime = foo;
int month = yourDateTime.Month;
相关问题