how to compare two dates in datetimepicker - c#

I am doing Windows project, in which I have two DateTimePicker controls, one for StartDate and other for EndDate.
In runtime, when user selects the StartDate and EndDate from that controls, it should read the textfile(i.e) log.txt & search line by line get the matching of both these dates and as well as in between dates and write the data to a textbox or label control
for eg in log file, data is like below:
3/12/2013 2:51:47 PM - ASDASDASD.D20131203145019
4/12/2013 2:52:23 PM - ASDDFSDSA.C20131203145019
5/12/2013 2:52:37 PM - SDASAFAS_20131203182101.D
6/12/2013 3:17:11 PM - RRRTWEWA_20131203184602.D00
7/12/2013 3:35:32 PM - XBCNXCXCXC.D0120131203153408
if I search from 5 dec 2013 to 7 dec 2013, it should retrieve:
5/12/2013 2:52:37 PM - SDASAFAS_20131203182101.D
6/12/2013 3:17:11 PM - RRRTWEWA_20131203184602.D00
7/12/2013 3:35:32 PM - XBCNXCXCXC.D0120131203153408
but up to now I am getting:
5/12/2013 2:52:37 PM - SDASAFAS_20131203182101.D
7/12/2013 3:35:32 PM - XBCNXCXCXC.D0120131203153408
I am retriving only the StartDate & EndDate matching data not in between date data.
The below are some of the coding I have tried:
try
{
// ...
string FDDate = FD.Date.ToString("M/d/yyyy");
string TDDate = TD.Date.ToString("M/d/yyyy");
string searchstring = EnterFileNameTextbox.Text.ToString();
string searchfromdate = FromDateTimePicker.Value.ToShortDateString();
string searchtodate = ToDateTimePicker.Value.ToShortDateString();
string line;
StringBuilder sb = new StringBuilder();
int counter = 0;
using (StreamReader file = new StreamReader(#"D:\log.txt"))
{
while ((line = file.ReadLine()) != null)
{
if (line.Contains(searchstring) && line.Contains(FDDate))
{
sb.AppendLine(line.ToString());
counter++;
}
else if (line.Contains(searchstring) && !line.Contains(FDDate))
{
if (FD.Date < TD.Date)
{
sb.AppendLine(line.ToString());
counter++;
FDDate = FD.Date.AddDays(1).ToShortDateString();
}
else if (FD.Date == TD.Date)
{
FDDate = FD.Date.ToShortDateString();
sb.AppendLine(line.ToString());
counter++;
}
}
}
}
ResultTextBox.Text = sb.ToString();
CountLabel.Text = counter.ToString();
}
catch (Exception ex)
{
MessageBox.Show("The file could not be read");
MessageBox.Show(ex.Message);
}
I am not getting idea to do the loop.

I would recommend using DateTime.TryParse (doc here) instead of just converting. That will allow you to provide valid formatting, handle failures (convert will throw if it fails).
The part about using the Date property seems fine, and comparison operators will work as expected.

Try and deal with DateTime datatypes here rather than converting everything to string. After reading the line from the file, parse out the date. Assuming it is always going to be the first element in the file, and is followed by a space, you could do this by using DateTime lineDate = DateTime.Parse(line.Split(" ")[0]);
Once you have the date from the file in that format, and you have DateTime fromDate and DateTime toDate obtained from your date pickers, you can write if(lineDate >= fromDate && lineDate <= toDate) sb.AppendLine(line);

Related

Delete files which are older than today's date

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.

Check if month is in interval in c# (asp.net)

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

Trouble with DateTime.ParseExact

I am working on a reminder application. The applications stores the reminder Date, Time and DateLastShown (in different fields) in the database and pulls them out to performs checks.
All dates are in "d/MM/yyyy" format. My problem is that when i pull the dates from the DB and try to store back into DateTime format they are still being shown in "M/d/yyyy" format which is not how the app needs to be.
I essentially need to pull the values from the DB do some checks to determine if it's time to show the reminder and do so. It seems rather straight forward, maybe i am making some small error.
Below is my code with comments.
Any help really appreciated.
public void CheckReminders()
{
IQueryable<Reminder> reminders;
DateTime reminderDate;
DateTime reminderTime;
DateTime reminderLastShown;
DateTime todayDate;
DateTime timeNow;
while (true)
{
try
{
db = new StudioManagementEntities();
reminders = from r in db.Reminders
select r;
foreach (Reminder r in reminders)
{
if (r.Enabled == 1)
{
if (r.Recurring == 1)
{
// This is the code i was using before when the date was in "M/d/yyyy" format
// which seems to be default.
reminderTime = DateTime.Parse(r.Time);
timeNow = DateTime.Parse(DateTime.Now.ToLongTimeString());
if (r.DateLastShown != DateTime.Today.ToShortDateString() && timeNow >= reminderTime)
{
FrmReminder frmReminder = new FrmReminder(r.Id, true);
frmReminder.ShowDialog();
r.DateLastShown = DateTime.Today.ToShortDateString();
}
}
else
{
// Now i need to pass in "d/M/yyyy" format but the
// code seems to return in "M/d/yyyy" format.
reminderDate = DateTime.ParseExact(r.Date, "d/MM/yyyy", null);
// Even this returns in wrong format
reminderDate = DateTime.ParseExact("24/01/2013", "d/MM/yyyy", null);
// Have tried with CultureInfo.InvariantCulture too.
MessageBox.Show(reminderDate.ToString());
return;
if (
r.DateLastShown != DateTime.Today.Date.ToShortDateString() //&&
//r.Date == DateTime.ParseExact(DateTime.Today, "d/MM/yyyy", CultureInfo.InvariantCulture).ToString() //&&
//now.TimeOfDay.TotalSeconds >= reminderTime.TimeOfDay.TotalSeconds
)
{
FrmReminder frmReminder = new FrmReminder(r.Id, true);
frmReminder.ShowDialog();
r.DateLastShown = DateTime.Today.ToShortDateString();
}
}
}
}
db.SaveChanges();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
// Check every minute
Thread.Sleep(60000);
}
}
And the DB table.
If the parsing into the date object is not erroring out, you are just having a problem with your output when you call .ToString().
From the docs:
The ToString method returns the string representation of the date and
time in the calendar used by the current culture.
If you need something other than the user's current culture settings, you can specify that using a format string in the overloaded ToString() method:
var reminderDate = DateTime.ParseExact("24/01/2013", "d/MM/yyyy", null);
MessageBox.Show(reminderDate.ToString("d/MM/yyyy"));
Also, as others have stated in comments, if possible you should be using the date data type in your database instead of storing the values as strings.

check if date time string contains time

I have run into an issue. I'm obtaining a date time string from the database and and some of these date time strings does not contain time. But as for the new requirement every date time string should contain the time like so,
1)1980/10/11 12:00:01
2)2010/APRIL/02 17:10:00
3)10/02/10 03:30:34
Date can be in any format followed by the time in 24hr notation.
I tried to detect the existence of time via the following code,
string timestamp_string = "2013/04/08 17:30";
DateTime timestamp = Convert.ToDateTime(timestamp_string);
string time ="";
if (timestamp_string.Length > 10)
{
time = timestamp.ToString("hh:mm");
}
else {
time = "Time not registered";
}
MessageBox.Show(time);
But this only works for the No 1) type timestamps. May I please know how to achieve this task on how to detect if the time element exist in this date time string. Thank you very much :)
POSSIBLE MATCH
How to validate if a "date and time" string only has a time?
INFO the three answers provided by Arun Selva Kumar,Guru Kara,Patipol Paripoonnanonda are all correct and checks for the time and serves my purpose. But I select Guru Karas answer solely on ease of use and for the explanation he has given. Thank you very much :) very much appreciated all of you :)
The date time components TimeOfDay is what you need.
MSDN says "Unlike the Date property, which returns a DateTime value that represents a date without its time component, the TimeOfDay property returns a TimeSpan value that represents a DateTime value's time component."
Here is an example with consideration of all your scenarios.
Since you are sure of the format you can use DateTime.Parse else please use DateTime.TryParse
var dateTime1 = System.DateTime.Parse("1980/10/11 12:00:00");
var dateTime2 = System.DateTime.Parse("2010/APRIL/02 17:10:00");
var dateTime3 = System.DateTime.Parse("10/02/10 03:30:34");
var dateTime4 = System.DateTime.Parse("02/20/10");
if (dateTime1.TimeOfDay.TotalSeconds == 0) {
Console.WriteLine("1980/10/11 12:00:00 - does not have Time");
} else {
Console.WriteLine("1980/10/11 12:00:00 - has Time");
}
if (dateTime2.TimeOfDay.TotalSeconds == 0) {
Console.WriteLine("2010/APRIL/02 17:10:00 - does not have Time");
} else {
Console.WriteLine("2010/APRIL/02 17:10:00 - Has Time");
}
if (dateTime3.TimeOfDay.TotalSeconds == 0) {
Console.WriteLine("10/02/10 03:30:34 - does not have Time");
} else {
Console.WriteLine("10/02/10 03:30:34 - Has Time");
}
if (dateTime4.TimeOfDay.TotalSeconds == 0) {
Console.WriteLine("02/20/10 - does not have Time");
} else {
Console.WriteLine("02/20/10 - Has Time");
}
Try this,
DateTime myDate;
if (DateTime.TryParseExact(inputString, "dd-MM-yyyy hh:mm:ss",
CultureInfo.InvariantCulture, DateTimeStyles.None, out myDate))
{
//String has Date and Time
}
else
{
//String has only Date Portion
}
You can try using other format specifiers as listed here, http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx
Combining the answers of Guru Kara and Patipol Paripoonnanonda with the .net globalisation API results in:
bool HasExplicitTime(DateTime parsedTimestamp, string str_timestamp)
{
string[] dateTimeSeparators = { "T", " ", "#" };
string[] timeSeparators = {
CultureInfo.CurrentUICulture.DateTimeFormat.TimeSeparator,
CultureInfo.CurrentCulture.DateTimeFormat.TimeSeparator,
":"};
if (parsedTimestamp.TimeOfDay.TotalSeconds != 0)
return true;
string[] dateOrTimeParts = str_timestamp.Split(
dateTimeSeparators,
StringSplitOptions.RemoveEmptyEntries);
bool hasTimePart = dateOrTimeParts.Any(part =>
part.Split(
timeSeparators,
StringSplitOptions.RemoveEmptyEntries).Length > 1);
return hasTimePart;
}
This approach:
detects explicit midnight times (e.g. "2015-02-26T00:00");
only searches the string when TimeOfDay indicates midnight or no explicit time; and
finds explicit midnight times in local format and any non midnight time in any format that .net can parse.
Limitations:
explicit midnight times in non culture local format are not detected;
explicit midnight times with less than two parts are not detected; and
less simple and elegant than the approaches of Guru Kara and Patipol Paripoonnanonda.
Here's what I'm going with for now. It may not be perfect, but likely better than considering any 12am datetime as not having a time. The premise is that if I tack a full time specification on the end it will parse if it's just a date but fail if it already has a time component.
I had to make the assumption that there's not some valid, date/time that has 7 non-white-space characters or less. It appears that "1980/10" parses, but not "1980/10 01:01:01.001".
I've included various test cases. Feel free to add your own and let me know if they fail.
public static bool IsValidDateTime(this string dateString, bool requireTime = false)
{
DateTime outDate;
if(!DateTime.TryParse(dateString, out outDate)) return false;
if (!requireTime) return true;
else
{
return Regex.Replace(dateString, #"\s", "").Length > 7
&& !DateTime.TryParse(dateString + " 01:01:01.001", out outDate);
}
}
public void DateTest()
{
var withTimes = new[]{
"1980/10/11 01:01:01.001",
"02/01/1980 01:01:01.001",
"1980-01-01 01:01:01.001",
"1980/10/11 00:00",
"1980/10/11 1pm",
"1980-01-01 00:00:00"};
//Make sure our ones with time pass both tests
foreach(var date in withTimes){
Assert.IsTrue(date.IsValidDateTime(), String.Format("date: {0} isn't valid.", date));
Assert.IsTrue(date.IsValidDateTime(true), String.Format("date: {0} does have time.", date));
}
var withoutTimes = new[]{
"1980/10/11",
"1980/10",
"1980/10 ",
"10/1980",
"1980 01",
"1980/10/11 ",
"02/01/1980",
"1980-01-01"};
//Make sure our ones without time pass the first and fail the second
foreach (var date in withoutTimes)
{
Assert.IsTrue(date.IsValidDateTime(), String.Format("date: {0} isn't valid.", date));
Assert.IsFalse(date.IsValidDateTime(true), String.Format("date: {0} doesn't have time.", date) );
}
var bogusTimes = new[]{
"1980",
"1980 01:01",
"80 01:01",
"1980T01",
"80T01:01",
"1980-01-01T01",
};
//Make sure our ones without time pass the first and fail the second
foreach (var date in bogusTimes)
{
DateTime parsedDate;
DateTime.TryParse(date, out parsedDate);
Assert.IsFalse(date.IsValidDateTime(), String.Format("date: {0} is valid. {1}", date, parsedDate));
Assert.IsFalse(date.IsValidDateTime(true), String.Format("date: {0} is valid. {1}", date, parsedDate));
}
}
Would this work for your use case:
bool noTime = _datetimevalue.TimeOfDay.Ticks == 0;
If no time component exists in the DateTime instance, Ticks will be 0.
Date and time are always separated by a space bar. The easiest way would be:
if (timestamp_string.Split(' ').Length == 2)
{
// timestamp_string has both date and time
}
else
{
// timestamp_string only has the date
}
This code assumes the date always exists.
If you want take it further (in case the date does not exist), you can do:
if (timestamp_string.Split(' ')
.Select(item => item.Split(':').Length > 1)
.Any(item => item))
{
// this would work for any string format that contains date, for example:
// 2012/APRIL/03 12:00:05 -> this would work
// 2013/04/05 09:00:01 -> this would work
// 08:50:45 2013/01/01 -> this would also work
// 08:50:50 -> this would also work
}
else
{
// no date in the timestamp_string at all
}
Hope this helps!

Prevent user from entering a from date greater than to date c#

I am searching data based on two dates a from field and a To field in Asp.net
I want to prevent the user from entering a From date greater than a To date and display a message to the user Please select a valid date range
DateTime InvoiceDateFrom = new DateTime();
DateTime InvoiceDateTo = new DateTime();
if (TxtInvoiceDateFrom.Text.Trim() != "")
{
//DateTime FromDate = DateTime.ParseExact(TxtInvoiceDateFrom.Text.Trim(), "dd/MM/yyyy", null).AddDays(1);
InvoiceDateFrom = Convert.ToDateTime(TxtInvoiceDateFrom.Text);
//DateTime toDate = DateTime.ParseExact(TxtInvoiceDateTo.Text.Trim(), "dd/MM/yyyy", null).AddDays(1);
}
if (TxtInvoiceDateTo.Text.Trim() != "")
{
InvoiceDateTo = Convert.ToDateTime(TxtInvoiceDateTo.Text);
}
if (InvoiceDateTo < InvoiceDateFrom)
MessageBox.Show("Please select a valid date range.");
DateTime x = DateTime.Parse("12/8/2012"); //as "12/8/2012" is the your specified date
dateTimePicker1.MaxDate = x; // or you can use it in one line
if you want to prevent the user to choose date greater than today:
dateTimePicker1.MaxDate = DateTime.Today;
Please see if this is of help! C# way of doing is fine. But i would rather suggest javascript.
DateTime toDate=DateTime.ParseExact(todateString,"dd/MM/yy",System.Globalization.InvariantCulture);
DateTime fromDate=DateTime.ParseExact(fromdateString,"dd/MM/yy",System.Globalization.InvariantCulture);
int comparison=DateTime.Compare(toDate,fromDate);
if(comparison>=0)
{
//Post custom error message.
}

Categories