web-dev-qa-db-ja.com

TimeSpanに対して24時間を超える時間の文字列を解析する方法は?

30:15のような文字列をC#のTimeSpanに解析する方法は? 30:15は、30時間15分を意味します。

string span = "30:15";
TimeSpan ts = TimeSpan.FromHours(
    Convert.ToDouble(span.Split(':')[0])).
  Add(TimeSpan.FromMinutes(
    Convert.ToDouble((span.Split(':')[1]))));

これはあまりエレガントではないようです。

29
jlp

形式が常に「HH:mm」であることが確実な場合は、次のようにしてみてください。

string span = "35:15";
TimeSpan ts = new TimeSpan(int.Parse(span.Split(':')[0]),    // hours
                           int.Parse(span.Split(':')[1]),    // minutes
                           0);                               // seconds
27
LukeH

ルークの答えに似ています:

String span = "123:45";
Int32 colon = span.IndexOf(':');
TimeSpan timeSpan = new TimeSpan(Int32.Parse(span.Substring(0, colon - 1)),
                                 Int32.Parse(span.Substring(colon + 1)), 0);

明らかに、元の文字列が整形式であると想定しています(コロンで区切られ、整数に解析可能な2つの部分で構成されています)。

4
Erik Burigo

私はずっと前に考案し、今日ブログに投稿した簡単な方法を使用しています。

public static class TimeSpanExtensions
{
    static int[] weights = { 60 * 60 * 1000, 60 * 1000, 1000, 1 };

    public static TimeSpan ToTimeSpan(this string s)
    {
        string[] parts = s.Split('.', ':');
        long ms = 0;
        for (int i = 0; i < parts.Length && i < weights.Length; i++)
            ms += Convert.ToInt64(parts[i]) * weights[i];
        return TimeSpan.FromMilliseconds(ms);
    }
}

これは、以前に提供されたより単純なソリューションよりもはるかに多くの状況を処理できますが、独自の欠点があります。さらに議論します ここ

これで、.NET 4を使用している場合は、ToTimeSpanの実装を次のように短縮できます。

public static TimeSpan ToTimeSpan(this string s)
{
    return TimeSpan.FromMilliseconds(s.Split('.', ':')
        .Zip(weights, (d, w) => Convert.ToInt64(d) * w).Sum());
}

水平方向の画面状態を使用してもかまわない場合は、ワンライナーにすることもできます...

4
Loudenvier

ルークスの答えと同様ですが、コードが多く、改善の余地があります。しかし、それはネガティブアワー( "-30:15")も扱うので、誰かを助けることができるかもしれません。

public static double GetTotalHours(String s)
    {
        bool isNegative = false;
        if (s.StartsWith("-"))
            isNegative = true;

        String[] splitted = s.Split(':');
        int hours = GetNumbersAsInt(splitted[0]);
        int minutes = GetNumbersAsInt(splitted[1]);

        if (isNegative)
        {
            hours = hours * (-1);
            minutes = minutes * (-1);
        }
        TimeSpan t = new TimeSpan(hours, minutes, 0);
        return t.TotalHours;
    }

public static int GetNumbersAsInt(String input)
        {
            String output = String.Empty;
            Char[] chars = input.ToCharArray(0, input.Length);
            for (int i = 0; i < chars.Length; i++)
            {
                if (Char.IsNumber(chars[i]) == true)
                    output = output + chars[i];
            }
            return int.Parse(output);
        }

使用法

double result = GetTotalHours("30:15");
double result2 = GetTotalHours("-30:15");
1
Jan

通常、特定の形式が必要な場合はTimeSpan.ParseExactを使用します。ただし、指定できる時間形式は日の一部としてのみです( カスタムTimeSpan形式文字列 を参照)。

したがって、自分で作業を行う必要があります。

string input = "30:24";
var parts = input.Split(':');
var hours = Int32.Parse(parts[0]);
var minutes = Int32.Parse(parts[1]);
var result = new TimeSpan(hours, minutes, 0);

(ただし、エラーチェックがあります。)

タイムスパンの3整数コンストラクターでは、24時間以上が日数にオーバーフローします。

0
Richard