zrabzdn
zrabzdn

Reputation: 1435

Get file with max datetime in name from directory

I have zip files in directory. How can I get file with max datetime in file name?

My files format:

Files_2013.06.04_15-42-55.zip Files_2013.06.03_15-42-55.zip ...

Upvotes: 0

Views: 1617

Answers (5)

Vlad I.
Vlad I.

Reputation: 425

if date format same for all files and if in 2013.06.04 the 06 is a month number then you could avoid DateTime.Parse or ParseExact.

Note: these methods applicable only if date in file name follow pattern yyyy.MM.dd_HH-mm-ss.

For case if all file names always follow same pattern (in your case 'File_yyyy.MM.dd_HH-mm-ss.zip'), then you can use max element

  var files = Directory.GetFiles(path);
  var fileWithMaxDate = files.Any() ? files.Max(f=>f) : (string)null;

For case if only date part follow pattern yyyy.MM.dd_HH-mm-ss:

  private const string DatePattern = "yyyy.MM.dd_HH-mm-ss";
  private static readonly int DatePatternLen = DatePattern.Length;
  var files = Directory.GetFiles(path);
  var fileWithMaxDate = files
                .Where
                  (f =>  Path.GetFileNameWithoutExtension(f).Length >= DatePatternLen)
                .OrderByDescending
                  (f => Path.GetFileNameWithoutExtension(f)
                            .Substring(f.Length - DatePatternLen))
                .FirstOrDefault();

In other cases you will need to cast date part to DateTime for right ordering

Upvotes: 0

Ahmed KRAIEM
Ahmed KRAIEM

Reputation: 10427

This is how to do it:

//var files = Directory.EnumerateFiles("path/to/dir");
var files = {"Files_2013.06.04_15-42-55.zip", "Files_2013.06.03_15-42-55.zip"};
var date = files.Max(f => 
            DateTime.ParseExact(f, "'Files_'yyyy'.'MM'.'dd'_'HH'-'mm'-'ss'.zip'", 
            CultureInfo.InvariantCulture));
Console.WriteLine(date);

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1500145

Given that your files appear to be using a sortable format, you can just sort the names in descending lexicographic order, and take the first entry. (Or sort them in ascending order and take the last entry, of course.)

That's assuming the examples you've given are truly representative, of course. If you've got a mixture of different prefixes, for example, you would probably want to parse the date part from each filename. LINQ would make this reasonable simple:

var latestFile = files.OrderByDescending(ParseFileDateTime)
                      .FirstOrDefault();

...

public static DateTime ParseFileDateTime(string name)
{
    int dateTimeStartIndex = name.Length - 19;
    if (dateTimeStartIndex < 0)
    {
        throw new ArgumentException("No date/time in filename: " + name);
    }
    string text = name.Substring(dateTimeStartIndex);
    return DateTime.ParseExact(text,
                               "yyyy'.'MM'.'dd'_'HH'-'mm'-'ss",
                               CultureInfo.InvariantCulture);
}

FirstOrDefault will return null if files is an empty sequence.

Note that we're only able to get away with taking the last 19 characters because your date/time format is fixed length. If you ever changed it to use the name of the month (or something similar) you'd need to work out a different way of finding out which part of the filename was the date/time.

Upvotes: 1

Piotr Czarnecki
Piotr Czarnecki

Reputation: 1688

You can go with following flow:

  1. Get all the file names from specific directory.
  2. Parse name to get only date part (between '_' signs ). Use Regex.Match
  3. After that you can use DateTime.ParseExact method to get collection of dates
  4. After that you can go with linq Max() method.

Upvotes: 0

3wic
3wic

Reputation: 500

Just split your string, bring the date and time together, convert it to datetime and then take a look at linq to find the max datetime.

edit: Don't forget to load all your filename into an array for exemple, do the same with your constructed datetime so you will find the good filename at the same index as the max datetime returned by linq.

Upvotes: 0

Related Questions