Jak sformatować zerową wartość DateTime za pomocą ToString ()?


226

Jak przekonwertować zerowalne DateTime dt2 na sformatowany ciąg?

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:

brak przeciążenia metody ToString wymaga jednego argumentu


3
Witaj, czy mógłbyś przejrzeć zaakceptowane i aktualne odpowiedzi? Bardziej trafna odpowiedź dnia może być bardziej poprawna.
iuliu.net

Odpowiedzi:


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

EDYCJA: Jak stwierdzono w innych komentarzach, sprawdź, czy nie ma wartości zerowej.

Aktualizacja: zgodnie z zaleceniami w komentarzach, metoda rozszerzenia:

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

Począwszy od C # 6, możesz użyć operatora warunkowego null, aby jeszcze bardziej uprościć kod. Poniższe wyrażenie zwróci null, jeśli DateTime?null.

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

26
Wygląda na to, że błaga mnie o metodę rozszerzenia.
David Glenn

42
.Value jest kluczem
stuartdotnet

@Dawid nie, że to zadanie nie jest trywialne ... stackoverflow.com/a/44683673/5043056
Sinjai

3
Czy jesteś gotowy na to ... dt? .ToString („dd / MMM / rrrr”)? „” Wielkie zalety C # 6
Tom McDonough

Błąd CS0029: Nie można niejawnie przekonwertować typu „string” na „System.DateTime?” (CS0029). .Net Core 2.0
Oracular Man

80

Spróbuj tego dla rozmiaru:

Rzeczywisty obiekt dateTime, który chcesz sformatować, znajduje się we właściwości dt.Value, a nie w samym obiekcie dt2.

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

36

Wy wszyscy jesteście nad inżynierią i wszystko to sprawia, że ​​jest to o wiele bardziej skomplikowane niż w rzeczywistości. Ważna rzecz: przestań używać ToString i zacznij korzystać z formatowania ciągów, takich jak string.Format lub metod, które obsługują formatowanie ciągów, takich jak Console.WriteLine. Oto preferowane rozwiązanie tego pytania. Jest to również najbezpieczniejsze.

Aktualizacja:

Aktualizuję przykłady za pomocą aktualnych metod dzisiejszego kompilatora C #. operatory warunkowe i interpolacja ciągów

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

Dane wyjściowe: (umieszczam w nim pojedyncze cudzysłowy, abyś mógł zobaczyć, że wraca jako pusty ciąg znaków, gdy jest pusty)

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

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

30

Jak stwierdzili inni, przed wywołaniem ToString należy sprawdzić wartość null, ale aby uniknąć powtarzania się, można utworzyć metodę rozszerzenia, która to robi, na przykład:

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

}

Które można wywołać jak:

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

Dziecko C # 6.0:

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


2
Sugerowałbym następującą wersję, aby ta odpowiedź była równoważna z istniejącą odpowiedzią zaakceptowaną dla C # 6.0. Console.WriteLine(dt2?.ToString("yyyy-MM-dd hh:mm:ss" ?? "n/a");
Can Bud,

15

Problem z sformułowaniem odpowiedzi na to pytanie polega na tym, że nie określa się żądanego wyniku, gdy zerowa data / godzina nie ma żadnej wartości. W DateTime.MinValuetakim przypadku wyświetli się następujący kod, w przeciwieństwie do obecnie akceptowanej odpowiedzi, nie zgłosi wyjątku.

dt2.GetValueOrDefault().ToString(format);

7

Widząc, że naprawdę chcesz podać format, sugeruję dodanie interfejsu IFormattable do metody rozszerzenia Smalls w ten sposób, aby nie mieć nieprzyjemnego połączenia formatu łańcucha.

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

Możesz użyć dt2.Value.ToString("format"), ale oczywiście wymaga to, aby dt2! = Null, i to przede wszystkim neguje użycie typu zerowalnego.

Jest tu kilka rozwiązań, ale najważniejsze pytanie brzmi: jak sformatować nulldatę?


5

Oto bardziej ogólne podejście. Umożliwi to formatowanie dowolnego typu wartości dopuszczającej wartości zerowe. Podałem drugą metodę, aby umożliwić zastąpienie domyślnej wartości ciągu zamiast używania wartości domyślnej dla typu wartości.

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

Najkrótsza odpowiedź

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

Testy

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

Składnia RAZOR:

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

2

Myślę, że musisz użyć metody GetValueOrDefault-Methode. Zachowanie w przypadku ToString („yy ...”) nie jest zdefiniowane, jeśli instancja ma wartość NULL.

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

1
Zachowanie w ToString („yy ...”) jest zdefiniowane, jeśli instancja ma wartość NULL, ponieważ funkcja GetValueOrDefault () zwróci DateTime.MinValue
Lucas

2

Oto doskonała odpowiedź Blake'a jako metody rozszerzenia. Dodaj to do swojego projektu, a wywołania w pytaniu będą działać zgodnie z oczekiwaniami.
Oznacza to, że używa się go MyNullableDateTime.ToString("dd/MM/yyyy")z tym samym wyjściem co MyDateTime.ToString("dd/MM/yyyy"), z tym wyjątkiem, że wartość będzie miała wartość, "N/A"jeśli DateTime ma wartość null.

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

1

IFormattable zawiera również dostawcę formatu, którego można użyć, pozwala to, aby zarówno format IFormatProvider był zerowy w dotnet 4.0, byłoby to

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

używając razem z nazwanymi parametrami możesz:

dt2.ToString (defaultValue: „n / a”);

W starszych wersjach dotnet występuje wiele przeciążeń

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


0

Proste rozszerzenia ogólne

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

Może to późna odpowiedź, ale może pomóc każdemu innemu.

Proste jest:

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

lub po prostu użyj dowolnego formatu zamiast „d”.

Najlepsza


1
Wystąpi błąd, gdy zmienna nullabledatevariable.Value ma wartość null.
John C,

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.