Delete files which are older than today's date - c#

I have some files in the format of "yyyyMMdd_hhmmss_abc.txt" in a particular location.
using the below code i am able to get all the files with "_abc.txt" in that folder.
fileArray = Directory.GetFiles(#"C://Documents", "*abc.txt");
for (int i = 0; i < fileArray.Length; i++)
{
fileArray[i] = Path.GetFileNameWithoutExtension(fileArray[i]);
Console.WriteLine(fileArray[i]);
}
But now I'm thinking of reading the file name, split it and then convert into date time object so that i can check for the condition(older than today's date) and delete them.
for eg: 20160426_045823_abc.txt
I want to split it into 2016, 04 , 26 and then convert into date time object using
Datetime d1 = new Datetime(2016,04,26) and then do other operations.
Is there any other way to solve this problem?
Thanks in advance

The following code can be used to get the collection of files having created date less than today's date, A simple iteration over the collection will help you to delete them as well: consider the code
Simple option:
foreach (var item in Directory.GetFiles(#"C://Documents", "*.txt")
.Where(x => new FileInfo(x).CreationTime.Date < DateTime.Now.Date))
{
File.Delete(item);
}
Based on Filename:
var fileArray = Directory.GetFiles(#"C://Documents", "*abc.txt");
for (int i = 0; i < fileArray.Length; i++)
{
DateTime fileNameTime;
string fileName = Path.GetFileNameWithoutExtension(fileArray[i]).Replace("_abc", " ");
fileNameTime = DateTime.ParseExact("yyyyMMdd_hhmmss", fileName, CultureInfo.InvariantCulture, DateTimeStyles.None);
if (fileNameTime.Date < DateTime.Now.Date)
{
File.Delete(fileArray[i]);
}
}
Please note : The best and effective option is the first one, what you need to do is assign the file-name as the dateTime at the time of
creation of the file(if it is under your control) so that the things
became easier for you

The filename is already in a sortable format based on the date. Instead of parsing bits of the filename into a DateTime object, why not create a filename based on today's date and filter your array of filenames down to only those that are string-comparison-less than your today's-date filename? It's probably quite a bit faster than doing date parsing on each filename, for large lists of files.
For example:
var path = "c:\\whatever";
var suffix = "_abc.txt";
var todaysFilename = DateTime.Now.ToString("yyyyMMdd_hhmmss") + suffix;
var filesToDelete = Directory.EnumerateFiles(path, "*" + suffix)
.Select(Path.GetFileName)
.Where(fileName => string.Compare(fileName, todaysFilename, StringComparison.Ordinal) < 0)
.ToArray();
foreach (var file in filesToDelete)
{
File.Delete(Path.Combine(path, file));
}

You could take the name of the string and do a DateTime.ParseExact.
String dateString = Path.GetFileNameWithoutExtension(fileArray[i])
DateTime d5 = DateTime.ParseExact(dateString, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None)
if (d5.Date < DateTime.Now.Date)
{
File.Delete(fileArray[i]);
}
This will take the first 8 characters of the string and parse do an exact parse on it.
Also you will probably just want the filename without the path and extension.
https://msdn.microsoft.com/en-us/library/w2sa9yss%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396

You can get the DateTime a file was created like this
DateTime time = File.GetCreationTime(fileName);
Yes it's that easy.

Related

Compare lastwritetime of file to todays date

I am trying to compare the date of a file to today's date but I'm always failing, even if the file is dated today.
My Code:
var dir = System.IO.Path.GetDirectoryName(line);
var filename = System.IO.Path.GetFileName(line);
var files = System.IO.Directory.GetFiles(dir, filename, System.IO.SearchOption.TopDirectoryOnly);
if (files.Length > 0)
{
var qry = from x in files
where System.IO.File.GetLastWriteTime(x) == DateTime.Now
select x;
if(!qry.Any())
{
Console.WriteLine("boom");
}
I suspect it has to to with the time on it. If so, how do I compare the GetLastWriteTime to today's date?
Thank you!
You should ignore the Time part of a DateTime variable and the GetLastWriteTime otherwise is practically impossible that you get any hit from that code.
var qry = from x in files
where System.IO.File.GetLastWriteTime(x).Date == DateTime.Today
select x;

How can i format the string to add '-' between the numbers?

var startIndexTimeDate = file.Path.IndexOf("time=") + "time=".Length;
var lengthTimeDate = file.Path.IndexOf("&", startIndexTimeDate) - startIndexTimeDate;
var timeDate = file.Path.Substring(startIndexTimeDate, lengthTimeDate);
What i'm getting in timeDate for example is:
201702012015
And i want to format it to be:
01-02-20-15-2017
Not only for this number for every time i will do this code. The format should be this way since i want to create a directory of this format.
01-02-20-15-2017
Then i will want to read it back from the hard disk the directory name to a List but this time the string should be format as a date time for example:
"01/02/2017 at 20:15"
So when i read it back i want to display it nicer to the user.
The directory on the hard disk will be in format of
01-02-20-15-2017
but when getting the directory name back to a List the format should be
"01/02/2017 at 20:15"
I would suggest you to parse DateTime object from your string, and after that format it in any way you want:
var s = "201702012015";
var date = DateTime.ParseExact(s, "yyyyMMddHHmm", CultureInfo.InvariantCulture);
var dirName = date.ToString("dd-MM-HH-mm-yyyy"); //01-02-20-15-2017
Then do the same when reading directory
var date = DateTime.ParseExact(dirName, "dd-MM-HH-mm-yyyy", CultureInfo.InvariantCulture);
var nameInList = date.ToString("dd/MM/yyyy a\\t HH:mm"); //01/02/2017 at 20:15

How can i create this format of date time directory but with my format?

The test i did is:
string date = DateTime.Now.ToString("ddd dd.MM.yyyy");
string time = DateTime.Now.ToString("HH.mm tt");
string format = "{0} from {1} At {2}";
string cp = string.Format(format, "", date, time);
Directory.CreateDirectory(#"c:\\temp\\" + cp);
The result in the variable cp is: from Fri 20.01.2017 At 09.27 AM
And there is no problem to create this directory.
This is my code:
for (int i = 0; i < countriesNames.Count(); i++)
{
string pathDateTime = urls[0].Substring(48, 12);
string pathDateTimeLast = urls[urls.Count - 1].Substring(48, 12);
var d = DateTime.ParseExact(pathDateTime, "yyyyMMddHHmm", CultureInfo.InvariantCulture);
var e = DateTime.ParseExact(pathDateTimeLast, "yyyyMMddHHmm", CultureInfo.InvariantCulture);
string country = countriesNames[i].Substring(15);
string f = "{0} from {1} At {2} until {3}";
string countryPath = countriesMainPath + "\\" + country + "\\" + string.Format(f, "", d,e);
if (!Directory.Exists(countryPath))
{
Directory.CreateDirectory(countryPath);
}
countryPaths.Add(countryPath);
}
The way i did it with the 'f' variable is not right and not working fine give me exception.
In my code in the variable 'd' there is 20/01/2017 05:15:00
And in variable 'e' 20/01/2017 07:30:00
But i can't create this directories.
So i want to format my date and time after extracting them to be like the format in the first example: from Fri 20.01.2017 At 09.27 AM but with my date and time.
For example my directory should be something like:
from Fri 20.1.2017 At 05:15 AM Until 20.1.2017 At 07:30 AM
Then to create this directory: "from Fri 20.1.2017 At 05:15 AM Until 20.1.2017 At 07:30 AM"
The question is how do i format my dates and times after parsed to this format ?
You are trying to create a path by formatting dates using your current locale's default (long) format. In most countries the date separator is / and the time separator is always :. This results in invalid paths.
It's a bit hard to understand what format you want to use, since you mix calls to String.Format and concatenate the results. It seems that the original path should be:
var cp=String.Format(#"c:\temp\From {0:ddd dd.MM.yyyy} At {0:HH.mm tt}",DateTime.Now);
or
var root="c:\temp\";
var partialPath = String.Format("From {0:ddd dd.MM.yyyy} At {0:HH.mm tt}",DateTime.Now)
var cp=Path.Combine(root,partialPath);
You don't need to format each component separately. If you check the documentation of String.Format you'll see that you can use a composite format string for each placeholder.
The country path seems to be
var partialPath = String.Format(#"{0}\from {1:ddd dd.MM.yyyy} At {1:HH.mm tt} until {2:HH.mm tt}",
country,d,e);
var countryPath =Path.Combine(countriesMainPath,partialPath);
That said, I wouldn't use that date format. The resulting folder names can't be sorted in a meaningful way making it difficult for users to find folders by date. I'd use the yyyy-MM-dd format, or yyyy-MM-dd ddd if the name of the day is really necessary.

Convert MM:SS string to HH:MM:SS in C#

I have this piece of code which works nicely to convert HH:MM:SS to seconds as an integer.
for (int i = 0; i < nrdaily.Rows.Count; i++)
{
double NRT = TimeSpan.Parse(nrdaily.Rows[i][3].ToString()).TotalSeconds;
nrdaily.Rows[i][3] = NRT;
}
However, I have a CSV file I'm dealing with where a field has many values that are stored in MM:SS format and TotalSeconds seems to misinterpret it as HH:MM and gives a false result.
How could I check the string to see if it's in HH:MM:SS format, and if it is in MM:SS convert it to HH:MM:SS?
Use TimeSpan.ParseExact
Example:
var testString = "01:05";
TimeSpan.ParseExact(testString, "mm\\:ss", CultureInfo.InvariantCulture).TotalSeconds;
//TotalSeconds will be 65
You could check the string length for starters to identify the format.
for (int i = 0; i < nrdaily.Rows.Count; i++)
{
string time = nrdaily.Rows[i][3].ToString();
if (time.Length == 5)
time = "00:" + time;
double NRT = TimeSpan.Parse(time).TotalSeconds;
nrdaily.Rows[i][3] = NRT;
}
Checking length is a very simplistic approach. To identify the format more accurately, you could use regular expressions.

Find highest DateTime from list of DateTime's

My Question is that, I want to find the highest DateTime from a list of DateTime?
I have one Array suppose string[] btime = new string[100];
In that Array I am storing the Date which is coming from the SQL-Server
The SQL Query is [CONVERT(varchar(10),GETDATE(),101)] it is returning the Date in format of MM/dd/yyyy
and then after I am concatenating the Date with my own given Time
i.e .btime[j] = SqlServerDate + " " + 15:20; and so on;
Now, from this given Array I want to find highest Date and Time
So, I have use this logic
string large=""
large=btime[0];
for (int i = 0; i < j; i++)
{
if (DateTime.Compare(DateTime.Parse(btime[i]),DateTime.Parse(large)) > 0)
{
large = btime[i];
}
}
but I am getting the Error at
if(DateTime.Compare(DateTime.Parse(btime[i]),DateTime.Parse(large)) > 0)
The Error is String not recognized as valid DateTime This error is occurring because of my System DateTime Format is yyyy/dd/MM
So Plz any one can help me in solving this problem
I don't want to change format of the system
Others have suggested different ways of parsing the DateTime. This seems pointless to me - if you can possibly change the query, just avoid performing the conversion to a string in the first place. The fewer conversions you use, the fewer chances you have for this sort of thing to be a problem.
Change the query so you end up with DateTime values, and then finding the latest one is trivial in LINQ:
DateTime latest = dateTimes.Max();
Hum,
// Containing your datetime field
string[] btime = new string[100];
var max = btime.Select(s => DateTime.Parse(s, "MM/dd/yyyy", CultureInfo.InvariantCulture)).Max();
Use the DateTime.ParseExact Method.
Example:
CultureProvider provider = CultureInfo.InvariantCulture;
DateTime.ParseExact(btime[i], "yyyy/dd/MM", provider);
you, can use DateTime.ParseExact() functionality to do this. Refer the following code part.
CurDate = DateTime.ParseExact(Name3, "yyyyMMddhhmmssffff", System.Globalization.CultureInfo.CurrentCulture, System.Globalization.DateTimeStyles.None)
You can use the DateTime.ParseExact() method.
CultureProvider provider = CultureInfo.InvariantCulture;
DateTime.ParseExact(btime[i], "MM/dd/yyyy HH:mm", provider);
The second parameter there is the format string. This specifies how your date will be formatted.
Since you are adding a 24 hour time at the end you need the HH:mm (HH says expect a 24 hour time).
Thanks to everyone.
I have got some sort of answer:
string large = "";
large = btime[0];
IFormatProvider culture = System.Threading.Thread.CurrentThread.CurrentCulture;
// This Code will convert the System Format in Thread, Not the Actual Format
// of The System
CultureInfo ciNewFormat = new CultureInfo(CultureInfo.CurrentCulture.ToString());
ciNewFormat.DateTimeFormat.ShortDatePattern = "MM/dd/yyyy";
System.Threading.Thread.CurrentThread.CurrentCulture = ciNewFormat;
for (int i = 0; i < TimeBackupCounter; i++)
{
if (DateTime.Compare(DateTime.Parse(btime[i]),DateTime.Parse(large)) > 0)
{
large = btime[i];
}
}

Categories