web-dev-qa-db-fra.com

Comment puis-je formater un DateTime nullable avec ToString ()?

Comment puis-je convertir le DateTime nullable dt2 en une chaîne formatée?

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:

pas de surcharge pour la méthode ToString prend un argument

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

EDIT: Comme indiqué dans d’autres commentaires, vérifiez qu’il existe une valeur non nulle.

Mise à jour: comme recommandé dans les commentaires, méthode d'extension:

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

Et à partir de C # 6, vous pouvez utiliser le opérateur null-conditionnel pour simplifier encore plus le code. L'expression ci-dessous retournera null si le DateTime? est nul.

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

Essayez ceci pour la taille:

L'objet dateTime que vous souhaitez mettre en forme se trouve dans la propriété dt.Value et non sur l'objet dt2 lui-même.

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

Vous êtes en train de tout organiser et de compliquer les choses. Ce qui est important, arrêtez d'utiliser ToString et commencez à utiliser le formatage de chaîne tel que string.Format ou des méthodes prenant en charge le formatage de chaîne tel que Console.WriteLine. Voici la solution préférée à cette question. C'est aussi le plus sûr.

Mise à jour:

Je mets à jour les exemples avec les méthodes à jour du compilateur C # d'aujourd'hui. opérateurs conditionnels & interpolation de chaîne

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}'");

Sortie: (j'y ai mis des guillemets simples pour que vous puissiez voir qu'il revient sous forme de chaîne vide quand null)

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

'2019-04-09 08:01:39'
''
34
John C

Comme d’autres l’ont déjà dit, vous devez vérifier la valeur null avant d’appeler ToString, mais pour éviter de vous répéter, vous pouvez créer une méthode d’extension permettant de le faire, par exemple:

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

}

Qui peut être invoqué comme:

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

Bébé C # 6.0:

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

24
iuliu.net

Le problème avec la formulation d'une réponse à cette question est que vous ne spécifiez pas la sortie souhaitée lorsque la date et l'heure nullable n'a pas de valeur. Le code suivant générera DateTime.MinValue dans un tel cas et, contrairement à la réponse actuellement acceptée, ne lèvera pas d'exception.

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

Voyant que vous voulez réellement fournir le format, je suggérerais d’ajouter l’interface IFormattable à la méthode d’extension Smalls, de la sorte, vous éviterez ainsi la concaténation du format de chaîne.

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

Vous pouvez utiliser dt2.Value.ToString("format"), mais bien sûr, cela nécessite dt2! = Null, et cela annule l'utilisation d'un type nullable en premier lieu.

Il y a plusieurs solutions ici, mais la grande question est: comment voulez-vous formater une date null?

5
Henk Holterman

Qu'en est-il de quelque chose d'aussi simple que cela:

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

Voici une approche plus générique. Cela vous permettra de formater sous forme de chaîne tout type de valeur nullable. J'ai inclus la deuxième méthode pour autoriser le remplacement de la valeur de chaîne par défaut au lieu d'utiliser la valeur par défaut pour le type de valeur.

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

Même une meilleure solution en C # 6.0:

DateTime? birthdate;

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

Plus courte réponse

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

Des tests

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

Je pense que vous devez utiliser la méthode GetValueOrDefault. Le comportement avec ToString ("yy ...") n'est pas défini si l'instance est null.

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

Syntaxe RAZOR:

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

Voici l'excellente réponse de Blake comme méthode d'extension. Ajoutez ceci à votre projet et les appels de la question fonctionneront comme prévu.
Cela signifie qu'il est utilisé comme MyNullableDateTime.ToString("dd/MM/yyyy"), avec la même sortie que MyDateTime.ToString("dd/MM/yyyy"), sauf que la valeur sera "N/A" si DateTime est null.

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

J'aime cette option:

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

IFormattable inclut également un fournisseur de format qui peut être utilisé. Il permet aux formats de IFormatProvider d'être nuls dans dotnet 4.0.

/// <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);
    }
}

en utilisant ensemble les paramètres nommés, vous pouvez faire:

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

Dans les anciennes versions de Dotnet, il y a beaucoup de surcharges

/// <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

Extensions génériques simples

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
Andzej Maciusovic