Removing data from returned information. - c#

I am making an SQL Query that brings back a list of files and their paths. They have different file paths and different file names ofc.
The file names are dates and time in the following format:
YearMonthDayHourMinuteSeconds
What I need to do is take the filepath that has the latest date and time, strip off everything except the date and time part and then using the date and time re-query the database.
I have very few ideas on how to do this.
EDIT: The date will be changing and I need to take the latest when ever the program is run.

My first idea would be to treat everything the query returns as strings
When you get your result set, you could iterate through it storing the record you want in a string or multiple strings. You can compare strings with firststring.Compare(secondstring) it returns 1 or greater if the secondstring is alfabeticaly after firststring.
Then use substring to extract the part of the string you want
string inf = latestdate.Substring(startindex, length);
Hope this helps

use the standard .NET file operation libraries
something like:
using System.IO;
...
string myFileNameWithFullPath;
...
DateTime newDate = DateTime.Parse(Path.GetFileName(myFileNameWithFullPath));

string tmps = Path.GetFileNameWithoutExtension(filenameFromSQL);
DateTime myDateTime = DateTime.Parse(String.Format("{1}/{2}/{0}",
tmps.Substring(0,4), tmps.Substring(5,2), tmps.Substring(7,2));

Related

How to get the latest file postfix name c#

I have two files in my directory, I have created an array and each of them have an unique postfix. In this array, there are two files. I want to the program to select the latest file 20160906. If there are 3rd file (20170906) then I want to program to select this filename. Help would be appreciated.
myArray:
[0] = myFile20150906
[1] = myFile20160906
[2] = myFile20170906
expected Result:
string latestFile = 'myFile20170906'
As long as your strings are all in the format myFileYYYYMMDD then comparing them as strings will be the same as comparing them in date order.
Because of this, you can use Enumerable.Max() to find the latest date, like so:
string latest = myArray.Max();
Note that Enumerable.Max() works with any type that implements IComparable or IComparable<T>, which includes string.

Delete character out of string

I am having some problems with a quite easy task - i feel like im missing something very obvious here.
I have a .csv file which is semicolon seperated. In this file are several numbers that contain dots like "1.300" but there are also dates included like "2015.12.01". The task is to find and delete all dots but only those that are in numbers and not in dates. The dates and numbers are completely variable and never at the same position in the file.
My question now: What is the 'best' way to handle this problem?
From a programmers point of view: Is it a good solution to just split at every semilicon, count the dots and if there is only one dot, delete it? This is the only way to solve the problem i could think of by now.
Example source file:
2015.12.01;
13.100;
500;
1.200;
100;
Example result:
2015.12.01;
13100;
500;
1200;
100;
If you can rely on the fact that dates have two dots and numbers just one, you can use that as a filter:
string s = "123.45";
if (s.Count(x => x == '.') == 1)
{
s = s.Replace(".", null);
}
The source file looks like a valid file generated by a program running on a machine whose locale uses . as the thousand separator (most of Europe does) and date separator (German locales only I think). Such locales also use ; as the list separator.
If the question was only how to parse such dates, numbers, the answer would be to pass the proper culture to the parse function, eg: decimal.Parse("13.500",new CultureInfo("de-at")) would return 13500. The actual issue though is that the data must be fed to another program that uses . as the decimal separator.
The safest option would be to change the locale used by the exporting program, eg change the thread CultureInfo if the exporter is a .NET program, the locale in an SSIS package etc, to a locale like en-gb to export with . and avoid the weird date format. This assumes that the next program in the pipeline doesn't use German for the date, English for numbers
Another option would be to load the text, parse the fields using the proper locale then export them in the format required by the next program.
Finally, a regular expression could be used to match only the numeric fields and remove the dot. This can be a bit tricky and depends on the actual contents.
For example (\d+)\.(\d{3}) can be used to match numbers if there is only one thousand separator. This can fail if some text field contains similar values. Or ;(\d+)\.(\d{3}); could match only a full field, except the first and last fields, eg:
Regex.Replace("1.457;2016.12.30;13.000;1,50;2015.12.04;13.456",#";(\d+)\.(\d{3});",#"$1$2;")
produces :
1.457;2016.12.3013000;1,50;2015.12.04;13.456
A regular expression that would match either numbers between ; or the first/last field could be
(^|;)(\d+)\.(\d{3})(;|$)
This would produce 1457;2016.12.30;13000;1,50;2015.12.04;13456, eg:
var data="1.457;2016.12.30;13.000;1,50;2015.12.04;13.456";
var pattern=#"(^|;)(\d+)\.(\d{3})(;|$)";
var replacement=#"$1$2$3$4";
var result= Regex.Replace(data,pattern,replacement);
The advantage of a regex over splitting and replacing strings is that it's a lot faster and more memory efficient. Instead of generating temporary strings for each split, manipulation, a Regex only calculates indexes in the source. A string object is generated only when you request the final text result. This results in far fewer allocations and garbage collections.
Even in medium-sized files this can result in 10x better performance
I wouldn't rely on the number of dots as mistakes can be made.
You can use the double.TryParse to safely test if the string is a number
var data = "2015.12.01;13.100;500;1.200;100;";
var dataArray = data.Split(';');
foreach (var s in dataArray)
{
double result;
if(double.TryParse(s,out result))
// implement your logic here
Console.WriteLine(s.Replace(".",string.Empty));
}

Varying filepaths in C#

I am creating C# Windows Form that retrieves files from shared drives as email attachments. I am trying to automate the file retrieval process, but the filepaths available to me vary according to the date. For example:
V:\....\Dec-03\filename12-3-2013.xml
J:\.....\December\filename12-4-2013
I have the filepath stored as string from a textbox, but since the path varies slightly day-to-day, I've been trying to figure out how automate this process. In the past I've used VBA code where I've concatenated method calls into the string like this
"..." & Day(Date) & "..."
(I replaced the ampersand with the plus sign of course for C#)
But this just gets me an illegal characters in path Argument exception.
I am using a check for filedate and taking a a specific filepath through a textbox. I want particular files that are being updated in monthly folders and the filename contains a date. I want to grab the ones with today's date or yesterday's date, but some have no date in the filename or directory at all. Since there isn't a lot of consistency, I would love to enter code
"+ DateTime.Now.ToString() +"
in the textbox per individual filepath as I load them via the form and have the program execute like I've done with some VBA code, but I get Illegal characters with the double quotes in the middle of a filepath. Is there some work around or will I need to create fixes for every particular pattern?
Use System.IO.Path.Combine(...) to handle chaining directories together (it takes care of extra slashes for you). In your combine, use String.Format(SomeFormatString, token1value, toke2value, etc.) to give you the name you were wanting.
C# uses + to append strings instead of & in older VB.
"My Date: " + DateTime.Now.ToString("MM/dd/yyyy")
An example of this with the String.Format I showed above would be
string.Format("My Date: {0}", DateTime.Now.ToString("MM/dd/yyyy"))
If I'm following what you're saying about Day(Date), you might try some thing like this in C#:
MyObject.SomeMethod("some string " + dateValue.ToString("ddd") + " more string data");
Where dateValue is a DateTime object and the "ddd" parameter tells the ToString method to return a three character abbreviation of the day of the week (e.g. 'Wed').
For more information on using ToString with DateTime objects to extract various parts of the date, see
http://msdn.microsoft.com/en-us/library/bb762911(v=vs.100).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-2
The ToString overload of the DateTime structure will allow you to format a date as the Month name, etc.
var x = DateTime.Today.ToString("MMMM"); // December
You can include other characters in the format string as well, for example to get Dec-19 you can use:
var x = DateTime.Today.ToString("MMM-dd"); // Dec-19
TyCobb's answer covers combining the formatted date into a path using Path.Combine (which I generally recommend).
You can also use String.Format to insert a formatted value into a string, which is often easier to read and leads to fewer mistakes. For example, to generate your first example, you could use the following:
var path =
String.Format("V:....\{0:MMM-dd}\filename{0:M-d-yyyy}.xml", DateTime.Today);

what is the best way to parse out string from longer string?

i have a string that looks like this:
"/dir/location/test-load-ABCD.p"
and i need to parse out "ABCD" (where ABCD will be a different value every day)
The only things that i know that will always be consistent (to use for the logic for parsing) are:
There will always be be a ".p" after the value
There will always be a "test-load-" before the value.
The things i thought of was somehow grab everything past the last "/" and then remove the last 2 characters (to take case of the ".p" and then to do a
.Replace("test-load-", "")
but it felt kind of hacky so i wanted to see if people had any suggestions on a more elegant solution.
You can use a regex:
static readonly Regex parser = new Regex(#"/test-load-(.+)\.p");
string part = parser.Match(str).Groups[1].Value;
For added resilience, replace .+ with a character class containing only the characters that can appear in that part.
Bonus:
You probably next want
DateTime date = DateTime.ParseExact(part, "yyyy-MM-dd", CultureInfo.InvariantCulture);
Since this is a file name, use the file name parsing facility offered by the framework:
var fileName = System.IO.Path.GetFileNameWithoutExtension("/dir/location/test-load-ABCD.p");
string result = fileName.Replace("test-load-", "");
A “less hacky” solution than using Replace would be the use of regular expressions to capture the solution but I think this would be overkill in this case.
string input = "/dir/location/test-load-ABCD.p";
Regex.Match(input, #"test-load-([a-zA-Z]+)\.p$").Groups[1].Value

Saving formatted timestring as file name problem in c#

HI guys,
I only started c# recently so I'm not 100% familiar with it's syntax yet and I got into a problem. I'd like to write the current time into a filename. I'm using the following code:
DateTime now = DateTime.now;
string dateString = string.Format(#"Z:\test\{0}.bmp",now.ToString("s"));
bitmap.Save(dateString);
Now this gives me a can't access filepath error. Apparently it has something to do with the ":" characters at the time part (at least when I give a now.ToString("d") ) it saves fine.
Any idea whats causing this? Thanks.
The "s" format will create a filename of something like:
2009-06-15T13:45:30.bmp
That's just not a valid filename, due to the colon. Either replace the colon with another character after calling ToString, or use a different format.
Note that "d" won't always work either, as it can include "/" in the name, depending on the culture.
Personally I'd suggest something like "yyyyMMdd-HHmmss" which will give you something like
20090615-134530.bmp
Regardless of the code, the Windows filesystems won't allow the use of a colon (or several other "special" characters) in a filename. So the issue is happening at the OS level, not in your code.
You'll want to strip out those characters and/or format the timestamp differently to use it as a filename.
Some characters are not valid in filenames on Windows - See this link. This is not related to c#.
That is caused by the Windows file system, which disallows :'s in file names.
':' are invalid characters for naming a file. You'll need to determine some other valid character to substitute for ':' before attempting to save the file.
public static class SPStringUtils
{
public static string MakeFilename(this DateTime dt)
{
return dt.ToString("yyyyMMdd-HHmmss");
}
public static string MakeFilename(this DateTime dt, string format)
{
return string.Format(format, MakeFilename(Now));
}
}
...
Console.WriteLine(Now.MakeFilename(#"c:\logs\log{0}.log");
There can't be no ':' in a file name, that's why.

Categories