如何使用ToString()格式化可为空的DateTime?

Edw*_*uay 214 c# formatting datetime nullable

如何将可空的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:
Run Code Online (Sandbox Code Playgroud)

方法ToString没有重载需要一个参数

Bla*_*son 313

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

编辑:如其他评论中所述,检查是否存在非空值.

更新:根据评论中的建议,扩展方法:

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

从C#6开始,您可以使用空条件运算符来进一步简化代码.如果DateTime?为null ,则下面的表达式将返回null.

dt2?.ToString("yyyy-MM-dd hh:mm:ss")
Run Code Online (Sandbox Code Playgroud)

  • .Value是关键 (41认同)
  • 这看起来像是在向我寻求扩展方法. (26认同)
  • 你准备好了吗?dt?.ToString("dd/MMM/yyyy")?? ""C#6的巨大优势 (3认同)

Rus*_*uss 79

试试这个尺码:

您希望格式化的实际dateTime对象位于dt.Value属性中,而不是dt2对象本身.

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


Joh*_*n C 34

你们都在设计这一切,并使它变得比实际更复杂.重要的是,停止使用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}'");
Run Code Online (Sandbox Code Playgroud)

输出:(我在其中放入单引号,以便您可以看到它在null时返回为空字符串)

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

'2019-04-09 08:01:39'
''
Run Code Online (Sandbox Code Playgroud)


Dav*_*enn 30

正如其他人所说,你需要在调用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);
  }

}
Run Code Online (Sandbox Code Playgroud)

可以调用如下:

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'
Run Code Online (Sandbox Code Playgroud)


iul*_*net 24

C#6.0宝贝:

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

  • 我建议使用以下版本,以便该答案等同于C#6.0的现有接受答案。`Console.WriteLine(dt2?.ToString(“ yyyy-MM-dd hh:mm:ss” ??“ n / a”);` (2认同)

Mat*_*lls 14

制定这个问题的答案的问题是,当可空的日期时间没有值时,你没有指定所需的输出.DateTime.MinValue在这种情况下将输出以下代码,与当前接受的答案不同,不会抛出异常.

dt2.GetValueOrDefault().ToString(format);
Run Code Online (Sandbox Code Playgroud)

  • 输出MinValue可能不是理想的行为. (8认同)

小智 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   
}
Run Code Online (Sandbox Code Playgroud)


Moh*_*din 6

C# 6.0 中甚至有更好的解决方案:

DateTime? birthdate;

birthdate?.ToString("dd/MM/yyyy");
Run Code Online (Sandbox Code Playgroud)


Hen*_*man 5

你可以使用dt2.Value.ToString("format"),但当然要求dt2!= null,并且首先否定使用可空类型.

这里有几种解决方案,但最大的问题是:您希望如何设置null日期格式?


Sch*_*lls 5

这是一种更通用的方法.这将允许您对任何可以为null的值类型进行字符串格式化.我已经包含了第二种方法来允许覆盖默认字符串值,而不是使用值类型的默认值.

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;
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

像这样简单的事情怎么样:

String.Format("{0:dd/MM/yyyy}", d2)
Run Code Online (Sandbox Code Playgroud)


wut*_*wut 5

剃刀语法:

@(myNullableDateTime?.ToString("yyyy-MM-dd") ?? String.Empty)
Run Code Online (Sandbox Code Playgroud)