0

In my net core project I have to parse a string into a DateTime. The format is dynamic and not known at compilation time. The code is:

var datetime = DateTime.ParseExact(data, format, CultureInfo.InvariantCulture, DateTimeStyles.None);

but I'm having issues when the format is just the hour and is coming as numbers from 0 to 23. According to this article to specify the hour format you have 4 options: h, hh, H and HH, but when trying to parse "0"

Using h I get:

System.FormatException : Input string was not in a correct format.

Using hh I get:

System.FormatException: String was not recognized as a valid DateTime.

Using H I get:

System.FormatException : Input string was not in a correct format.

Using HH I get:

System.FormatException: String was not recognized as a valid DateTime.

In this article it is stated that

If format is a custom format pattern that does not include date or time separators (such as "yyyyMMddHHmm"), use the invariant culture for the provider parameter and the widest form of each custom format specifier. For example, if you want to specify hours in the format pattern, specify the wider form, "HH", instead of the narrower form, "H".

but it is what i have been doing and is not working. I cannot guess how to achieve parsing a string which is just the hour into a DateTime. Any ideas??

EDIT

The exception is thrown when executing any of these lines:

DateTime.ParseExact("0", "HH", CultureInfo.InvariantCulture, DateTimeStyles.None);
DateTime.ParseExact("0", "H", CultureInfo.InvariantCulture, DateTimeStyles.None);

I cannot use TimeSpan.Parse as I have a generic solution to read xlsx files. How to read the file is stored on the datatabase. Sometimes the DateTime is all in one column and the format is ddMMyyHHmmss and others the DateTime is in one column with the format ddMMyy and the hour in other as a number from 0 to 23 (minutes and seconds should be initialized with 0). Later the date and hour are merged to return the whole DateTime.

joacoleza
  • 775
  • 1
  • 9
  • 26
  • What will be the date in case you only have time, would it be 1.1.0001? – st_stefanov May 16 '18 at 20:47
  • In that case the day part will be ignored, so it's the same. – joacoleza May 16 '18 at 20:49
  • May be you already checked this, but here it is anyway: https://stackoverflow.com/questions/34321486/how-to-convert-time-only-using-datetime-parse?rq=1 – st_stefanov May 16 '18 at 20:50
  • Also, is it an option for you to check what value you have and pad it, so it fits a proper format, e.g. if string.Length == 1 or 2...string = string + ":00". – st_stefanov May 16 '18 at 20:53
  • Please post a [mcve]. – Lasse V. Karlsen May 16 '18 at 20:55
  • 2
    Unfortunately, `DateTime.ParseExact` doesn't handle *all* format combinations, and a string that contains just 1 number, taken to mean the hour, isn't handled. The most likely reason for this is that "nobody" would ask `DateTime.ParseExact` to parse something that isn't a date or a time or a combination, and `"23"` is neither. – Lasse V. Karlsen May 16 '18 at 21:01
  • if you do not need the day, you certainly do not need a `DateTime` – Rovann Linhalis May 16 '18 at 21:18
  • As I have a generic solution I cannot know beforehand if it will be a complete DateTime or just the date or just the time. If not the solution would be quite simple. – joacoleza May 16 '18 at 22:20

1 Answers1

1

When supplying only a single character as a format, it will be interpreted as a standard format specifier rather than a custom format specifier. The % character can be used to force it to be treated as a custom specifier. This is covered in the documentation here.

Thus, instead of passing "h", pass "%h". Instead of "H", pass "%H"

Other answers, such as this one, have mentioned this with regards to formatting using String.Format or ToString, but it is also applicable for ParseExact.

Alternatively, you may find your code more legible and performant if you instead start with some known DateTime value (perhaps DateTime.MinValue, or perhaps something else) and then use AddHours to get to the desired result. (Of course, you would parse the string to an integer first.)

Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
  • I didn't know that difference between standard and costume formats specifiers. Your answer fix my problem. Thanks!! – joacoleza May 16 '18 at 22:21