ToString()でnull可能なDateTimeをフォーマットするにはどうすればよいですか?


226

null可能なDateTime dt2をフォーマットされた文字列に変換するにはどうすればよいですか?

DateTime dt = DateTime.Now;
Console.WriteLine(dt.ToString("yyyy-MM-dd hh:mm:ss")); //works

DateTime? dt2 = DateTime.Now;
Console.WriteLine(dt2.ToString("yyyy-MM-dd hh:mm:ss")); //gives following error:

メソッドToStringへのオーバーロードは引数を1つ取りません


3
こんにちは、承認された現在の回答を確認していただけませんか?より関連性の高い今日の答えがより正しいかもしれません。
iuliu.net

回答:


335
Console.WriteLine(dt2 != null ? dt2.Value.ToString("yyyy-MM-dd hh:mm:ss") : "n/a"); 

編集:他のコメントで述べたように、null以外の値があることを確認してください。

更新:コメントで推奨されているように、拡張メソッド:

public static string ToString(this DateTime? dt, string format)
    => dt == null ? "n/a" : ((DateTime)dt).ToString(format);

また、C#6以降では、null条件演算子を使用してコードをさらに簡略化できます。がnullの場合、以下の式DateTime?はnull を返します。

dt2?.ToString("yyyy-MM-dd hh:mm:ss")

26
これは、拡張メソッドを私に頼んでいるようです。
David Glenn、

42
.Valueが鍵
stuartdotnet 2013

@デビッドタスクは些細な...ではないではないことをstackoverflow.com/a/44683673/5043056
Sinjai

3
準備はいいですか... dt?.ToString( "dd / MMM / yyyy")?? 「」C#6の大きな利点
トム・マクドナー

エラーCS0029:型 'string'を暗黙的に 'System.DateTime?'に変換できません (CS0029)。.Net Core 2.0
Oracular Man 2018

80

サイズを試してみてください:

フォーマットする実際のdateTimeオブジェクトはdt.Valueプロパティにあり、dt2オブジェクト自体にはありません。

DateTime? dt2 = DateTime.Now;
 Console.WriteLine(dt2.HasValue ? dt2.Value.ToString("yyyy-MM-dd hh:mm:ss") : "[N/A]");

36

皆さんはこれをすべてエンジニアリングしすぎて、実際よりもずっと複雑にしています。重要なことは、ToStringの使用を中止し、string.Formatのような文字列フォーマット、またはConsole.WriteLineのような文字列フォーマットをサポートするメソッドの使用を開始することです。この質問に対する推奨される解決策を次に示します。これも最も安全です。

更新:

今日のC#コンパイラの最新のメソッドで例を更新します。条件演算子文字列補間

DateTime? dt1 = DateTime.Now;
DateTime? dt2 = null;

Console.WriteLine("'{0:yyyy-MM-dd hh:mm:ss}'", dt1);
Console.WriteLine("'{0:yyyy-MM-dd hh:mm:ss}'", dt2);
// New C# 6 conditional operators (makes using .ToString safer if you must use it)
// https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operators
Console.WriteLine(dt1?.ToString("yyyy-MM-dd hh:mm:ss"));
Console.WriteLine(dt2?.ToString("yyyy-MM-dd hh:mm:ss"));
// New C# 6 string interpolation
// https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated
Console.WriteLine($"'{dt1:yyyy-MM-dd hh:mm:ss}'");
Console.WriteLine($"'{dt2:yyyy-MM-dd hh:mm:ss}'");

出力:(私はそれに単一引用符を入れたので、nullのときに空の文字列として返されることがわかります)

'2019-04-09 08:01:39'
''
2019-04-09 08:01:39

'2019-04-09 08:01:39'
''

30

他の人が述べたように、ToStringを呼び出す前にnullを確認する必要がありますが、自分自身の繰り返しを避けるために、次のような拡張メソッドを作成できます。

public static class DateTimeExtensions {

  public static string ToStringOrDefault(this DateTime? source, string format, string defaultValue) {
    if (source != null) {
      return source.Value.ToString(format);
    }
    else {
      return String.IsNullOrEmpty(defaultValue) ?  String.Empty : defaultValue;
    }
  }

  public static string ToStringOrDefault(this DateTime? source, string format) {
       return ToStringOrDefault(source, format, null);
  }

}

次のように呼び出すことができます:

DateTime? dt = DateTime.Now;
dt.ToStringOrDefault("yyyy-MM-dd hh:mm:ss");  
dt.ToStringOrDefault("yyyy-MM-dd hh:mm:ss", "n/a");
dt = null;
dt.ToStringOrDefault("yyyy-MM-dd hh:mm:ss", "n/a")  //outputs 'n/a'

28

C#6.0の赤ちゃん:

dt2?.ToString("dd/MM/yyyy");


2
この回答がC#6.0の既存の承認済み回答と同等になるように、次のバージョンを提案します。 Console.WriteLine(dt2?.ToString("yyyy-MM-dd hh:mm:ss" ?? "n/a");
Bud Can

15

この質問への回答を定式化する際の問題は、null許容のdatetimeに値がない場合に目的の出力を指定しないことです。次のコードはDateTime.MinValueそのような場合に出力され、現在受け入れられている回答とは異なり、例外はスローされません。

dt2.GetValueOrDefault().ToString(format);

7

実際にIFormattableインターフェイスをSmalls拡張メソッドに追加することをお勧めしますが、厄介な文字列形式の連結がないようにしたい形式を提供したいと考えています。

public static string ToString<T>(this T? variable, string format, string nullValue = null)
where T: struct, IFormattable
{
  return (variable.HasValue) 
         ? variable.Value.ToString(format, null) 
         : nullValue;          //variable was null so return this value instead   
}


5

使用できます dt2.Value.ToString("format")が、もちろんdt2!= nullが必要であり、そもそもnull許容型の使用を無効にします。

ここにはいくつかの解決策がありますが、大きな問題は、null日付をどのようにフォーマットしたいですか?


5

これはより一般的なアプローチです。これにより、任意のnull許容値の型を文字列形式にすることができます。値のタイプにデフォルト値を使用する代わりに、デフォルトの文字列値を上書きできるようにする2番目のメソッドを含めました。

public static class ExtensionMethods
{
    public static string ToString<T>(this Nullable<T> nullable, string format) where T : struct
    {
        return String.Format("{0:" + format + "}", nullable.GetValueOrDefault());
    }

    public static string ToString<T>(this Nullable<T> nullable, string format, string defaultValue) where T : struct
    {
        if (nullable.HasValue) {
            return String.Format("{0:" + format + "}", nullable.Value);
        }

        return defaultValue;
    }
}

4

最短の答え

$"{dt:yyyy-MM-dd hh:mm:ss}"

テスト

DateTime dt1 = DateTime.Now;
Console.Write("Test 1: ");
Console.WriteLine($"{dt1:yyyy-MM-dd hh:mm:ss}"); //works

DateTime? dt2 = DateTime.Now;
Console.Write("Test 2: ");
Console.WriteLine($"{dt2:yyyy-MM-dd hh:mm:ss}"); //Works

DateTime? dt3 = null;
Console.Write("Test 3: ");
Console.WriteLine($"{dt3:yyyy-MM-dd hh:mm:ss}"); //Works - Returns empty string

Output
Test 1: 2017-08-03 12:38:57
Test 2: 2017-08-03 12:38:57
Test 3: 


4

RAZOR構文:

@(myNullableDateTime?.ToString("yyyy-MM-dd") ?? String.Empty)

2

GetValueOrDefault-Methodeを使用する必要があると思います。インスタンスがnullの場合、ToString( "yy ...")の動作は定義されません。

dt2.GetValueOrDefault().ToString("yyy...");

1
GetValueOrDefault()はDateTime.MinValueを返すため、ToString( "yy ...")での動作定義されています
Lucas

2

ここでブレイクの優れた答え拡張メソッドとしては。これをプロジェクトに追加すると、質問の呼び出しは期待どおりに機能します。
のようMyNullableDateTime.ToString("dd/MM/yyyy")に使用されることを意味し、DateTimeがnullの場合のMyDateTime.ToString("dd/MM/yyyy")値を除いて、と同じ出力を持ち"N/A"ます。

public static string ToString(this DateTime? date, string format)
{
    return date != null ? date.Value.ToString(format) : "N/A";
}

1

IFormattableには、使用可能なフォーマットプロバイダーも含まれています。これにより、InetProviderの両方のフォーマットをdotnet 4.0でnullにすることができます。

/// <summary>
/// Extentionclass for a nullable structs
/// </summary>
public static class NullableStructExtensions {

    /// <summary>
    /// Formats a nullable struct
    /// </summary>
    /// <param name="source"></param>
    /// <param name="format">The format string 
    /// If <c>null</c> use the default format defined for the type of the IFormattable implementation.</param>
    /// <param name="provider">The format provider 
    /// If <c>null</c> the default provider is used</param>
    /// <param name="defaultValue">The string to show when the source is <c>null</c>. 
    /// If <c>null</c> an empty string is returned</param>
    /// <returns>The formatted string or the default value if the source is <c>null</c></returns>
    public static string ToString<T>(this T? source, string format = null, 
                                     IFormatProvider provider = null, 
                                     string defaultValue = null) 
                                     where T : struct, IFormattable {
        return source.HasValue
                   ? source.Value.ToString(format, provider)
                   : (String.IsNullOrEmpty(defaultValue) ? String.Empty : defaultValue);
    }
}

名前付きパラメーターと一緒に使用すると、次のことができます。

dt2.ToString(defaultValue: "n / a");

古いバージョンのdotnetでは、多くのオーバーロードが発生します

/// <summary>
/// Extentionclass for a nullable structs
/// </summary>
public static class NullableStructExtensions {

    /// <summary>
    /// Formats a nullable struct
    /// </summary>
    /// <param name="source"></param>
    /// <param name="format">The format string 
    /// If <c>null</c> use the default format defined for the type of the IFormattable implementation.</param>
    /// <param name="provider">The format provider 
    /// If <c>null</c> the default provider is used</param>
    /// <param name="defaultValue">The string to show when the source is <c>null</c>. 
    /// If <c>null</c> an empty string is returned</param>
    /// <returns>The formatted string or the default value if the source is <c>null</c></returns>
    public static string ToString<T>(this T? source, string format, 
                                     IFormatProvider provider, string defaultValue) 
                                     where T : struct, IFormattable {
        return source.HasValue
                   ? source.Value.ToString(format, provider)
                   : (String.IsNullOrEmpty(defaultValue) ? String.Empty : defaultValue);
    }

    /// <summary>
    /// Formats a nullable struct
    /// </summary>
    /// <param name="source"></param>
    /// <param name="format">The format string 
    /// If <c>null</c> use the default format defined for the type of the IFormattable implementation.</param>
    /// <param name="defaultValue">The string to show when the source is null. If <c>null</c> an empty string is returned</param>
    /// <returns>The formatted string or the default value if the source is <c>null</c></returns>
    public static string ToString<T>(this T? source, string format, string defaultValue) 
                                     where T : struct, IFormattable {
        return ToString(source, format, null, defaultValue);
    }

    /// <summary>
    /// Formats a nullable struct
    /// </summary>
    /// <param name="source"></param>
    /// <param name="format">The format string 
    /// If <c>null</c> use the default format defined for the type of the IFormattable implementation.</param>
    /// <param name="provider">The format provider (if <c>null</c> the default provider is used)</param>
    /// <returns>The formatted string or an empty string if the source is <c>null</c></returns>
    public static string ToString<T>(this T? source, string format, IFormatProvider provider)
                                     where T : struct, IFormattable {
        return ToString(source, format, provider, null);
    }

    /// <summary>
    /// Formats a nullable struct or returns an empty string
    /// </summary>
    /// <param name="source"></param>
    /// <param name="format">The format string 
    /// If <c>null</c> use the default format defined for the type of the IFormattable implementation.</param>
    /// <returns>The formatted string or an empty string if the source is null</returns>
    public static string ToString<T>(this T? source, string format)
                                     where T : struct, IFormattable {
        return ToString(source, format, null, null);
    }

    /// <summary>
    /// Formats a nullable struct
    /// </summary>
    /// <param name="source"></param>
    /// <param name="provider">The format provider (if <c>null</c> the default provider is used)</param>
    /// <param name="defaultValue">The string to show when the source is <c>null</c>. If <c>null</c> an empty string is returned</param>
    /// <returns>The formatted string or the default value if the source is <c>null</c></returns>
    public static string ToString<T>(this T? source, IFormatProvider provider, string defaultValue)
                                     where T : struct, IFormattable {
        return ToString(source, null, provider, defaultValue);
    }

    /// <summary>
    /// Formats a nullable struct or returns an empty string
    /// </summary>
    /// <param name="source"></param>
    /// <param name="provider">The format provider (if <c>null</c> the default provider is used)</param>
    /// <returns>The formatted string or an empty string if the source is <c>null</c></returns>
    public static string ToString<T>(this T? source, IFormatProvider provider)
                                     where T : struct, IFormattable {
        return ToString(source, null, provider, null);
    }

    /// <summary>
    /// Formats a nullable struct or returns an empty string
    /// </summary>
    /// <param name="source"></param>
    /// <returns>The formatted string or an empty string if the source is <c>null</c></returns>
    public static string ToString<T>(this T? source) 
                                     where T : struct, IFormattable {
        return ToString(source, null, null, null);
    }
}

1

私はこのオプションが好きです:

Console.WriteLine(dt2?.ToString("yyyy-MM-dd hh:mm:ss") ?? "n/a");

0

単純な汎用拡張

public static class Extensions
{

    /// <summary>
    /// Generic method for format nullable values
    /// </summary>
    /// <returns>Formated value or defaultValue</returns>
    public static string ToString<T>(this Nullable<T> nullable, string format, string defaultValue = null) where T : struct
    {
        if (nullable.HasValue)
        {
            return String.Format("{0:" + format + "}", nullable.Value);
        }

        return defaultValue;
    }
}

-2

多分それは遅い答えですが他の人を助けるかもしれません。

シンプルは:

nullabledatevariable.Value.Date.ToString("d")

または「d」ではなく任意の形式を使用します。

ベスト


1
nullabledatevariable.Valueがnullの場合、これはエラーになります。
ジョンC

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.