I have a bunch of pictures in a folder, pictures whose names contain a substring which represent a date(time) like "YYYY-MM-DD-HH-MM-SS", "YYYYMMDD" or "YYYYMMDD_HHMMSS" and I would like to get the corresponding DateTime. I know how to do it (with several TryParseExact) would the name be exactly of these forms but it's the substring part which bothers me has I don't know how to code that. (I never used regexes so far.)
2 Answers
Another approach using regular expression.
class Program
{
static void Main()
{
string[] fileNames = Directory.GetFiles(folderPath);
string regexPattern = @"\d{4}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}|\d{8}_\d{6}|\d{8}";
foreach (string filePath in fileNames)
{
string fileName = Path.GetFileNameWithoutExtension(filePath);
Match match = Regex.Match(fileName, regexPattern);
if (match.Success)
{
string dateString = match.Value;
DateTime dateTime;
if (DateTime.TryParseExact(dateString,
new[] { "yyyy-MM-dd-HH-mm-ss", "yyyyMMdd_HHmmss", "yyyyMMdd" },
null, System.Globalization.DateTimeStyles.None, out dateTime))
{
Console.WriteLine($"File: {fileName}, DateTime: {dateTime}");
}
else
{
Console.WriteLine($"File: {fileName}, Could not parse date");
}
}
else
{
Console.WriteLine($"File: {fileName}, No valid date found");
}
}
}
}
Comments
You could run 3 regexes, one for each format. Something like this
internal class Program
{
static void Main(string[] args)
{
var testData = new string[]
{
"testfile2004-12-30-13-55-23.png",
"2004-12-30-13-55-23testfile.png",
"testfile20041230.png",
"20041230testfile.png",
"testfile20041230_135523.png",
"20041230_135523testfile.png",
};
foreach (var fileName in testData)
{
Console.WriteLine(DateTimeFromFileName(fileName));
}
}
//
private static DateTime DateTimeFromFileName(string fileName)
{
var dateTimePatterns = new[] { "yyyy-MM-dd-HH-mm-ss", "yyyyMMdd", "yyyyMMdd_HHmmss" };
foreach (var pattern in dateTimePatterns)
{
var regex = "";
switch (pattern)
{
case "yyyy-MM-dd-HH-mm-ss":
regex = @"\d{4}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}";
break;
case "yyyyMMdd":
regex = @"\d{8}";
break;
case "yyyyMMdd_HHmmss":
regex = @"\d{8}_\d{6}";
break;
}
var match = System.Text.RegularExpressions.Regex.Match(fileName, regex);
if (match.Success && DateTime.TryParseExact(match.Value, pattern, null,
System.Globalization.DateTimeStyles.None, out var dateTime))
return dateTime;
}
throw new FormatException("No valid date-time format found in the file name.");
}
}
TryParseExactalso takes an array of formats to try at once.