Seeing a strange issue where on some systems the below code steps into the if statement (i.e. it returns true) while in other systems it returns false and steps into the else statement. What environmental conditions or framework version changes am I missing where this was changed? For example .net Fiddle returns true, but my own console apps return false.
DateTime time;
formatText = "";
if (DateTime.TryParse (DateTime.Now.ToString(formatText), CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out time))
{
// If TryParseExact Worked
Console.WriteLine ("True: " + time.ToString ());
}
else
{
// If TryParseExact Failed
Console.WriteLine ("Failed to Parse Date");
}
String representations of DateTime are culture specific.
Passing an empty string or null as the format parameter of the ToString overload of DateTime is the same as passing the standard format specifier "G" - from the remarks section of the DateTime.ToString Method (String) msdn page:
If format is null or an empty string, the general format specifier, 'G', is used.
The TryParse overload you are using attempts to parse the DateTime value using the date and time formats available in the IFormatProvider format parameter - InvariantCulture in your case - so when you use TryParse with InvariantCulture, unless your current culture's ShortDatePattern and LongTimePattern properties are the same as in InvariantCulture, the tryParse will fail.
Related
I want to check if a given string is a valid .net date format.
so i have the following function that checks if the date format is correct
public void IsValidDateFormat(string dateFormat)
{
var flag = true;
try
{
DateTime.ParseExact(DateTime.Now.ToString(),
dateFormat,
System.Globalization.CultureInfo.InvariantCulture);
}
catch (Exception ex)
{
flag = false;
}
return flag;
}
However, The method is not working as expected. For a valid date format also it returns false.
dateFormat = ,, => returns false =>Passed
dateFormat = someinvalidformat => returns false =>Passed
dateFormat = MM/dd/yyyy => returns false => Not Passed
So MM/dd/yyyy is valid dateformat. But method returns false.
Is there a better way to check if given date format is valid .Net date format?
Update 1
I understand why method fails for MM/dd/yyyy or for other valid date formats. I am not asking why it fails. MM/dd/yyyy is just common valid date time format i am using here for example.
I am looking for a way to check if the given date format is valid .Net date format. So it could be any .Net date format.
Since the format returned by DateTime.ToString does not match your format (it includes the time part), ParseExact fails.
Validate the format by using public string ToString(string format, System.IFormatProvider provider) instead
public bool IsValidDateFormat(string dateFormat)
{
try {
string s = DateTime.Now.ToString(dateFormat, CultureInfo.InvariantCulture);
DateTime.Parse(s, CultureInfo.InvariantCulture);
return true;
} catch {
return false;
}
}
Note that date/time formats that may seem not to be valid, can in fact be valid, as some non-format characters are just outputted as is. E.g.
DateTime.Now.ToString("abcdefg", CultureInfo.InvariantCulture)
results in "abc27e6A.D.". So it is in fact a valid date/time format, even if it does not make a lot of sense. You can enhance the quality of the test by trying to parse the resulting date string. This will eliminate a lot of nonsensical formats.
This test ...
Console.WriteLine(IsValidDateFormat(",,"));
Console.WriteLine(IsValidDateFormat("a"));
Console.WriteLine(IsValidDateFormat("MM/dd/yyyy hh:mm:ss"));
Console.WriteLine(IsValidDateFormat("MM/dd/yyyy"));
Console.WriteLine(IsValidDateFormat("abcdefg"));
Console.ReadKey();
... prints
False
False
True
True
False
why not TryParse() or exact version? https://learn.microsoft.com/es-es/dotnet/api/system.datetime.tryparse?view=netframework-4.8
returns true if system can parse.
It does "the same" your method does.
Hi I have a string in following format 23/03/2014 and I have tried to convert it to this format:
string npacked = Convert.ToDateTime(packeddate).ToString("yyyy/MM/dd");
But I am getting an error:
String was not recognized as a valid DateTime
Also tried this:
string npacked = DateTime.Parse(packeddate).ToString("yyyy/MM/dd");
but same error.
try with ParseExact with the format
string npacked = DateTime.ParseExact(packeddate, "dd/MM/yyyy", CultureInfo.InvariantCulture).ToString("yyyy/MM/dd");
DEMO
Convert.ToDateTime is running a DateTime.Parse() on your string (23/03/2014). In the default culture (en-US) that is going to fail, since dates in that culture should be formatted MM/DD/YYYY. You need to switch to a different culture (like French) per MSDN:
// Reverse month and day to conform to the fr-FR culture.
// The date is February 16, 2008, 12 hours, 15 minutes and 12 seconds.
dateString = "16/02/2008 12:15:12";
try {
dateValue = DateTime.Parse(dateString);
Console.WriteLine("'{0}' converted to {1}.", dateString, dateValue);
}
catch (FormatException) {
Console.WriteLine("Unable to convert '{0}'.", dateString);
}
// Call another overload of Parse to successfully convert string
// formatted according to conventions of fr-FR culture.
try {
dateValue = DateTime.Parse(dateString, new CultureInfo("fr-FR", false));
Console.WriteLine("'{0}' converted to {1}.", dateString, dateValue);
}
catch (FormatException) {
Console.WriteLine("Unable to convert '{0}'.", dateString);
}
Calling "ToString" afterwards has no effect whatsoever on the parse attempt, it just formats the output of the parse.
It may be due to your system date time format. You have mm-dd-yyyy format in your system and you are trying to parse it in dd-mm-yyyy format. Try changing your system date format to dd/MM/yyyy.
Convert.ToDateTime(string) calls DateTime.Parse(string, CultureInfo.CurrentCulture) explicitly. That means your both lines are equivalent.
In your profile, it says you are from Dubai, United Arab Emirates. That's why I assume your CurrentCulture is probably ar-AE at first but your string matches it's ShortDatePattern and that's why it prints;
Convert.ToDateTime("23/03/2014", new CultureInfo("ar-AE")) // 23/03/2014
But you didn't tell us what is your CurrentCulture, we never know.. But looks like your current culture's date seperator is not / or your current culture doesn't have standart date format dd/MM/yyyy (which is unlikely for most of cultures) your both lines fail (first scenario is more likely).
You can easly parse your string with a culture that has / as a DateSeparator using DateTime.ParseExact method. This method let's you specify your custom date formats. We can use InvariantCulture for example;
var date = DateTime.ParseExact("23/03/2014",
"dd/MM/yyyy",
CultureInfo.InvariantCulture);
Now, let's consider to it's representation with yyyy/MM/dd format.
/ specifier has a special meaning of "replace me with the current culture's date separator" in custom date formats. That means if your date seperator is not / (I assume it is not) your date.ToString("yyyy/MM/dd") results will be included your date seperator, not /.
For example, I'm from Turkey, my culture is tr-TR. My date seperator is . (dot) That's why this example;
date.ToString("yyyy/MM/dd"); // Prints 2014.03.23 not 2014/03/23
In such a case, you can use a culture which has / a date seperator as a second parameter in your ToString method (InvariantCulture for example) like;
date.ToString("yyyy/MM/dd", CultureInfo.InvariantCulture) // Prints 2014/03/23
or you can escape your / character regardless which culture you use like;
date.ToString(#"yyyy\/MM\/dd") // Prints 2014/03/23
I'm using a library called Json.NET that uses the following code internally to parse a JSON string into a DateTime:
if (DateTime.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt))
{
dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling);
SetToken(JsonToken.Date, dt);
return dt;
}
I thought Json.NET was screwing up the conversion, but it looks like it's DateTime.TryParse itself that's botching the value.
When I parse the following valid Iso date (which corresponds to UTC DateTime.MinValue):
string json = "0001-01-01T00:00:00+00:00";
DateTime dt;
DateTime.TryParse(json, invariantCulture, DateTimeStyles.RoundtripKind, out dt);
The result is a localized DateTime: {0001-01-01 8:00:00 PM}, which when converted back to Utc time gives {0001-01-02 0:00:00 PM}. Essentially, the date underflowed, which is exactly the kind of problem you would expect DateTimeStyles.RoundtripKind to avoid.
How do I avoid this scenario?
Why use DateTimeStyles.RoundtripKind? The documentation for RoundtripKind says:
The DateTimeKind field of a date is preserved when a DateTime object is converted to a string using the "o" or "r" standard format specifier, and the string is then converted back to a DateTime object.
The string output from the "o" or "r" standard format specifiers are not like the ISO 8601 string you are trying to parse. It doesn't sound to me like RoundtripKind is really supposed to work with any date time string format. It sounds like the round trip is for the DateTime.Kind property when the string is in a particular format.
Since you know the format of the string you are trying to parse, then I would suggest using DateTime.TryParseExact.
I have had to support a couple different versions of the ISO 8601 string - either of these formats are valid date-time values in ISO 8601 (and there are even more options for dates, times and fractional seconds, but I didn't those):
0001-01-01T00:00:00+00:00
0001-01-01T00:00:00Z
Here's a method that will handle either of these formats:
private bool TryParseIso8601(string s, out DateTime result)
{
if (!string.IsNullOrEmpty(s))
{
string format = s.EndsWith("Z") ? "yyyy-MM-ddTHH:mm:ssZ" : "yyyy-MM-ddTHH:mm:sszzz";
return DateTime.TryParseExact(s, format, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out result);
}
result = new DateTime(0L, DateTimeKind.Utc);
return false;
}
I have a excel sheet in which am taking a date column in this format "23/8/11 01:33:01:PM"
and am inserting it in sql 2008 using datarow but am getting a error
String was not recognised as valid datetime.
Can any one please help?
DateTime newdate = Convert.ToDateTime(row[8].ToString());
Here how Convert.ToDateTime method looks like when you decompile it;
public static DateTime ToDateTime(string value)
{
if (value == null)
return new DateTime(0L);
else
return DateTime.Parse(value, (IFormatProvider) CultureInfo.CurrentCulture);
}
As you can see, this method use DateTime.Parse method with your CurrentCulture. And if your string doesn't match your current culture date format, your code will be broken. That's the reason you get this error.
Use DateTime.ParseExact with "dd/M/yy hh:mm:ss:tt" format instead.
Converts the specified string representation of a date and time to its
DateTime equivalent. The format of the string representation must
match a specified format exactly or an exception is thrown.
string s = "23/8/11 01:33:01:PM";
DateTime newdate = DateTime.ParseExact(s, "dd/M/yy hh:mm:ss:tt", CultureInfo.InvariantCulture);
Console.WriteLine(newdate);
Output will be;
8/23/2011 1:33:01 PM
Here a DEMO.
For your case;
DateTime newdate = DateTime.ParseExact(row[8].ToString(), "dd/M/yy hh:mm:ss:tt", CultureInfo.InvariantCulture);
For more informations, take a look;
Custom Date and Time Format Strings
Convert.ToDateTime internally calls DateTime.Parse which by default will use the current culture of your application. If 23/8/11 01:33:01:PM is not a valid format for this culture then this method will fail.
For specific date formats it's best to use DateTime.ParseExact e.g.
DateTime.ParseExact("23/8/11 01:33:01:PM", "dd/M/yy hh:mm:ss:tt", CultureInfo.InvariantCulture);
This approach makes your code culture independent which means the date will always be parsed correctly (given it's in the specified format).
This will work:
DateTime newdate = Convert.ToDateTime("8/23/11 01:33:01 PM");
I changed day and month and removed the colon a the end. But that is very specific. You need to know more about the dates passed to do that.
I have a date string in format "08/1999" I want to get the first date of the corresponding month. eg : in this case 08/01/1999.
It is simple for en-Us culture. I break the string, append "01" in the string to get 08/01/1999 and then DateTime.Parse(datestring) but this is valid for en-US culture only.
How can I do this for different culture ?
My datestring will always be in mm/yyyy format. and I am trying to obtain a DataTime obj from this dateString.
Use ParseExact method. Note upper-cased M's are for months and lower-cased m's for minutes.
string dateToConvert = "08/1999";
string format = "MM/yyyy";
CultureInfo provider = CultureInfo.InvariantCulture;
DateTime result = DateTime.ParseExact(dateToConvert, format, provider);
Output:
{1999-08-01 00:00:00}
You can also use Convert.ToDateTime and Parse methods. It will produce the same result, but in implicite way:
DateTime result = Convert.ToDateTime(dateToConvert, provider); // Output: {1999-08-01 00:00:00}
DateTime result = DateTime.Parse(dateToConvert, provider); // Output: {1999-08-01 00:00:00}
Read more at:
Parsing Date and Time Strings
Standard Date and Time Format Strings
Custom Date and Time Format Strings
I'm not sure if I understand your question correctly, but you can try passing CultureInfo.InvariantCulture if you want to force the US date format regardless of the regional settings of the client computer:
DateTime.Parse("08/1999", System.Globalization.CultureInfo.InvariantCulture)
I break the string, append "01" in the string to get 08/01/1999 and then DateTime.Parse(datestring)
That's a very long-winded way to do it. Simply this will work:
DateTime.Parse("08/1999")
How can I do this for different culture ?
If your string is always in this format, do this:
DateTime.Parse("08/1999", CultureInfo.InvariantCulture)