var date= DateTime.ParseExact("16-03-2022 1:30", "dd-MM-yyyy HH:mm", CultureInfo.InvariantCulture);
When I enter 16-03-2022 13:30, it does not give an error but when the parameter is 16-03-2022 1:30, I get an error, how can I solve it?
I feel like taking a risk to answer but..
Let's go step by step. One of the good things about .NET methods is that you can see what exceptions can be thrown on that method in their documentation.
From "Exception" section on documentation it says;
FormatException
s or format is an empty string.
-or-
s does not contain a date and time that corresponds to the pattern
specified in format.
-or-
The hour component and the AM/PM designator in s do not agree.
Your s or format is not empty, your string does not have any AM or PM designator, so the only option left is "s does not contain a date and time that corresponds to the pattern specified in format." as a reason.
Also from documentation, it says;
Converts the specified string representation of a date and time to its
DateTime equivalent using the specified format and culture-specific
format information. The format of the string representation must match
the specified format exactly.
What "format" we are talking about? There are two of them. Custom date and time format strings and Standard date and time format strings. Since we are using DateTime.ParseExact, we need to consider using custom date and time format.
Let's look at all parts can be parse in your 16-03-2022 1:30 string;
16 --> Two digit day number (dd)
03 --> Two digit month number with leading zero (MM)
2022 --> Four digit year (yyyy)
1 --> One digit hour (it can be h or H because there is no time designator in your string and we can't know it's in 12-hour clock format or 24-hour clock format)
30 --> Two digit minutes (mm)
So, the proper format of your 16-03-2022 1:30 string can be either dd-MM-yyyy H:mm or dd-MM-yyyy h:mm which depends on you. If it is 24-hour format, use H specifier, if it is 12-hour format, use h specifier.
When you see the word "Exact" in ParseExact(), it means it. Any deviation from the expected format at all will cause an exception.
In this case, the HH specifier is not an exact match for the 1 value for the hour. It would match if you had 01 instead, but just 1 isn't the same thing. To match the hours without leading zeros you need a single H, creating this format string:
dd-MM-yyyy H:mm
This will still match later hours like "10" and "11". Additionally, the capital "H" instead of lower-case means it still expects 24-hour time, so numbers like "13" up to "23" still work, too.
If you could get a mix of values, that sometimes has just the 1 and sometimes might have the full 01, then you need to use a ParseExact() overload that accepts an array of formats, and provide both versions.
Related
Does following DateTime format "%M/%d/yyyy %H:%m:%s" will include both lines, e.g. with or without leading zero:
Line 1: 4/8/2022 7:6:3
Line 2: 04/08/2022 07:06:03
It's seems to be working but related documentation is more welcome.
The related documentation can be found here: https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings
Note the description of the % symbol: "Defines the following character as a custom format specifier".[1]
Since you have a custom date time format string, the symbols M, d, H, ... are custom format specifiers. This means, here % essentially becomes a no-operation without any effect, because the symbols following it are already custom format specifiers.
So, what exactly is the purpose of % if the symbols in a custom date time format string are already custom format specifiers regardless of % being there or not? The reason for % becomes understandable when you consider that there are also standard date time format strings, which consist of a single character, a single format specifier. Pertinent documentation here: https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings
Basically, any date time format string made of only one character is treated as a standard date time format string. And any date time format string with two or more characters is treated as a custom date time format string.
What if you want to use a custom date time format string consisting of only one custom format specifier? That one-character string will be interpreted as a standard date time format string instead. And that is a problem.
If you compare the lists of specifiers for standard and custom date time format strings, you'll notice that many of the standard date time format specifiers use symbols that are also used by custom date time format specifiers. However, standard date time format specifiers represent different data and/or formatting patterns than the respective custom date time format specifier using the same symbol. For example, the standard date time format specifier y yields year+month, while the custom date time format specifier y yields the last two digits of the year.
Therefore, if you need a functionally single-specifier custom date time format string, you gotta fatten up that string and turn it from a one-character string into a two-characters string with the help of the "no-op" specifier %, so that it will be correctly treated as a custom date time format string.
As an example, imagine you want to get just the last two digits of the year and nothing more, and you decide to use the custom format specifier y which does exactly what you want. However, the format string "y" is a standard date time format string yielding year+month. So, how do you get what you want? You turn the standard date time format string "y" into a custom date time format string by using "%y".
[1]According to that documentation, it should theoretically be possible to use contiguous sequences of multiple % in custom date time format string like "%%%%%M/%%%%%%d". Each of those % sequences should functionally collapse into a single %, as by definition according to the quoted documentation, each % defines the following % as a custom format specifier that it already is. However -- and for the better, i might add -- the DateTime formatting functions will have none of such shenanigans and throw a FormatException for you being a bad boy having even tried this...
I am trying to convert string dates like 2020-01-14T17:01:48.757Z and 2020-01-14T17:01:50.760Z in to C# DateTime. Looks like my parsing is failing somewhere.
DateTimeOffset.ParseExact("2020-01-14T17:01:48.757Z", "yyyy-MM-dd'T'HH:mm:sszzz", CultureInfo.InvariantCulture).DateTime;
Whats wrong with above code ? It fails with
String '2020-01-14T17:01:50.760Z' was not recognized as a valid
DateTime.
When I parse same date online https://nsdateformatter.com/ It has no issues.
I even tried using yyyy-MM-dd'T'HH:mm:ssZ but it also gives above error.
Use this date format:
DateTimeOffset.ParseExact("2020-01-14T17:01:48.757Z", "yyyy-MM-ddTHH:mm:ss.fffZ", CultureInfo.InvariantCulture).DateTime;
2020-01-14T17:01:48.757Z
yyyy-MM-ddTHH:mm:ss.fffZ
As You see format corresponds to Your provided date string.
Looks like you forget to use proper format specifier for your milliseconds part and dot (.) between your seconds and milliseconds part.
The "fff" custom format specifier
The "fff" custom format specifier represents the three most
significant digits of the seconds fraction; that is, it represents the
milliseconds in a date and time value.
DateTimeOffset.ParseExact("2020-01-14T17:01:48.757Z",
"yyyy-MM-dd'T'HH:mm:ss.fffZ",
CultureInfo.InvariantCulture)
In a .Net application, I would like to format a date and time in a fixed length format, but with no leading zeros for the day as below:
String.Format("{0:d MMM HH:mm:ss}", DateTime.Now);
"25 Jun 04:21:11"
This works for days of the month greater than ten, but (as documented) does not insert a leading space. Now, the following should provide the format required:
String.Format("{0,2:d}", DateTime.Now);
"25/06/2016"
but, as is seen, formats the date instead using the standard Short date format string. I can use:
String.Format("{0,2:''d} {0:MMM HH:mm:ss}", DateTime.Now.AddDays(-20));
" 5 Jun 04:21:11"
to get the desired effect, but this does not seem very satisfactory.
Is there less of a workaround to have the formatter use the Custom format string interpretation of an isolated d instead of the Short date Standard format?
To distinguish between a custom and standard format when the format is only a single character, use the % symbol. For example: {0:d} gives the standard date format, but {0:%d} gives just the day of the month. See the MSDN docs for more details.
So, you could do this:
String.Format("{0,2:%d} {0:MMM HH:mm:ss}", ...
However, consider that you could also just specify the length of the entire string:
String.Format("{0,15:d MMM HH:mm:ss}", ...
Of course, this assumes that MMM will always be three characters long. That is true for English (as .NET uses "Sep" instead of "Sept"), but isn't guaranteed for all languages and locales.
Also note that you should use HH for 24 hour time. hh gives 12 hour time, but is meaningless without using tt to indicate the meridem designation (am/pm).
Using the below DateTime.TryPaseExact method gives me different out puts when one is expected.
I get the following formats returned from the code below:
2014-02-10 18:32:37
1402-10-18 17:23:00 (which is clearly incorrect)
How do I just get a yyyy-MM-dd HH:mm:ss format returned?
static readonly string[] DateFormats = new string[] { "yyMMddHHmm", "yyyyMMddHHmm", "yyMMddHHmmss", "yyyy-MM-dd HH:mm:ss" };
DateTime date;
DateTime.TryParseExact("140211090915", DateFormats, CultureInfo.InvariantCulture,
DateTimeStyles.AssumeLocal, out date);
Also if someone could explain why this 140211084947 input returns the expected format and 140211090915 returns an unwanted format I would be grateful
It is clear that you are mistaken.
When the format is yyMMddHHmmss, it is taking first 2 digits as a year which in this case is 14 and is automatically converted to 2014.
When format is something like yyyy...., it is taking first 4 digits as a year which in your case is 1402.
From The "yy" Custom Format Specifier
In a parsing operation, a two-digit year that is parsed using the "yy"
custom format specifier is interpreted based on the
Calendar.TwoDigitYearMax property of the format provider's current
calendar.
From Calendar.TwoDigitYearMax property
This property allows a 2-digit year to be properly translated to a
4-digit year. For example, if this property is set to 2029, the
100-year range is from 1930 to 2029. Therefore, a 2-digit value of 30
is interpreted as 1930, while a 2-digit value of 29 is interpreted as
2029.
As Marcin mentioned, your string input doesn't match with yyMMddHHmm and yyyy-MM-dd HH:mm:ss formats.
Your 140211084947 string matches with yyMMddHHmmss format but it doesn't match with yyyyMMddHHmm format (Because 49 is not a valid hour)
I have a date with the following format:
20/01/2011 7:15:28 PM
I need to convert it to something like:
2011-01-20 09:24:06
How would I do this?
Thanks in advance.
DateTime.ParseExact("20/01/2011 7:15:28 PM",
"dd/MM/yyyy h:mm:ss tt",
CultureInfo.InvariantCulture)
.ToString("yyyy-MM-dd HH:mm:ss")
The most explicit way to do this would be:
DateTime.ParseExact("20/01/2011 7:15:28 PM", "dd/MM/yyyy h:m:s tt",
CultureInfo.InvariantCulture).ToString("yyyy-MM-dd HH:mm:ss")
First you'll need to parse the original date (Assuming you don't already have it as DateTime)
Then you will need to format it, see Date formatting in c#
DateTime time = DateTime.Now; // Use current time
string format = "yyyy-MM-dd HH:mm:ss"; // Use this format
time.ToString(format); // Write to console
Formats
d
Use this to specify the numeric value for the day of the month. It will be one or two digits long.
dd
This is the same as a single d, except there are always two digits, with a leading 0 prepended if necessary.
ddd
This displays a three-letter string that indicates the current day of the week.
dddd
This displays the full string for the day of the week.
f
ff
fff
ffff
fffff
ffffff
fffffff
F
FF
FFF
FFFF
FFFFF
FFFFFF
FFFFFFF
Use the lowercase f to indicate the seconds to one digit length. Use two lowercase fs to indicate the seconds to two digits. The uppercase F patterns do the same but work differently on trailing zeros.
gg
Use this to display A.D. on your date. It is unlikely that this will be B.C. in most programs.
h
Display the hours in one digit if possible. If the hours is greater than 9, it will display two digits. Range is 1-12.
hh
Display the hours in two digits always, even if the hour is one digit. The range here will be 01-12.
H
This represents the hours in a range of 0-23, which is called military time in some parts of the world.
HH
This represents the hours in a range of 00-23. The only different here between the single H is that there is always a leading zero if the number is one digit.
K
Use this to display time zone information.
m
mm
This formats the minutes in your date format string. Here, the one m means that there is only one digit displayed if possible. The two ms means that there are always two digits displayed, with a leading zero if necessary.
M
MM
These display the months in numeric form. The one uppercase M does not have a leading zero on it. The two uppercase Ms will format a number with a leading zero if it is required.
MMM
This displays the abbreviated three-letter form of the month represented in the DateTime.
MMMM
This displays the full month string, properly capitalized.
s
ss
The lowercase s displays seconds. A single lowercase s means that you do not require a leading zero. Two lowercase s characters means you always want two digits, such as 00-59.
t
Use the lowercase t to indicate A, when the time is in the AM, and P, for when the time is in PM.
tt
Use two lowercase tts to display the full AM or PM string. You will normally want this for when you are displaying the string to a user.
y
yy
yyy
yyyy
yyyyy
These display the year to different digits. In your programs, you won't need three digits for the year, or five. Therefore, you should only consider one y, two ys, or four ys.
z
zz
zzz
These represent the offset from the UTC time on the local operating system.
:
This is the time separator.
/
This is the date separator.
Regards
Check this:
String Mydate = "20/01/2011 7:15:28 PM";
String result = DateTime.Parse(MyDate).ToString("yyyy-MM-dd HH:mm:ss")
MessageBox.Show(result);
Regards