如何使用 ToString() 格式化可为空的 DateTime?
Posted
技术标签:
【中文标题】如何使用 ToString() 格式化可为空的 DateTime?【英文标题】:How can I format a nullable DateTime with ToString()? 【发布时间】:2010-12-22 10:16:23 【问题描述】:如何将可为空的 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");
编辑:如其他 cmets 所述,检查是否存在非空值。
更新:在cmets中推荐,扩展方法:
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")
【讨论】:
这看起来像是在乞求我的扩展方法。 @David 并不是说任务不简单...***.com/a/44683673/5043056 你准备好了吗... dt?.ToString("dd/MMM/yyyy") ?? "" C#6 的巨大优势 错误 CS0029:无法将类型“字符串”隐式转换为“System.DateTime?” (CS0029)。 .Net Core 2.0 为什么要强制转换为不可空而不是只使用dt.Value
?【参考方案2】:
您可以使用dt2.Value.ToString("format")
,但当然这需要 dt2 != null,这首先否定了可空类型的使用。
这里有几种解决方案,但最大的问题是:你想如何格式化null
日期?
【讨论】:
【参考方案3】:试穿一下尺寸:
您要格式化的实际 dateTime 对象位于 dt.Value 属性中,而不是 dt2 对象本身。
DateTime? dt2 = DateTime.Now;
Console.WriteLine(dt2.HasValue ? dt2.Value.ToString("yyyy-MM-dd hh:mm:ss") : "[N/A]");
【讨论】:
【参考方案4】:制定此问题的答案的问题在于,当可空日期时间没有值时,您没有指定所需的输出。下面的代码在这种情况下会输出DateTime.MinValue
,与目前接受的答案不同,不会抛出异常。
dt2.GetValueOrDefault().ToString(format);
【讨论】:
【参考方案5】:我认为您必须使用 GetValueOrDefault-Methode。如果实例为空,则未定义 ToString("yy...") 的行为。
dt2.GetValueOrDefault().ToString("yyy...");
【讨论】:
如果实例为空,则定义 ToString("yy...") is 的行为,因为 GetValueOrDefault() 将返回 DateTime.MinValue【参考方案6】:正如其他人所说,您需要在调用 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'
【讨论】:
【参考方案7】:这是一种更通用的方法。这将允许您对任何可为空的值类型进行字符串格式化。我已经包含了第二种方法来允许覆盖默认字符串值,而不是使用值类型的默认值。
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;
【讨论】:
【参考方案8】:看到您实际上想要提供格式,我建议您将 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
【讨论】:
【参考方案9】: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);
【讨论】:
【参考方案10】:你们对这一切都进行了过度设计,并使其变得比实际情况更复杂。重要的是,停止使用 ToString 并开始使用像 string.Format 这样的字符串格式或支持像 Console.WriteLine 这样的字符串格式的方法。这是此问题的首选解决方案。这也是最安全的。
更新:
我使用当今 C# 编译器的最新方法更新示例。 conditional operators & string interpolation
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'
''
【讨论】:
第二个选项是更好的选择。 String.Format() 无论如何都必须调用 .ToString() 然后进行复杂的格式化。 ***.com/questions/10400142/string-format-vs-tostring @ChristenDen 并非总是如此。这仅在最近的 C# 更新中引入。而且...大多数时候,当您为显示/记录目的格式化字符串时,您会使用多个参数来构建字符串。【参考方案11】:简单的通用扩展
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;
【讨论】:
【参考方案12】:C# 6.0 宝贝:
dt2?.ToString("dd/MM/yyyy");
【讨论】:
我建议使用以下版本,以便此答案等同于 C# 6.0 的现有公认答案。Console.WriteLine(dt2?.ToString("yyyy-MM-dd hh:mm:ss" ?? "n/a");
【参考方案13】:
也许这是一个迟到的答案,但可能对其他人有所帮助。
简单的是:
nullabledatevariable.Value.Date.ToString("d")
或者只使用任何格式而不是“d”。
最好的
【讨论】:
当 nullabledatevariable.Value 为 null 时会出错。【参考方案14】:你可以用简单的线:
dt2.ToString("d MMM yyyy") ?? ""
【讨论】:
【参考方案15】:我喜欢这个选项:
Console.WriteLine(dt2?.ToString("yyyy-MM-dd hh:mm:ss") ?? "n/a");
【讨论】:
【参考方案16】:像这样简单的事情怎么样:
String.Format("0:dd/MM/yyyy", d2)
【讨论】:
【参考方案17】:这里是Blake's excellent answer 作为扩展方法。将此添加到您的项目中,问题中的调用将按预期工作。
这意味着它与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";
【讨论】:
【参考方案18】:最短答案
$"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:
【讨论】:
【参考方案19】:在 C# 6.0 中甚至是更好的解决方案:
DateTime? birthdate;
birthdate?.ToString("dd/MM/yyyy");
【讨论】:
【参考方案20】:RAZOR 语法:
@(myNullableDateTime?.ToString("yyyy-MM-dd") ?? String.Empty)
【讨论】:
以上是关于如何使用 ToString() 格式化可为空的 DateTime?的主要内容,如果未能解决你的问题,请参考以下文章
如何在基于块的 API 方法中使用非空和可为空的 Objective-C 关键字
如何使用 System.Text.Json 处理可为空的引用类型?