Short Time with DateTime.ParseExact - c#

I’m trying to parse a time. I’ve seen this question asked/answered here many times but not for this specific scenario. Here’s my code:
var time1 = DateTime.ParseExact("919", "Hmm", CultureInfo.InvariantCulture);
also
var time2 = DateTime.ParseExact("919", "Hmm", null);
both of these throw the same
"String was not recognized as a valid DateTime"
What I want is 9:19 AM.
For further info I also need to parse “1305” as 1:05 PM, this is working fine.
It seems to me I’m using the correct format. What am I overlooking?

I'm not sure there is any format that can handle this. The problem is that "H" can be either one digit or two, so if there are two digits available, it will grab both - in this case parsing it as hour 91, which is clearly invalid.
Ideally, you'd change the format to HHmm - zero-padding the value where appropriate - so "0919" would parse fine. Alternatively, use a colon in the format, to distinguish between the hours and the minutes. I don't believe there's any way of making DateTime parse a value of "919" as you want it to... so you'll need to adjust the string somehow before parsing it. (We don't have enough context to recommend a particular way of doing that.)

Yes, your format is right but since H specifier might be 2 character, ParseExact method try to parse 91 as an hour, which is an invalid hour, that's why you get FormatException in both case.
I connected to microsoft team about this situation 4 months ago. Take a look;
DateTime conversion from string C#
They suggest to use 2 digit form in your string or insert a date separator between them.
var time1 = DateTime.ParseExact("0919", "Hmm", CultureInfo.InvariantCulture);
or
var time1 = DateTime.ParseExact("9:19", "H:mm", CultureInfo.InvariantCulture);

You cant exclude the 0 prefix to the hour. This works
var time1 = DateTime.ParseExact("0919", "Hmm", CultureInfo.InvariantCulture);
Perhaps you want to just prefix 3-character times with a leading zero before parsing.

Much appreciated for all the answers. I don’t have control of the text being created so the simplest solution for me seemed to be prefixing a zero as opposed to adding a colon in the middle.
var text = "919";
var time = DateTime.ParseExact(text.PadLeft(4, '0'), "Hmm", null);

Related

Time difference calculation when values accepted in 24 hour format

In C#, I am accepting 2 time values in textboxes and want to calculate the time between these 2 times. The times are accepted in 24 hour format as hhmm. There is no any semicolon or . is used in between hrs and mins.
I have tried following code :
DateTime ts1 = DateTime.Parse(TextBox3.Text);
DateTime ts2 = DateTime.Parse(TextBox4.Text);
TimeSpan ts = ts2-ts1;
TextBox12.Text = Convert.ToString(ts);
Getting the error as
String was not recognized as a valid DateTime.
Suppose TextBox3.Text = 0800 and TextBox4.Text = 2000 then TextBox12.Text = 12
Please help.
Since the format of the text in your text boxes is not the "default" date / time format the call to TimeSpan.Parse() fails / returns wrong results. (You are using a format without a colon : character for separating the hours and minutes).
In this case you'll need to specify the format explicitly, for example using the TimeSpan.ParseExact() method.
The following example parses the text "0854" into a TimeSpan value, representing the time 08:54
TimeSpan.ParseExact("0854", "hhmm", System.Globalization.CultureInfo.InvariantCulture)
You have three problems:
1) Trying to parse times as dates. Using DateTime.Parse is inappropriate here.
2) Even if you use TimeSpan.Parse, your example data does not conform to the required format for the parse method to recognise it. The accepted formats are shown here: https://msdn.microsoft.com/en-us/library/se73z7b9(v=vs.110).aspx For the time part, you would need at least to include a colon (:) between the hours and minutes in your input, e.g. 08:00.
So you can either do that, or use TimeSpan ts1 = TimeSpan.ParseExact(TextBox3.Text, "hhmm", System.Globalization.CultureInfo.InvariantCulture) in order to give it a custom format to recognise.
3) You should use the TimeSpan.Subtract method to accurately deduct one time period from the other. Currently just using - is unlikely to work, and the system will not know whether you want the output in hours, minutes, seconds or anything else.
TextBox12.Text = ts2.Subtract(ts1).Hours
Should give you what you want.
You probably ought to consider some other prior validation as well - checking that ts2 is actually greater than ts1 before allowing the input, and maybe using TryParseExact to attempt to parse the input and return true/false, in case the user has input the value incorrectly (you will get a FormatException from the Parse or ParseExact method if there's an incorrect input).

ParseExact/TryParseExact failing with single digit hour [duplicate]

This question already has answers here:
DateTime conversion from string C#
(3 answers)
Closed 5 years ago.
I have a time and a date value with no field delimiters which I'm attempting to parse into a DateTime using TryParseExact. The time component has a single digit hour, and two digit minutes and seconds.
The following expression:
DateTime.ParseExact("20170101 84457", "yyyyMMdd Hmmss",
System.Globalization.CultureInfo.InvariantCulture)
results in FormatException with the message "String was not recognized as a valid DateTime.". I am assuming that this is because the time can't be unambiguously resolved, however since mm and ss are always going to be two digits each, I don't understand why this would be an issue.
The following results in successful parsing:
Hacking the input time to include delimiters (e.g., '8:44:57' and 'H:mm:ss')
Kludging the input time to have a leading zero if < 6 digits
Both of these seem a bit of a hack.
From what I can understand from other people's research, parsing attempts to retrieve two digits if it can, and parses from left to right.
Using my failing example of the raw time value 84857 and format Hmmss, because the hour is followed by a digit, it will be parsed as 84 - hence throwing a format exception.
According to the documentation:
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".
So it appears that if you don't have any delimiters, you are required to use HH and not H.
Personally I would pad the time component to 6 digits and use HH. The following works fine for me:
DateTime.ParseExact("20170101 084457", "yyyyMMdd hhmmss", System.Globalization.CultureInfo.InvariantCulture);
If you want to wrap this in a custom function, you can use something like this:
static DateTime ParseDateTime(string input)
{
int dateInteger, timeInteger;
var s = input.Split(' ');
bool dateOK = int.TryParse(s[0], out dateInteger);
bool timeOK = int.TryParse(s[1], out timeInteger);
if (!dateOK || !timeOK) throw new FormatException("Invalid date/time string.");
var newInput = String.Format("{0:00000000} {1:000000}", dateInteger, timeInteger);
return DateTime.ParseExact(newInput, "yyyyMMdd hhmmss", System.Globalization.CultureInfo.InvariantCulture);
}

date month not displaying correctly

why is
string date = string.Format("{0:mmddyyHHmmss}",
DateTime.Now);
giving me 420813104204
shouldn't it be 040813... ?
I am trying to match
mmddyyHHmmSS
You need to use MM for month not mm, mm is for minutes not months.
string date = string.Format("{0:MMddyyHHmmss}",
You can find more about formats here.
try this instead
string date = string.Format("{0:MMddyyHHmmss}", DateTime.Now);
string date = string.Format("{0:MMddyyHHmmss}", DateTime.Now);
would give you the required format.
Check out this link for reference
That's because mm is for the minute not months, you need to use MM. You can see the definition for custom date time strings here.
string date = string.Format("{0:MMddyyHHmmss}",
Further, I generally don't use string.Format with DateTime objects because I've seen some anomalies when it comes to parsing them across different cultures. Leveraging the ToString method on the DateTime object for me has always been more reliable. That's just something I've seen - it also could be that I was doing something wrong with the string.Format. I wish I could build an example of that right now but I don't even remember what those anomalies are now - I just remember having problems so I switched.

How to parse this string as a DateTime

How can I parse the following string to DateTime with timezone?
Should I use CultureInfo? TimeZoneInfo? Or some other kind?
15.08.11 17:15:18.084867000 +02:00
I have try to use the following format:
var z = DateTime.Now.ToString("dd.MM.yy H:mm:ss.fffffff", CultureInfo.InvariantCulture);
But it threw an exception.
DateTime.ParseExact is what you want.
The actual format string you need is dd.MM.yy HH:mm:ss.FFFFFFF00 zzz
var dateTest = "15.08.11 17:15:18.084867000 +02:00";
var format = "dd.MM.yy HH:mm:ss.FFFFFFF00 zzz";
var returnDate = DateTime.ParseExact(dateTest, format, System.Globalization.CultureInfo.InvariantCulture);
The problem is that the fractional portion of seconds can only be 7 digits, and you need to pad the format string with zeros to cater for it.
There is a problem in that the last two digits of the seconds must be 00, otherwise the format won't work, so if the last two digits are ever anything other than 00 this format string won't work for you.
You'd need to parse out the entire string excluding the last to digits of the seconds but keeping the rest of the string intact. If one was to go to that much bother one might be as well off just manually parsing the string.
Sorry I can't be of more help.

DateTime.TryParseExact not working as expected

why does this not work?
DateTime.TryParseExact(text, "H", CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out value);
I want to parse an Time value only providing the hour part, but it throws a FormatException.
On the other hand, this works:
DateTime.TryParseExact(text, "HH", CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out value)
Anybody knows the cause?
Thanks.
Okay, I had to look this one up - it seems like it should be working, but it does not because the custom format string is not valid. A custom format string needs to be at least two characters wide - see:
http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx#UsingSingleSpecifiers
So, according to the documentation, you can fix this by using this code:
DateTime.TryParseExact(text, "%H", CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out value);
I guess this means that TryParseExact does not manage to fit the hour part into a single char, and that is understandable enough to me since hour will either be 12 or 24 hour based.
Without more specific information, the DatTime you're constructing can't determine AM / PM given the input. H would only allow a value of 1 - 12, leaving ambiguity. The HH provides the extra info.
The format specifier you pass to DateTime.TryParseExact needs to exactly match the string you are parsing.
E.g. passing "15:20" with format of "H" will fail, because there is other content in the string.
Either parse the whole string and use DateTime.Hour to just get the hour, or create a string with just the hour part and use Int32.Parse.

Categories