2

次の文字列の日付を C# の DateTime オブジェクトに解析するにはどうすればよいですか。

「1970 年 1 月 1 日木曜日」

これは XML フィードからのものであり、DateTime.Parse は en-GB ロケールでそれを好まないようです。フィードは英国のサーバーからのみ取得されるため、グローバル化の問題について心配する必要はありません

私の最初のブルートフォースアプローチは次のとおりです。

  • 「1970 年 1 月 1 日」を残すために、コンマと末尾のスペースまでのすべてを削除します。
  • 次に、「st」、「nd」、「rd」または「th」を適宜削除して、「1970 年 1 月 1 日」のままにします。
  • 次に、「1 1 1970」を残して、月を対応する数値に変換します
  • 次に、スペースを「/」に置き換えて「1/1/1970」を取得します

しかし、はるかにエレガントな方法があるに違いないと確信していますか?DateTime.Prse または Datetime.ParseExact を動作させることができませんでした

4

3 に答える 3

5

これについて少し異なる見方をして、他にいくつかのオプションがあることを示します。DateTime.Parse (または私の例のように TryParse) にフォーマットを指定して、String.Replace呼び出しなどで文字列を別のものに「事前にフォーマット」しようとすることなく、このような状況を考慮することができます。

public DateTime ParseOrdinalDateTime(string dt)
{
    string[] expectedFormats = 

    DateTime d;
    if (DateTime.TryParseExact(dt, "dddd, d\"st\" MMMM yyyy", null, DateTimeStyles.None, out d))
        return d;
    if (DateTime.TryParseExact(dt, "dddd, d\"nd\" MMMM yyyy", null, DateTimeStyles.None, out d))
        return d;
    if (DateTime.TryParseExact(dt, "dddd, d\"rd\" MMMM yyyy", null, DateTimeStyles.None, out d))
        return d;
    if (DateTime.TryParseExact(dt, "dddd, d\"th\" MMMM yyyy", null, DateTimeStyles.None, out d))
        return d;

    throw new InvalidOperationException("Not a valid DateTime string");
}

私がこのアプローチを提案する理由は、それが入力の期待を非常に明確に設定し、単一のメソッドに対する動作を含んでいるためです。フォーマットが変更された場合は、ここで別のフォーマット文字列を指定して、新しい日時文字列構造を考慮することができます。

または、以下のコメントを考慮して、上記のわずかなバリエーション。

private static DateTime ParseOrdinalDateTime(string dt)
{
    string[] expectedFormats = new[]
    {
        "dddd, d'st' MMMM yyyy",
        "dddd, d'nd' MMMM yyyy",
        "dddd, d'rd' MMMM yyyy",
        "dddd, d'th' MMMM yyyy"
    };

    try
    {
        return DateTime.ParseExact(dt, expectedFormats, null, DateTimeStyles.None);
    }
    catch (Exception e)
    {
        throw new InvalidOperationException("Not a valid DateTime string", e);
    }
}

注: 上記の InvalidOperationException をキャッチしてスローする唯一の理由は、スローされるcatch Exception可能性のある例外を処理する必要がないように呼び出し元を保護するためDateTime.ParseExactです。この API は簡単に変更できます。

于 2013-07-17T21:44:58.297 に答える