How to compare two files based on datetime? - c#

I need to compare two files based on datetime. I need to check whether these two files were created or modified with same datetime. I have used this code to read the datetime of files...
string fileName = txtfile1.Text;
var ftime = File.GetLastWriteTime(fileName).ToString();
string fileName2 = txtfile2.Text;
var ftime2 = File.GetLastWriteTime(fileName2).ToString();
Any suggestions?

Don't call ToString() on the DateTime values returned by GetLastWriteTime(). Do this instead:
DateTime ftime = File.GetLastWriteTime(fileName);
DateTime ftime2 = File.GetLastWriteTime(fileName2);
Then you can just compare ftime and ftime2:
if (ftime == ftime2)
{
// Files were created or modified at the same time
}

Well, how about doing
ftime == ftime2
? No need for the ToString though, better just compare DateTimes as-is.

The precision of the last modification time being stored in a file system varies between different file systems (VFAT, FAT, NTFS). So, its best to use an epsillon environment for this and either let the user choose a sensible value or choose a value based on the involved file systems.
https://superuser.com/questions/937380/get-creation-time-of-file-in-milliseconds
double epsillon = 2.0
DateTime lastUpdateA = File.GetLastWriteTime(filename);
DateTime lastUpdateB = File.GetLastWriteTime(filename2);
if (Math.Abs(Math.Round((lastUpdateA - lastUpdateB).TotalSeconds)) > epsillon)
different = true;

GetLastWriteTime() returns a DateTime object, so you can do this:
if (File.GetLastWriteTime(filename).CompareTo(File.GetLastWriteTime(filename2)) == 0)
to test if they have the same timestamp.
See this for more tips on comparing DateTime objects.

bool isMatched=false;
int ia = string.Compare(ftime.ToString(), ftime2.ToString());
if (string.Compare(ftime.ToString(), ftime.ToString()) == 0)
isMatched = true;
else
isMatched = false;

Related

Is it good practice to compare string values of two comboboxes c#

I want to compare values of two comboboxes. The variables are of type var and they come like this: 27-12-2018
I want to compare these two values and for this purpose I have converted the value in date format and in string format.
This is meteorologycal charts.
var formattedDates = string.Join("_", Path.GetFileName(file).Split('_', '.').Skip(1).Take(3));
var formattedDates2 = string.Join("_", Path.GetFileName(file).Split('_', '.').Skip(1).Take(3));
if (!comboBox2.Items.Contains(formattedName))
{
comboBox2.Items.Add(formattedName);
}
if (!comboBox3.Items.Contains(formattedDates))
{
comboBox3.Items.Add(formattedDates);
}
if (!comboBox4.Items.Contains(formattedDates2))
{
comboBox4.Items.Add(formattedDates2);
}
listBox1.Items.Add(Path.GetFileName(file));
}
}
else
{
MessageBox.Show("Директорията Meteo не е октирта в системен диск 'C:\'");
Application.ExitThread();
}
var result = Directory
.EnumerateFiles(#"C:\Meteo", "*.dat")
.SelectMany(file => File.ReadLines(file))
.Select(line => line.Split(new char[] { '\t', ' ' }, StringSplitOptions.RemoveEmptyEntries))
.Select(items => new {
id = items[0],
date = DateTime.ParseExact(items[1], "dd-MM-yyyy", CultureInfo.InvariantCulture).ToString(),
date2 = items[1],
hours = items[2],
temperature = items[3],
presure = items[4],
windSpeed = items[5],
windDirect = items[6],
rain = items[7],
rainIntensity = items[8],
sunRadiation = items[12],
/* etc. */
})
.ToList();
var dates = result
.Select(item => item.date)
.ToArray();
I have the same values in two formats - String and Date, but I dont know how to compare two comboboxes (if firstCombo > secondCombo){ messagebox.show("")}
Convert your string to a DateTime type.
DateTime DT1 = DateTime.ParseExact("18/08/2015 06:30:15.006542", "dd/MM/yyyy HH:mm:ss.ffffff", CultureInfo.InvariantCulture);
Rearrange the format string to match whatever date format you are using.
Then you can just do:
if(DT1 > DT2)
Also FYI, VAR isnt a type, it just sets the type of the variable to whatever type is on the right side of the equals.
To compare values of two comboboxes, you first need to convert both values into a type that can be compared. In your case, you seem to want to compare dates.
Ex: 07-06-2019 > 06-06-2019 = True.
I would recommend you to get the current values from both comboboxes (combobox.Text) and create a DateTime object with them.
Then, you'll be able to compare them like you want.
DateTime date0 = Convert.ToDateTime(combobox0.Text);//"07-06-2019"
DateTime date1 = Convert.ToDateTime(combobox1.Text);//"06-06-2019"
int value = DateTime.Compare(date0, date1);
if (value > 0)
{
//date0 > date1
}
else
{
if (value < 0)
{
//date0 < date1
}
else
{
//date0 == date1
}
}
Finally, to answer your question, the best practice to compare combobox values is depending on what value you're trying to compare... If you want to compare dates like in your example, it is better to convert the values to DateTime. The only comparison you can make with strings, correct me if I'm wrong, is to check if the strings are equal or have the same value.
Another good practice is to use the TryParse method associated to the type of value you want to convert/compare. Most of, if not all, basic types in c# have this method associated to them.
https://learn.microsoft.com/en-us/dotnet/api/system.datetime.tryparse?view=netframework-4.8
DateTime date0;
//Take text from combobox0, convert it and put the result in date0
bool success = DateTime.TryParse(combobox0.Text, out date0);
if(success)
{
//Your date has been converted properly
//Do stuff
}

Use DateTime.ToFileTime and FromFileTime through file name string

I want to save to a specific space a single file at several states. So i thought about stamping it with the time of creation to tell one from another.
I have created a dummy program that goes through exactly the same procedure my full program does but concentrated.
Here is the code:
DateTime first = DateTime.Now;
long ft = first.ToFileTime();
string time = "" + ft;
long timeLong = Convert.ToInt64(time);
DateTime normalDate = DateTime.FromFileTime(timeLong);
string normalName = ""+ normalDate;
DateTime thisDate = DateTime.Parse(normalName);
long fit = thisDate.ToFileTime();
So it goes through those steps:
Create time and convert to long for file.
Save it as string inside the files name(i pass it like that but in "" is the files name)
Then i retrieve it, i cast it into long, to create a DateTime format readable for the human with FromFileTime.Then to string fro the user to read it in a comboBox.
Then the user selects and it becomes DateTime , to get into long through tge TiFileTime ( at this point i have the problem as it appears to loose everything smaller than seconds)
I want to cast it back into long at the end to be able to run through the files again and find the one that matches with the one that the user choose.
here is some output values:
Edit : As you can see form the results above. I miss something . The initial and the final values are not the same.So i cant find the same file again.
The Parse() method don't have all the information that the DateTime structure holds (you can find its members here).
string normalName = ""+ normalDate;
DateTime thisDate = DateTime.Parse(normalName);
Will not return the exact value (including Ticks) as the original one.
You should do it as follows, using Ticks:
string normalName = "" + normalDate.Ticks;
DateTime thisDate = new DateTime(long.Parse(normalName));
long fit = thisDate.ToFileTime();

.StartsWith and .Contains are returning null when comparing dates

In my application, I was trying to pull out the sum of values in a specific column for a specific period of time. For example if I want it to pull the sum for every month I did something like this
var thisDate = DateTime.Now;
var currentDay = thisDate.Day;
var thisMonth = DateTime.Now.ToString("MM");
var thisYear = thisDate.Year.ToString();
var thisYearthisMonth = string.Format("{0}-{1}", thisYear, thisMonth);
var SpecifiedTotal = (from t in db.Transaction
where t.AgentId == CurrentUser.SalesAgent.AgentId
&& t.Status.Status == "Approved"
&& t.DateApproved.ToString().StartsWith(thisYearthisMonth)
select (decimal?)t.AmountApproved).Sum() ?? 0;
Setting a breakpoint showed me that SpecifiedTotal was evaluating to zero. I tried to find out why by removing the line && t.DateApproved.ToString().Contains(thisYearthisMonth) and it evaluated to the right value. In essence i tried to pull out the sum of the values in a column for the period of March i.e 2015-03 so i thought comparing the stored date with that by finding any date that starts with 2015-03 would make sense. What could i have done wrong?
Without trying to work out exactly this fails, I would strongly recommend not using string representations for this sort of thing anyway. Just use DateTime comparisons instead - assuming that DateApproved is a DateTime column, of course. (If it's not, make it so!)
var thisDate = DateTime.Now;
var start = new DateTime(thisDate.Year, thisDate.Month, 1);
var end = start.AddMonths(1);
var specifiedTotal = (from t in db.Transaction
where t.AgentId == CurrentUser.SalesAgent.AgentId
&& t.Status.Status == "Approved"
&& t.DateApproved >= start && t.DateApproved < end
select (decimal?)t.AmountApproved).Sum() ?? 0;
In general, you should avoid using string operations unless you're actually interested in text. In this case, you're not - you're trying to perform a range comparison on dates. That has nothing to do with textual representations of them.
Because StartsWith is a stricter match than Contains? Have you tried checking to see what format your DateApproved is in?

Export to Excel using OpenXML and C#, Integers and DateTime

I'm writing an application that's supposed to export data from a map application.
This application is using Silverlight, and to facilitate export to Excel I am using this library.
All of the data is represented in strings by default. When I write to the spreadsheet, I try to parse each string to see which type it is:
string str = kvp.Value;
int i = 0;
long l = 0;
decimal dec = 0;
DateTime dt;
if (int.TryParse(str, out i))
doc.Workbook.Sheets[0].Sheet.Rows[r].Cells[c].SetValue(i);
else if (decimal.TryParse(str, out dec))
doc.Workbook.Sheets[0].Sheet.Rows[r].Cells[c].SetValue(dec);
else if (long.TryParse(str, out l))
doc.Workbook.Sheets[0].Sheet.Rows[r].Cells[c].SetValue(l);
else if (DateTime.TryParse(str, out dt))
doc.Workbook.Sheets[0].Sheet.Rows[r].Cells[c].SetValue(dt);
else
doc.Workbook.Sheets[0].Sheet.Rows[r].Cells[c].SetValue(str);
This works great, except for DateTime and when I try to parse a social security number, which in my case is 12 characters long.
The social security number is parsed as a decimal number, and is displayed in scientific form in Excel. From what I've gathered through reading it seems like a limitation in Excel. If I mark the cell however, I see the correct number in the top bar where you can write formulas. I've solved this problem so far by simply putting this number as a string and letting the end user handle it for now, but I'd really like for it to be a number in the finished document. Is this possible?
What really boggles my mind though, is the DateTime. The format of the date comes like this from the application: 10/15/2013 1:10:00 AM.
It looks like this in the Excel file: 2455075.
I checked the source code for the date formatting but I don't seem to be adept enough to see if there is anything wrong in it. For anyone intresed, you can check it out here.
The SetValue-function is supposed to identify the following types automatically:
bool
DateTime
decimal
Exception
SharedStringDefinition
string
I apologize for the long post. It boils down to these questions:
Can I make Excel handle long numbers without scientific notation programatically?
Why is the DateTime being outputed to such a weird format?
To be set Cell Value in Date format you have to convert DateTime to OLE Automation Date. Also you can create more clear method for writing cell values. Somthing like this:
public bool UpdateValue(WorkbookPart wbPart, string sheetName, string addressName, string value,
UInt32Value styleIndex, CellValues dataType)
{
// Assume failure.
bool updated = false;
Sheet sheet = wbPart.Workbook.Descendants<Sheet>().Where(
(s) => s.Name == sheetName).FirstOrDefault();
if (sheet != null)
{
Worksheet ws = ((WorksheetPart)(wbPart.GetPartById(sheet.Id))).Worksheet;
Cell cell = InsertCellInWorksheet(ws, addressName);
if (dataType == CellValues.SharedString)
{
// Either retrieve the index of an existing string,
// or insert the string into the shared string table
// and get the index of the new item.
int stringIndex = InsertSharedStringItem(wbPart, value);
cell.CellValue = new CellValue(stringIndex.ToString());
}
else
{
cell.CellValue = new CellValue(value);
}
cell.DataType = new EnumValue<CellValues>(dataType);
if (styleIndex > 0)
cell.StyleIndex = styleIndex;
// Save the worksheet.
ws.Save();
updated = true;
}
return updated;
}
Then call this method like this (first call is for String second is for DateTime):
UpdateValue(workbookPart, wsName, "D14", "Some text", 0, CellValues.String);
UpdateValue(workbookPart, wsName, "H13", DateTime.Parse("2013-11-01").ToOADate().ToString(CultureInfo.InvariantCulture), 0, CellValues.Date);

C# times matching

I have written a small function in C# which isn't my main launguage so is coming across a little foreign to me.
public bool CheckForKey(string key)
{
string strKeyTime = Decode(key);
//valid key will be current time +- 5 minutes
string strTheTime = DateTime.Now.ToString("HH:mm:ss tt");
if (strKeyTime == strTheTime)
{
return true;
}
else
{
return false;
}
}
I need to alter this to allow for 5 minutes, so
if (strKeyTime == strTheTime)
needs to be
if (strKeyTime == strTheTime + or - 5 minutes)
my problem is matching the times as they are strings, perhaps convert key(original time) back to a date first and then do it, but I am pretty new to c#
If you convert (or keep) them both to DateTimes you can use TimeSpan:
TimeSpan delta = dateTime1 - dateTime2;
if (Math.Abs(delta.TotalMinutes) <= 5) { ... }
Look into using the DateTime.ParseExact (or any of the Parse... methods) to parse your strKeyTime, and then do something similar to the above.
To convert your sent string to the equivalent DateTime value, use the following code:
var keyDateTime = Convert.ToDateTime(strKeyTime);
var strTheTime = DateTime.Now
from here, you can use this value to compare with your original time value as the following:
if (keyDateTime == strTheTime || (keyDateTime > strTheTime && keyDateTime < strTheTime.AddMinutes(5))
{
return true;
}
the previous block of code will first check if we got an exact match, or the time sent to the method is between the original time and a time shift of additional 5 minutes.
that's it, if this is not what you need, let me know so I may update my answer for you, thanks.
-- if my answer is correct, don't forget to "Mark as answer".
"perhaps convert key(original time) back to a date first and then do it" sounds like a sound solution. I'd do it this way:
Convert both strings to DateTime instances.
Store difference in TimeSpan instance using DateTime.Subtract(DateTime value) ( http://msdn.microsoft.com/en-us/library/8ysw4sby.aspx )
Check if TimeSpanInstance.TotalMinutes is less than or equal to 5.
The first step is something I can't really give you any advice on without information concerning how your string is formatted. However, once this is done, the rest should be easy.

Categories