Как я могу отформатировать DateTime с нулевым значением с помощью ToString()?
Как преобразовать нулевую 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
Console.WriteLine(dt2 != null ? dt2.Value.ToString("yyyy-MM-dd hh:mm:ss") : "n/a");
РЕДАКТИРОВАТЬ: Как указано в других комментариях, проверьте, что есть ненулевое значение.
Обновление: как рекомендуется в комментариях, метод расширения:
public static string ToString(this DateTime? dt, string format)
=> dt == null ? "n/a" : ((DateTime)dt).ToString(format);
И начиная с С# 6, вы можете использовать нулевой условный оператор, чтобы еще больше упростить код. Выражение ниже вернет ноль, если DateTime?
нулевой.
dt2?.ToString("yyyy-MM-dd hh:mm:ss")
Ответ 2
Попробуйте это для размера:
Фактический объект dateTime, который вы ищете для форматирования, находится в свойстве dt.Value, а не в самом объекте dt2.
DateTime? dt2 = DateTime.Now;
Console.WriteLine(dt2.HasValue ? dt2.Value.ToString("yyyy-MM-dd hh:mm:ss") : "[N/A]");
Ответ 3
Как утверждали другие, вам нужно проверить значение null перед вызовом ToString, но чтобы избежать повторения, вы можете создать метод расширения, который делает это, например:
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'
Ответ 4
Вы, ребята, уже спроектировали все это и сделали его намного сложнее, чем на самом деле. Важная вещь, прекратите использовать ToString и начните использовать форматирование строки, например string.Format или методы, которые поддерживают форматирование строки, например Console.WriteLine. Вот предпочтительное решение этого вопроса. Это также самый безопасный.
Обновить:
Я обновляю примеры современными методами сегодняшнего компилятора С#. условные операторы и интерполяция строк
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}'");
Вывод: (я поместил в него одинарные кавычки, чтобы вы могли видеть, что он возвращается как пустая строка, когда ноль)
'2019-04-09 08:01:39'
''
2019-04-09 08:01:39
'2019-04-09 08:01:39'
''
Ответ 5
С# 6.0:
dt2?.ToString("dd/MM/yyyy");
Ответ 6
Проблема с формулировкой ответа на этот вопрос заключается в том, что вы не указываете желаемый результат, когда значение Nable-времени не имеет значения. Следующий код выводит 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
}
Ответ 8
Вы можете использовать dt2.Value.ToString("format")
, но, конечно, это требует, чтобы dt2!= null, и это отрицает использование типа с нулевым значением в первую очередь.
Здесь есть несколько решений, но большой вопрос: как вы хотите отформатировать дату null
?
Ответ 9
Вот более общий подход. Это позволит вам форматировать любой тип значения с нулевым значением. Я включил второй метод, позволяющий переопределить строковое значение по умолчанию вместо использования значения по умолчанию для типа значения.
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;
}
}
Ответ 10
Как насчет чего-то такого же простого:
String.Format("{0:dd/MM/yyyy}", d2)
Ответ 11
Самый короткий ответ
$"{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:
Ответ 12
Я думаю, вам нужно использовать GetValueOrDefault-Methode. Поведение с ToString ( "yy..." ) не определено, если экземпляр имеет значение null.
dt2.GetValueOrDefault().ToString("yyy...");
Ответ 13
Еще лучшее решение в С# 6.0:
DateTime? birthdate;
birthdate?.ToString("dd/MM/yyyy");
Ответ 14
Синтаксис бритвы:
@(myNullableDateTime?.ToString("yyyy-MM-dd") ?? String.Empty)
Ответ 15
IFormattable также включает в себя поставщика форматов, который можно использовать, он допускает, чтобы формат IFormatProvider был нулевым в 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);
}
}
используя вместе с именованными параметрами вы можете:
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);
}
}
Ответ 16
Мне нравится эта опция:
Console.WriteLine(dt2?.ToString("yyyy-MM-dd hh:mm:ss") ?? "n/a");
Ответ 17
Вот отличный ответ Блэйка в качестве метода расширения. Добавьте это в свой проект, и звонки в вопросе будут работать как положено.
Это означает, что он используется как MyNullableDateTime.ToString("dd/MM/yyyy")
, с тем же выводом, что и MyDateTime.ToString("dd/MM/yyyy")
, за исключением того, что значение будет равно "N/A"
если DateTime нулевой.
public static string ToString(this DateTime? date, string format)
{
return date != null ? date.Value.ToString(format) : "N/A";
}
Ответ 18
Простые общие расширения
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;
}
}
Ответ 19
Возможно, это поздний ответ, но может помочь кому-либо еще.
Простой:
nullabledatevariable.Value.Date.ToString("d")
или просто использовать любой формат, а не "d".
Лучшие
Ответ 20
вы можете использовать простую строку:
dt2.ToString("d MMM yyyy") ?? ""