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;
Related
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.
I'm currently working on a project which needs to check for the day and time, then compare these with values in my database.
This needs to be done for an Live Chat, while we have opened.
I'm new to ASP.Net and this is giving me an headache.
I Have a table which contains these Rows:
- weekday
- starttime
- endtime
In my Controller for the Chat I have tried this so far
private Model1Container db = new Model1Container();
public ActionResult Index(Openinghours openinghours)
{
ViewBag.Opening = db.OpeninghoursSatz.ToList();
string CurrentDay = DateTime.Now.DayOfWeek.ToString();
string CurrentTime = DateTime.Now.TimeOfDay.ToString();
bool IsWeekDay= db.OpeninghoursSatz.Where(i => i.weekday == CurrentDay).Any();
var Starttime = db.OpeninghoursSatz.Find(CurrentDay);
Debug.Write("!!++" + Starttime);
My exact Problem is to compare the time with the two rows from my table.
I thought about putting the values in a variable and then compare them, but there must be a cleaner way for this.
I hope I was able to point out what my problem is, if not please ask.
With regards,
Nico
EDIT:
Maybe I should say that the database holds the hour it opens and the hour it closes (e.g. 9 and 17). I need to check if the current time is between these two.
int getStartHour = DateTime.Now.Hour;
int weekDay= (int)DateTime.Now.DayOfWeek;
bool value = db.OpeninghoursSatz.Where(m => getStartHour >= m.Starttime && getStartHour <= m.EndTime && m.weekday == weekDay).Any()
/// if everything is in int. or if in string
string getStartHour = DateTime.Now.Hour.ToString();
string weekDay= DateTime.Now.DayOfWeek.ToString();
bool value = db.OpeninghoursSatz.Where(m => getStartHour >= m.Starttime && getStartHour <= m.EndTime && m.weekday == weekDay).Any();
But in this case for Thursday , we will get Thursday, but in Int we will get 4.
The line looks odd to me:
var Starttime = db.OpeninghoursSatz.Find(CurrentDay);
I guess you should change it to something like:
if (IsWeekDay){
var Starttime = db.OpeninghoursSatz.Where(i => i.weekday == CurrentDay).First().StartTime;
Debug.Write("!!++" + Starttime);
}
I am developping an application where a user can download various reports. There is one report per month and each report is called "YYYY-MM.txt". An user can only download files of the last 18 months.
I have written a function that takes in parameter a list of filespath and then downloading them to the client. My problem is how to add files in this list, basically how can I check if a file is in the last 18 months, knowing that I have his year and month, and the current year and month.
This is what I have :
//just for test, supposed that theses values were extracted from the report of august 2014.
string fileYear = "2014";
string fileMonth = "08";
string currentYear = DateTime.Now.Year.ToString();
string currentMonth = DateTime.Now.Month.ToString();
How can I compare fileYear and fileMonth with currentYear and currentMonth to know if the report correspond to a month of the last 18.
Thanks in advance for your help
Here's how I would do it.
int fileYear = int.Parse(fileName.Substring(0,4));
int fileMonth = int.Parse(fileName.Substring(5,2));
DateTime oldestDate = DateTime.Now.AddMonths(-18);
int oldestYear = oldestDate.Year;
int oldestMonth = oldestDate.Month;
if(fileYear > oldestYear || (fileYear == oldestYear && fileMonth >= oldestMonth))
{
// This file is within 18 months.
}
This means that if today is 12-31-2014 it will include files back to 2013-06.txt. If needed you can also put an upper bounds check in case you could have files with future dates.
EDIT
The other alternative is to create a DateTime from the file name to compare. Here's how I would do that to ensure I'm comparing the last day of the file's month
int fileYear = int.Parse(fileName.Substring(0,4));
int fileMonth = int.Parse(fileName.Substring(5,2));
DateTime fileDate = new DateTime(fileYear, fileMonth, 1).AddMonths(1).AddDays(-1);
DateTime oldestDate = DateTime.Now.AddMonths(-18);
if(fileDate.Date >= oldestDate.Date)
{
// This file is within 18 months.
}
You could do something like this:
https://dotnetfiddle.net/VORvZr
using System;
public class Program
{
public static void Main()
{
DateTime fileDate = new DateTime(2013, 5, 1);
DateTime fileDateNewer = new DateTime(2014, 1, 1);
GetMonthDifference(fileDate);
GetMonthDifference(fileDateNewer);
}
public static void GetMonthDifference(DateTime fileDate)
{
DateTime currentDate = DateTime.Now;
DateTime eighteenMonthsAgo = currentDate.AddMonths(-18);
if (eighteenMonthsAgo > fileDate)
Console.WriteLine("{0} is greater than or equal to 18 months ago", fileDate);
else
Console.WriteLine("{0} is less than 18 months ago", fileDate);
}
}
Note that if you can, you always want to try to work with objects that most closely represent your data. E.g. if working with years you should work with a numeric type rather than string type. In this case, working with dates.
EDIT:
as comments posted on the other answers pointed out, you would have some room for error depending on the day the file was uploaded/created if it's right around the 18 month mark. Something you could potentially do is get the actual file creation date (assuming you are the system creating the file and the date of the file creation coincides with the month the data belongs. You can get a files creation date as such:
string fullFilePathAndName = #""; // wherever your file is located
FileInfo fi = new FileInfo(fullFilePathAndName);
DateTime fileCreateDate = fi.CreationTime
A part of my project is to write a function that will generate an increasing number for every day for every record I have to store in a database table. My problem is that when I try to compare the DateTime.Now with the column I have in my database, I try to compare Datetime with Date so I never have equality on the days. My code explains better than me my issue:
var r = (from i in context.vehicles
where i.InsertionDate == DateTime.Now
select i); // In this query i cant compare the two dates. The one is datetime and the other is date format
int result3 = 0;
if (r.Any())
{
var result = r.OrderByDescending(ii => ii.IncreasingNumberOfTheDay).FirstOrDefault();
int myint = Convert.ToInt32(result.IncreasingNumberOfTheDay);
result3 = myint + 1;
}
else
result3 = 1;
I suspect you just want:
DateTime today = DateTime.Today; // Just fetch the date part.
var query = context.vehicles.Where(v => v.InsertionDate == today);
Avoid string conversions if you possibly can.
If your InsertionDate includes times, then either you need to try to get the SQL query to truncate that to a date, or you could use:
DateTime today = DateTime.Today;
DateTime tomorrow = today.AddDays(1);
var query = context.vehicles.Where(v => v.InsertionDate >= today &&
v.InsertionDate < tomorrow);
I have some dates which are currently stored as a list of strings.
For example:
List<string> dates = new List<string>();
dates.Add("1/10/14");
dates.Add("2/9/14");
dates.Add("1/15/14");
dates.Add("2/3/14");
dates.Add("2/15/14");
(The date is in mm/dd/yy format)
I will take a user's input (also in mm/dd/yy format), but as a string.
Now, I want to find the date in the array that is the next closest after the user input date.
For example, if the user enters "1/13/14", the output should be "1/15/14".
If the user enters "2/5/14", then the next closest date is "2/9/14".
But if the user enter a date that is later than the last date (say "3/1/14", it will STILL return the last date in the array which is "2/15/14")
I know at some point you have to convert to type DateTime, but I couldn't figure out the logic to find such date.
List<string> dates = new List<string>();
dates.Add("1/10/14");
dates.Add("2/9/14");
dates.Add("1/15/14");
dates.Add("2/3/14");
dates.Add("2/15/14");
var allDates = dates.Select(DateTime.Parse).OrderBy(d=>d).ToList();
var inputDate = DateTime.Parse("1/13/14");
var closestDate = inputDate >= allDates.Last()
? allDates.Last()
: inputDate <= allDates.First()
? allDates.First()
: allDates.First(d => d >= inputDate);
For now I'm just parsing strings, but you should handle it separately. This is simple plain LINQ, you can go fancy and do binary search as well.
Here is a solution that uses a Binary Search.
You need to have a list of DateTimes, no question about it. No point in keeping them as strings, parse them on the way into the list if you have to. You can use LINQ to convert all the elements in the list, but that's the only way you'll be able to compare dates with eachother.
Check out the page for BinarySearch to understand why I am using the bitwise operator on the return value.
//build list of random dates
Random r = new Random();
var dates = new List<DateTime>();
for (int i = 0; i < 10; i++)
{
dates.Add(new DateTime(2014, r.Next(1,13), r.Next(1,28)));
}
//sort list (if you don't do this, you'll most likely get the wrong answer)
dates.Sort();
//get input
string input = "1/13/14";
DateTime inputDate = DateTime.Parse(input);
//find nearest
var result = dates.BinarySearch(inputDate);
DateTime nearest;
//get match or next in list.
if(result >= 0)
nearest = dates[result];
else if (~result == dates.Count )
nearest =dates.Last();
else
nearest = dates[~result];
If you need to find the true closest, use this in place of the last if block.
//get match, or true nearest date in list
if(result >= 0) //date was found! Use that index.
nearest = dates[result];
else if (~result == 0) //date not found, smaller than any item in the list. use first index.
nearest = dates.First();
else if(~result == dates.Count) //date was not found, and is greater than all items. Use last index.
nearest = dates.Last();
else //date not found, somewhere in the middle of the list. find the nearest date
{
var daysAfter = dates[~result].Subtract(inputDate); //date after input
var daysBefore = inputDate.Subtract(dates[~result - 1]); //date before input
if(daysAfter < daysBefore)
nearest = dates[~result];
else
nearest = dates[~result - 1];
}
DateTime searchDate = new DateTime(2014,03,01);
var orderedDates = dates
.Select(d => DateTime.ParseExact(d, "M/d/yy", CultureInfo.InvariantCulture))
.OrderBy(d => d).ToList();
var result = orderedDates.FirstOrDefault(d => d > searchDate);
if (result == default(DateTime))
result = orderedDates.Last();
Something like this?
List<string> dates = YourListOfStringsHere() ; // list of strings in MM/dd/yyyy form.
DateTime desiredDate = new DateTime(2014,2,27) ;
DateTime foundDate = dates
.Select( x => DateTime.ParseExact(x,"MM/dd/yyyy",CultureInfo.CurrentCulture))
.Where( x => x >= desiredDate.Date )
.Min()
;
Why you'd be storing date/time values as a string is beyond me. When you load them, why not convert them? That way, they're easier to manipulate, you know you've got clean data. Everything becomes much simpler.