Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I format a nullable DateTime with ToString()?

People also ask

How do you make a date time nullable?

The Nullable < T > structure is using a value type as a nullable type. By default DateTime is not nullable because it is a Value Type, using the nullable operator introduced in C# 2, you can achieve this. Using a question mark (?) after the type or using the generic style Nullable.

How do I change the date format in Tostring?

To do this, you use the "MM/yyyy" format string. The format string uses the current culture's date separator. Getting a string that contains the date and time in a specific format. For example, the "MM/dd/yyyyHH:mm" format string displays the date and time string in a fixed format such as "19//03//2013 18:06".

Can DateTime be nullable?

DateTime itself is a value type. It cannot be null.

Can we assign null to DateTime in C#?

Using the DateTime nullable type, you can assign the null literal to the DateTime type.


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

EDIT: As stated in other comments, check that there is a non-null value.

Update: as recommended in the comments, extension method:

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

And starting in C# 6, you can use the null-conditional operator to simplify the code even more. The expression below will return null if the DateTime? is null.

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

Try this on for size:

The actual dateTime object your looking to format is in the dt.Value property, and not on the dt2 object itself.

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

You guys are over engineering this all and making it way more complicated than it really is. Important thing, stop using ToString and start using string formatting like string.Format or methods that support string formatting like Console.WriteLine. Here is the preferred solution to this question. This is also the safest.

Update:

I update the examples with up to date methods of today's C# compiler. 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}'");

Output: (I put single quotes in it so you can see that it comes back as a empty string when null)

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

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

C# 6.0 baby:

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


As others have stated you need to check for null before invoking ToString but to avoid repeating yourself you could create an extension method that does that, something like:

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

}

Which can be invoked like:

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'