I want to check whether a string contains dates such as 1/01/2000 and 10/01/2000 in dd/MM/yyyy format.
So far I have tried this.
DateTime dDate = DateTime.Parse(inputString);
string.Format("{0:d/MM/yyyy}", dDate);
But how can I check if that format is correct to throw an exception?
string inputString = "2000-02-02";
DateTime dDate;
if (DateTime.TryParse(inputString, out dDate))
{
String.Format("{0:d/MM/yyyy}", dDate);
}
else
{
Console.WriteLine("Invalid"); // <-- Control flow goes here
}
you can use DateTime.ParseExact with the format string
DateTime dt = DateTime.ParseExact(inputString, formatString, System.Globalization.CultureInfo.InvariantCulture);
Above will throw an exception if the given string not in given format.
use DateTime.TryParseExact if you don't need exception in case of format incorrect but you can check the return value of that method to identify whether parsing value success or not.
check Custom Date and Time Format Strings
I think one of the solutions is to use DateTime.ParseExact or DateTime.TryParseExact
DateTime.ParseExact(dateString, format, provider);
source: http://msdn.microsoft.com/en-us/library/w2sa9yss.aspx
https://msdn.microsoft.com/es-es/library/h9b85w22(v=vs.110).aspx
string[] formats= {"M/d/yyyy h:mm:ss tt", "M/d/yyyy h:mm tt",
"MM/dd/yyyy hh:mm:ss", "M/d/yyyy h:mm:ss",
"M/d/yyyy hh:mm tt", "M/d/yyyy hh tt",
"M/d/yyyy h:mm", "M/d/yyyy h:mm",
"MM/dd/yyyy hh:mm", "M/dd/yyyy hh:mm"};
string[] dateStrings = {"5/1/2009 6:32 PM", "05/01/2009 6:32:05 PM",
"5/1/2009 6:32:00", "05/01/2009 06:32",
"05/01/2009 06:32:00 PM", "05/01/2009 06:32:00"};
DateTime dateValue;
foreach (string dateString in dateStrings)
{
if (DateTime.TryParseExact(dateString, formats,
new CultureInfo("en-US"),
DateTimeStyles.None,
out dateValue))
Console.WriteLine("Converted '{0}' to {1}.", dateString, dateValue);
else
Console.WriteLine("Unable to convert '{0}' to a date.", dateString);
}
You can use below IsValidDate():
public static bool IsValidDate(string value, string[] dateFormats)
{
DateTime tempDate;
bool validDate = DateTime.TryParseExact(value, dateFormats, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None, ref tempDate);
if (validDate)
return true;
else
return false;
}
And you can pass in the value and date formats. For example:
var data = "02-08-2019";
var dateFormats = {"dd.MM.yyyy", "dd-MM-yyyy", "dd/MM/yyyy"}
if (IsValidDate(data, dateFormats))
{
//Do something
}
else
{
//Do something else
}
you could always try:
Regex r = new Regex(#"\d{2}/\d{2}/\d{4}");
r.isMatch(inputString);
this will check that the string is in the format "02/02/2002"
you may need a bit more if you want to ensure that it is a valid date like dd/mm/yyyy
Use an array of valid dates format, check docs:
string[] formats = { "d/MM/yyyy", "dd/MM/yyyy" };
DateTime parsedDate;
var isValidFormat= DateTime.TryParseExact(inputString, formats, new CultureInfo("en-US"), DateTimeStyles.None, out parsedDate);
if(isValidFormat)
{
string.Format("{0:d/MM/yyyy}", parsedDate);
}
else
{
// maybe throw an Exception
}
Try this
DateTime dDate;
dDate = DateTime.TryParse(inputString);
String.Format("{0:d/MM/yyyy}", dDate);
see this link for more info. http://msdn.microsoft.com/en-us/library/ch92fbc1.aspx
Related
edit: since I've had so many comments regarding utilising TryParseExact with a single format instead of an array:
I must test all of the formats within the array - the inputs can potentially be these formats, and my unit tests for these other formats actually work. I MUST use them all.
I am aware that DateTime.TryParse would match the first and not iterate further. Hence I am using TryParseExact as Microsoft shows. It should match exactly. BUT it doesn't work in this scenario.
TLDR: Given a string of the format "dd/MM/yyyy" with value "29/11/2019" DateTime.TryParseExact returns a match with the format "dd/MM/yyyy hh:mm tt" and value 29/11/2019 12:00 AM. Why?
Question: How can I ensure a string of the format "dd/MM/yyyy" returns as a match with the format "dd/MM/yyyy" instead of "dd/MM/yyyy hh:mm tt" when using TryParseExact?
The long explanation of Context;
I have the following problem. I need to parse multiple date formats from strings to datetime values. They (input strings) can appear in the following formats:
{ "dd/MM/yyyy hh:mm tt", "dd/M/yyyy hh:mm tt", "dd/MM/yyyy H:mm", "dd/MM/yyyy H:mm", "dd/MM/yyyy H:m", "dd/MM/yyyy", "dd-MM-yyyy", "d-M-yyyy", "dddd, d MMMM yyyy"};
To solve this, I wrote a string extension that parses a given input string and returns a bool success and a potential matching format.
private static readonly string[] _DateFormats = new string[] { "dd/MM/yyyy hh:mm tt", "dd/M/yyyy hh:mm tt", "dd/MM/yyyy H:mm", "dd/MM/yyyy H:mm", "dd/MM/yyyy H:m", "dd/MM/yyyy", "dd-MM-yyyy", "d-M-yyyy", "dddd, d MMMM yyyy"};
public static bool StringToDateTime(this string dateTimeString, out DateTime dateTimeValue, out string matchingFormat)
{
matchingFormat = ""; // defaults
dateTimeValue = new DateTime();
if (string.IsNullOrEmpty(dateTimeString)) return false;
foreach (string format in DateFormats)
{
matchingFormat = format;
if (DateTime.TryParseExact(dateTimeString, DateFormats, AUSCulture, DateTimeStyle, out dateTimeValue)) return true;
}
return false;
}
This returns the string input "29/11/2019 successfully" as the DateTime 29/11/2019 12:00 AM with the matching format as "dd/MM/yyyy hh:mm tt", rather than the format matching the original input 29/11/2019.
Given this issue, the only (duct-tape) solution I could think of is:
public static bool StringToDateTime(this string dateTimeString, out DateTime dateTimeValue, out string matchingFormat)
{
matchingFormat = ""; // defaults
dateTimeValue = new DateTime();
if (string.IsNullOrEmpty(dateTimeString)) return false;
foreach (string format in DateFormats)
{
matchingFormat = format;
if (DateTime.TryParseExact(dateTimeString, DateFormats, AUSCulture, DateTimeStyle, out dateTimeValue))
{
// ensure the datetime format is consistent with the dateTimeString passed to us.
if(dateTimeString.Length != matchingFormat.Length)
{
var _matchingFormat = DateFormats.First(d => d.Length == dateTimeString.Length);
matchingFormat = string.IsNullOrEmpty(_matchingFormat) ? matchingFormat : _matchingFormat;
}
return true;
}
}
return false;
}
Which works, but obviously, this has further issues (begetting the formatting of input, etc.). So I'd rather not use this.
System.DateTime cannot exist without the time component, so it's no possible to parse a date to DateTime and not the time component. It will default to the start of day e.g. 12:00 AM, which is the same result as calling dateTime.Date(). This will allow you to compare two dates without considering the time of day.
If having or storing the time element really bothers you then you can either create your own struct to store the date or consider using something like NodaTime that provides a date only struct.
Also, Dotnet 6 will introduce DateOnly and TimeOnly structs to do exactly this. You can read more about it on the MS devblogs.
You are passing the whole array of formats, so it will match any of them.
Since you are in a foreach over DateFormats, you only need to match against the current value.
So replace this line
if (DateTime.TryParseExact(dateTimeString, DateFormats, AUSCulture, DateTimeStyle, out dateTimeValue))
return true;
with this
if (DateTime.TryParseExact(dateTimeString, format, AUSCulture, DateTimeStyle, out dateTimeValue))
return true;
There are lots of thread for this , but I am still blocked at the following:
What I have:
I am trying to build windows phone App which will pick Date of Birth of an individual
Code Behind:
string dateString = "";
DateTime dt = DateTime.Now;
if (value != null && DateTime.TryParse(value.ToString(), culture, DateTimeStyles.None, out dt))
{
if (dt.Equals(DateTime.MinValue))
{
//dateString = "mm/dd/yyyy";
return "";
}
else
return dt.ToShortDateString();
}
else
return dateString;
}
what I need:
I want it to parse any date format which should be culture Independent.
What I tried:
1.I tried using CultureInfo.InvariantCultute, CultureInfo.CurrentCulture
2.Tried using ExactParser as follows:
string[] formats = {"M/d/yyyy h:mm:ss tt", "M/d/yyyy h:mm tt", "d/M/yyyy hh:mm:ss tt", "dd/MM/yyyy hh:mm:ss tt", "d/M/yyyy" , "dd/MM/yyyy" , "M/d/yyyy" ,"MM/dd/yyyy",
"MM/dd/yyyy hh:mm:ss", "M/d/yyyy h:mm:ss", "dd/MM/yyyy hh:mm:ss", "d/M/yyyy h:mm:ss",
"M/d/yyyy hh:mm tt", "M/d/yyyy hh tt", "d/M/yyyy hh:mm tt", "d/M/yyyy hh tt",
"M/d/yyyy h:mm", "M/d/yyyy h:mm", "d/M/yyyy h:mm", "d/M/yyyy h:mm",
"MM/dd/yyyy hh:mm", "M/dd/yyyy hh:mm","dd/MM/yyyy hh:mm", "dd/M/yyyy hh:mm"};
if (value != null && DateTime.TryParseExact(value.ToString(), format, CultureInfo.InvariantCulture, DateTimeStyles.None, out dt))
but that is too hardcoded and will not cover several cases.
Is there any way to pick DOB in any format?
Any help would be Appreciated. Thanks!!
Not really, because everyone has their own date formatting.
What you're basically trying to do is magically deduce the dates from the second half of the above XKCD comic. ;)
That said, the only way you could TRY and do this, is to parse a string with every format you think it might be, and then make a sanity check in every case where a parse was successful. Said sanity check would be difficult however... Does 11-02 mean February 11th or November 2nd? You'd require some sort of context.
Sorry, but it seems impossible, since datetime could be ambiguous, and that's why misinterpreted e.g.
"01/02/03" is
01 Feb 2003 (Russia)
02 Jan 2003 (USA)
03 Feb 2001 (China)
see http://en.wikipedia.org/wiki/Date_format_by_country
This will try all culture:
public static bool TryParseAnyDate(string dateValue, out DateTime result)
{
result = DateTime.MinValue;
foreach (CultureInfo cultureInfo in CultureInfo.GetCultures(CultureTypes.AllCultures))
{
if (DateTime.TryParse(dateValue, cultureInfo, DateTimeStyles.None, out result))
{
return true;
}
}
return false;
}
I am writing a syslog server that receives syslog messages and stores them in a database.
I am trying to parse the date string received in the message into a DateTime structure.
For the following examples, I'll be using an underscore in place of whitespace for clarity; the actual strings received have spaces.
The string I received is in the format "Jun__7_08:09:10" - please note the two whitespaces between the month and day.
If the day is after the 10th, the strings become "Jun_10_08:09:10" (one whitespace).
If I parse with:
DateTime.ParseExact(Log.Date, "MMM d HH:mm:ss", CultureInfo.InvariantCulture);
it works for strings from the 1st to 9th but throws exception from the 10th forward, and if I parse with one space, it throws an exception on the 1st to 9th (and works from the 10th on).
What is the correct way to parse this string?
Consider using this line:
DateTime.ParseExact(Log.Date,
"MMM d HH:mm:ss",
CultureInfo.InvariantCulture,
DateTimeStyles.AllowWhiteSpaces);
Notice that I removed one of the spaces between the month and the day. That's because AllowWhiteSpaces literally means:
Specifies that s may contain leading, inner, and trailing white spaces not defined by format.
Use the DateTime.ParseExact overload that takes an array of format strings:
DateTime.ParseExact(Log.Date,
new [] {"MMM d HH:mm:ss", "MMM d HH:mm:ss"},
CultureInfo.InvariantCulture,
DateTimeStyles.None);
You could remove the extra space first and then parse the string:
DateTime.ParseExact(Log.Date.Replace(" ", " "), "MMM d HH:mm:ss", CultureInfo.InvariantCulture);
DateTime's ParseExect Method has some overloads where you can pass multiple format that could be readed if the earlier one is not working. here a sample for you..
using System;
using System.Globalization;
public class Example
{
public static void Main()
{
string[] formats= {"M/d/yyyy h:mm:ss tt", "M/d/yyyy h:mm tt",
"MM/dd/yyyy hh:mm:ss", "M/d/yyyy h:mm:ss",
"M/d/yyyy hh:mm tt", "M/d/yyyy hh tt",
"M/d/yyyy h:mm", "M/d/yyyy h:mm",
"MM/dd/yyyy hh:mm", "M/dd/yyyy hh:mm"};
string[] dateStrings = {"5/1/2009 6:32 PM", "05/01/2009 6:32:05 PM",
"5/1/2009 6:32:00", "05/01/2009 06:32",
"05/01/2009 06:32:00 PM", "05/01/2009 06:32:00"};
DateTime dateValue;
foreach (string dateString in dateStrings)
{
try {
dateValue = DateTime.ParseExact(dateString, formats,
new CultureInfo("en-US"),
DateTimeStyles.None);
Console.WriteLine("Converted '{0}' to {1}.", dateString, dateValue);
}
catch (FormatException) {
Console.WriteLine("Unable to convert '{0}' to a date.", dateString);
}
}
}
}
// The example displays the following output:
// Converted '5/1/2009 6:32 PM' to 5/1/2009 6:32:00 PM.
// Converted '05/01/2009 6:32:05 PM' to 5/1/2009 6:32:05 PM.
// Converted '5/1/2009 6:32:00' to 5/1/2009 6:32:00 AM.
// Converted '05/01/2009 06:32' to 5/1/2009 6:32:00 AM.
// Converted '05/01/2009 06:32:00 PM' to 5/1/2009 6:32:00 PM.
// Converted '05/01/2009 06:32:00' to 5/1/2009 6:32:00 AM.
DateTime.ParseExact(date, "MMM d HH:mm:ss", CultureInfo.InvariantCulture,DateTimeStyles.AllowInnerWhite)
There is a SQL Server 2008 database for which I have to create a management software. The database contains a column named DateOfCreation. The table designer made this column as string and gave freedom to users to add date in any format they want and this was really a silly mistake by him. Now some users added as "24 Jan" or
"Jan 24" or "1991 1 12" and many unknown formats. What I want is that when I fetch this string date, a function should be called that will check the format and return -1 if date is not in correct format else return the converted date in DD/MM/YYYY. So how can I check the format of the date that string date variable is containing?
use DateTime.TryParseExact with your date format, it will return false in case if the date format is different or invalid.
For multiple formats you can specify multiple formats in a string array and then use that in DateTime.TryParseExact something like:
From MSDN - DateTime.TryParseExact Method (String, String[], IFormatProvider, DateTimeStyles, DateTime%)
string[] formats= {"M/d/yyyy h:mm:ss tt", "M/d/yyyy h:mm tt",
"MM/dd/yyyy hh:mm:ss", "M/d/yyyy h:mm:ss",
"M/d/yyyy hh:mm tt", "M/d/yyyy hh tt",
"M/d/yyyy h:mm", "M/d/yyyy h:mm",
"MM/dd/yyyy hh:mm", "M/dd/yyyy hh:mm"};
string[] dateStrings = {"5/1/2009 6:32 PM", "05/01/2009 6:32:05 PM",
"5/1/2009 6:32:00", "05/01/2009 06:32",
"05/01/2009 06:32:00 PM", "05/01/2009 06:32:00"};
DateTime dateValue;
foreach (string dateString in dateStrings)
{
if (DateTime.TryParseExact(dateString, formats,
new CultureInfo("en-US"),
DateTimeStyles.None,
out dateValue))
Console.WriteLine("Converted '{0}' to {1}.", dateString, dateValue);
else
Console.WriteLine("Unable to convert '{0}' to a date.", dateString);
}
DateTime.TryParse could help to some extent. However, you would be dependent on your user using an appropriate date/time format.
public Tuple<bool, DateTime> GetDateTime(string x)
{
DateTime DT = null;
return Tuple.Create((DateTime.TryParse(x, out DT)), DT)
}
may work. I can't guarantee it though.
When a date string has the day of the week attached to it, TryParse fails:
DateTime d;
string dateString = "Tuesday May 1, 2012 9:00 AM";
return DateTime.TryParse(dateString, out d); // returns false
What is the best way to deal with this so that I can safely determine it IS a date, and furthermore convert it to such?
You need to tell TryParseExact what format to look for:
DateTime d;
string dateString = "Tuesday May 1, 2012 9:00 AM";
return DateTime.TryParseExact(
dateString,
"dddd MMMM d, yyyy h:mm tt",
System.Globalization.CultureInfo.CurrentCulture,
System.Globalization.DateTimeStyles.None,
out d
);
This should do the trick :)
// Parse date and time with custom specifier.
string dateValue = "Tuesday May 1, 2012 9:00 AM";
string pattern = "dddd MMMM d, yyyy h:mm tt";
DateTime parsedDate;
if (DateTime.TryParseExact(dateValue, pattern, null,
DateTimeStyles.None, out parsedDate))
Console.WriteLine("Converted '{0}' to {1:d}.",
dateValue, parsedDate);
else
Console.WriteLine("Unable to convert '{0}' to a date and time.",
dateValue);
Reference
http://msdn.microsoft.com/en-us/library/w2sa9yss.aspx
http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx