39

Is there a simple way to configure JSON.NET so that some DateTime fields will be formatted without time and other DateTime fields will still be formatted with time?

Example:

{ firstName: 'John', lastName : 'Doe', birthday: '1965-09-23' }

4 Answers 4

75

If you need this to only affect a particular field, create a converter type first:

public class OnlyDateConverter : IsoDateTimeConverter
{
    public OnlyDateConverter()
    {
        DateTimeFormat = "yyyy-MM-dd";
    }
}

and then add this attribute to whatever fields/properties you want this for:

[JsonConverter(typeof(OnlyDateConverter))]
Sign up to request clarification or add additional context in comments.

8 Comments

Nice. I was just getting to write the same thing, but extending DateTimeConverterBase. This is much cleaner!
Apparently you should use / instead of dashes for the benefit of certain old browsers : blog.dygraphs.com/2012/03/javascript-and-dates-what-mess.html
Should you make the property as a DateTime or as a string?
You can also use predefined Microsoft.Rest.Serialization.DateJsonConverter type from Microsoft.Rest.ClientRuntime package (it is installed together with Microsoft.AspNetCore.All package)
This did not work for me, I am still getting the time sent even if I decorate a model's property with this attribute.
|
5

Try adding this line to configure your Web API:

config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(
    new IsoDateTimeConverter() { DateTimeFormat = "yyyy-MM-dd" });

1 Comment

That would have effect globally, not just on "some" fields, as requested.
1

Answer from Youssef works when using Newtonsoft.Json to serialize a single field in the model. But by default core uses System.Text.Json to serialize objects. The same thing can be achieved in core without Newtonsoft like so:

using System.Text.Json.Serialization;

internal class JsonOnlyDateConverter : JsonConverter<DateTime>
{
    public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return DateTime.ParseExact(reader.GetString()!, "yyyy-MM-dd", CultureInfo.InvariantCulture);            
    }

    public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture));            
    }
}

And use it in your model:

using System.Text.Json.Serialization;

...

[JsonConverter(typeof(JsonOnlyDateConverter))]
public DateTime MyDateField { get; set; }

1 Comment

This is the right solution! To expand on it, instead of using this: [JsonConverter(typeof(JsonOnlyDateConverter))] in you Program.cs or Startup.cs, add the following: builder.Services.AddControllers().AddJsonOptions(options => { options.JsonSerializerOptions.Converters.Add( new IsoDateNoTimeConverter()); });
0

Yousesef's answer with the OnlyDateConverter is best. But here is one alternative:

private DateTime _birthday;
public string Birthday
{
    get { return _birthday.ToString("yyyy-MM-dd"); }
    set {
          _birthday = DateTime.ParseExact(value, "yyyy-MM-dd",
                                          CultureInfo.InvariantCulture);
        }
}

Advantage - You don't need to bind the Newtonsoft.Json library to your classes.

Disadvantage - The property is now exposed as a string anywhere you use it, which can cause it's own set of problems.

1 Comment

I've considered that approach, but it may not be the best when computations could be involved between dates. Thanks anyways!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.