-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*年))

C#にはこれに対する機能がありますか?

DateTime dt1
DateTime dt2

TimeSpan span = dt1- dt2;

上記のようにTimeSpanを解析します(2つのDateTimeの違い)

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 フォーマット文字列を参照してください。

編集:アスカーは、「解析」ではなく「フォーマット」を望んでいることを明らかにしたため、私の答えは関係ないかもしれません。この回答で他に何が問題なのかわかりません。

さて、これが(テストされていない)解決策です。最も重要な部分がゼロの場合だけでなく、「中間」のゼロ部分も削除されます ( 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 チュートリアル

初期化後、これらの DateTime 間の減算を簡単に行うことができます。DateTime difference のリンク

以前のスタイルとの違いをもう一度印刷したい場合:

312 Days 21 Hours 16 Minutes 5 Seconds

DateTimeDifference から日、月などを簡単に取得できます。次に例を示します。

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