web-dev-qa-db-ja.com

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

ヌル可能な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つ取りません

203
Edward Tanguay
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-conditional operator を使用してコードをさらに簡素化できます。 DateTime?がnullの場合、以下の式はnullを返します。

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

サイズについてはこれを試してください:

書式設定する実際のdateTimeオブジェクトはdt.Valueプロパティ内にあり、dt2オブジェクト自体にはありません。

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

皆さんはこれをすべてエンジニアリングしすぎており、実際よりもずっと複雑になっています。重要なことは、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'
''
32
John C

他の人が述べているように、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'
30
David Glenn

C#6.0ベイビー:

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

24
iuliu.net

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

dt2.GetValueOrDefault().ToString(format);
14
Matt Howells

実際にフォーマットを提供したいので、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   
}
7
ElmarG

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

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

5
Henk Holterman

これほど簡単なものはどうですか:

String.Format("{0:dd/MM/yyyy}", d2)
5
Max Brown

より一般的なアプローチを次に示します。これにより、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;
    }
}
5
Schmalls

C#6.0のさらに優れたソリューション:

DateTime? birthdate;

birthdate?.ToString("dd/MM/yyyy");
3

最短回答

$"{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: 
3
drobertson

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

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

RAZOR構文:

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

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

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

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

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

IFormattableには、使用できるフォーマットプロバイダーも含まれています。これにより、ドットネット4.0でIFormatProviderの両方のフォーマットを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
JeroenH

単純な汎用拡張

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;
    }
}
0