1

I cannot deserialise a datetime string from Excel using EPPlus. I have read other answers about this but still cannot this to work and get the error: String 'M-d-yy hh:mm' was not recognized as a valid DateTime.

As per other answers a found on this topic, I have changed the DateTimeFormat to "M/d/yy hh:mm", which is what EPPlus is returning as a string when I put a watch on it. My current culture is "en-UK", however I'm using InvariantCulture because EPPlus is out-putting the above format which I would rather use. If this is an issue then I don't mind changing it but I don't see the point of going from a US format to a UK format, only for it be changed again to an international ISO format in the DB.

It must still somehow think that it follows a UK datetime format but I can't see where I'm going wrong. Any help would be greatly appreciated! Thanks

Here is what I have at the moment:

                var dateTimeConverter = new IsoDateTimeConverter
                {
                    Culture = CultureInfo.InvariantCulture,
                    DateTimeFormat = "M/d/yy h:mm",
                    DateTimeStyles = DateTimeStyles.AssumeLocal
                };

                var excelImportResponse = new ExcelImportResponse<T>();
                foreach (DataRow row in dataTable.AsEnumerable())
                {
                    excelImportResponse.Objects.Add(
                        JsonConvert.DeserializeObject<T>(
                            new JObject(
                                row.Table.Columns
                                    .Cast<DataColumn>()
                                    .Select(c => new JProperty(c.ColumnName.Trim(), JToken.FromObject(row[c])))
                                )
                                .ToString(Formatting.None),
                                new JsonSerializerSettings
                                {
                                    Error = delegate (object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args)
                                    {
                                        excelImportResponse.Errors.Add(args.ErrorContext.Error.Message);
                                        args.ErrorContext.Handled = true;
                                    },
                                    Converters = { dateTimeConverter }
                                })
                        );
                }

my code

The error: String '7/1/20 14:15' was not recognized as a valid DateTime.

Full exception at System.DateTimeParse.ParseExact(ReadOnlySpan1 s, ReadOnlySpan1 format, DateTimeFormatInfo dtfi, DateTimeStyles style) at System.DateTime.ParseExact(String s, String format, IFormatProvider provider, DateTimeStyles style) at Newtonsoft.Json.Converters.IsoDateTimeConverter.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)

enter image description here

Sean
  • 11
  • 2
  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/221318/discussion-on-question-by-sean-json-net-string-7-1-20-1415-was-not-recognize). – Samuel Liew Sep 11 '20 at 11:52

1 Answers1

0

Using this converter

var dateTimeConverter = new IsoDateTimeConverter
{
    Culture = CultureInfo.InvariantCulture,
    //note the "H" which accepts 24-hour format, whereas "h" only accepts 12-hour format and will fail for a time like "14:25"
    DateTimeFormat = "M/d/yy H:mm",  
    DateTimeStyles = DateTimeStyles.AssumeLocal
};

works fine if I do this

class AType {
    public DateTime aDate {get;set;}
}

...

var sett = new JsonSerializerSettings { Converters = new List<JsonConverter>{ dateTimeConverter}};
var d1 = new AType{ aDate = DateTime.Now};

var s = JsonConvert.SerializeObject(d1, sett);
var d2 = JsonConvert.DeserializeObject<AType>(s, sett);

Your converter is probably failing, because M/d/yy h:mm can't cope with a time like 14:25 which is in 24-hour format, but h only accepts 12-hour format.

And you should also inspect what exact output this part of code

new JObject(
    row.Table.Columns
      .Cast<DataColumn>()
      .Select(c => new JProperty(c.ColumnName.Trim(), JToken.FromObject(row[c])))
    ).ToString(Formatting.None)

produces, because that's what's going into the converter. And if this format is slightly off, the converter may throw the error you are seeing.

Furthermore, I don't know the purpose or context of your project. But using only two digits for the year is strongly discouraged. You may do so, if you exactly know what you are doing and you never will have any dates before 1.1.2000 or after 31.12.2099. But yeah, we've been there once (nobody in the 70s thought about their systems still running in 2000), and some systems probably will be there again on 19/1/38 3:14

derpirscher
  • 14,418
  • 3
  • 18
  • 35
  • There's no way to avoid problems with 2-digit years. This year [three major UK banks had to shut down](https://www.standard.co.uk/news/uk/lloyds-halifax-bank-of-scotland-online-banking-crash-a4323976.html) because `20` was interpreted as 1920 - Lloyd's, Halifax and Bank of Scotland. Using a non-standard date format in JSON is a very bad idea to begin with – Panagiotis Kanavos Sep 11 '20 at 14:25
  • @PanagiotisKanavos You are right about y2k, and OP has been warned about that multiple times. But in the end of the day, it's his decisions what he does with the warning. And the error OP is seeing has nothing to do with y2k but with a custom DateTime converter not accepting 24h format. – derpirscher Sep 11 '20 at 14:31