I need to know if a given string is a valid DateTime format string because the string may represent other things. I tried DateTime.ParseExact(somedate.ToString(format), format)
Thank you everyone. I 'upped' all of you and settled on a brute force implementation that doesn't use a Dictionary/HashSet and doesn't convert chars to strings:
private const string DateTimeFormatCharacters = "yYmMdDhHsS";
private static bool IsDateTimeFormatString(string input)
{
foreach (char c in input)
if (DateTimeFormatCharacters.IndexOf(c) < 0)
return false;
return true;
}
Slightly shorted Dan Tao's version since string represents an implementation of IEnumerable<&char>
[TestClass]
public class UnitTest1 {
private HashSet<char> _legalChars = new HashSet<char>("yYmMdDsShH".ToCharArray());
public bool IsPossibleDateTimeFormat(string format) {
if (string.IsNullOrEmpty(format))
return false; // or whatever makes sense to you
return !format.Except(_legalChars).Any();
}
[TestMethod]
public void TestMethod1() {
bool result = IsPossibleDateTimeFormat("yydD");
result = IsPossibleDateTimeFormat("abc");
}
}
Something like
Regex regex = new Regex("^(y|Y|m|M|d|D|s|S|h|H)+$");
if (regex.IsMatch('DateTime String'))
{
// 'valid'
}
if you're literally searching for those characters and not the numerical representation for a given date and time
With .NET2, you need to roll your own check for this. For example, the following method uses a foreach to check:
bool FormatValid(string format)
{
string allowableLetters = "yYmMdDsShH";
foreach(char c in format)
{
// This is using String.Contains for .NET 2 compat.,
// hence the requirement for ToString()
if (!allowableLetters.Contains(c.ToString()))
return false;
}
return true;
}
If you had the option of using .NET 3.5 and LINQ, you could use Enumerable.Contains to work with characters directly, and Enumerable.All. This would simplify the above to:
bool valid = format.All(c => "yYmMdDsShH".Contains(c));
There's a new project, NLib, which can do this much faster:
if (input.IndexOfNotAny(new char[] { 'y', 'm', 'd', 's', 'h' }, StringComparison.OrdinalIgnoreCase) < 0)
{
// Valid
}
Like this:
static readonly Regex Validator = new Regex(@"^[yYmMdDsShH]+$");
public static bool IsValid(string str) {
return Validator.IsMatch(str);
}
The regex works like this:
^
matches the beginning of the string[...]
matches any of the characters that appear in the brackets+
matches one or more characters that match the previous item$
matches the end of the stringWithout the ^
and $
anchors, the regex will match any string that contains at least one valid character, because a regex can match any substring of the string use pass it. The ^
and $
anchors force it to match the entire string.