string comparison on date format wont work? - c#

Hi for some reason I cant do a string comparison on a date? Take for example:
public List<HireDate> GetHireDate(string anything)
{
List<HireDate> hiredate = hiredates.Where(n =>
string.Equals(n.HireFromDate, anything, StringComparison.CurrentCultureIgnoreCase)
).ToList();
return hiredate;
}
It simply wont work? if I type into a textbox 13/07/2012 which is how its stored it returns a 404 not found???
The output looks like this from a generic list/get request:
<ArrayOfHireDate>
<HireDate>
<HireFromDate>13/07/2012</HireFromDate>
<HireToDate>28/07/2012</HireToDate>
<NumberOfDaysHired>15</NumberOfDaysHired>
</HireDate>
</ArrayOfHireDate>
Is there another way to find a string with a forward slash in it? For instance using / in any of web string comparers does not work it will always throw a 404 not found?

Two things:
1) To put a string in another string, the most common way to do this is using String.Format. That method takes a format string (such as "Date: {0} Time: {1}") and a bunch of arguments. Each occurrence of {0} in the string is replaced by the first argument, {1} by the second, etc.. There are additional options to format the arguments in the string, see for more information the MSDN page on String.Format.
2) If you have an URL and you get a 404 in your application, first verify that the syntax of the URL is correct. Manually try the URL you create in your program directly in your browser, and if it does not work, find out what syntax is actually used to provide the arguments. For example, it might be that a date must be formatted as 13-07-2012 instead of 13/07/2012 for it to work. If so, you can probably solve this by choosing the appropriate CultureInfo.
For any DateTime date object, to format it has a short date using any CultureInfo you want, use an overload of ToString and specify d as the format. For example, using the invariant culture:
var str = date.ToString("d", CultureInfo.InvariantCulture);
Other format strings can be found here.

Related

Get Date From Filename Using ParseExact

I am trying to find the file that has the highest date in a single directory. The problem is that the dates are attached to filenames. I am using the following code to try to pull the max date but am running into trouble with the ParseExact.
//Gather all of the files in the local directory
var files = Directory.EnumerateFiles(r.getLeadLocalFile());
returnDateTime = files.Max(f => DateTime.ParseExact(f, "MMddyyXXXX.csv", CultureInfo.InvariantCulture));
I continue to get the following error:
String was not recognized as a valid DateTime.
I can tell that the value of the file path is being passed in because the value of 'f' is below:
\\\\vamarnas02\\users\\meggleston\\User Files\\Leads\\110716ENH9.csv
The value of ENH9 can change depending on the file.
How can I get the DateTime from my filename?
Here's another approach. No need to split out anything. But one bad filename (as with your current approach) will ruin it:
//Gather all of the files in the local directory
var files = new DirectoryInfo(r.getLeadLocalFile()).GetFiles("*.csv");
returnDateTime = files.Max(f => DateTime.ParseExact(f.Name.Substring(0, 6), "MMddyy", CultureInfo.InvariantCulture));
You need to split out the date text before parsing. The following code snippet should help.
Assume the variable f is the filename.
DateTime.ParseExact(f.Substring( f.LastIndexOf("\\") + 1, 6), "MMddyy", CultureInfo.InvariantCulture);
Do you really need to use ParseExact here? Because it seems that you just need to get Int32 values and compare them afterwards.
So another approach: you can extract your date parts with some regex, from the path provided. For example you can use this one:
\\\d{6} // 2 slashes and 6 digits. I'm not an expert in regex, but seems that this one is enough for your task.
And trim the \\ part afterwards. So something like this in the loop:
private string ExtractDateFromFilename(string filename) {
var m = Regex.Match(filename, #"\\\d{6}");
if (!string.IsNullOrEmpty(m.Value))
return m.Value.Substring(1);
return "";
}
Try only passing the filename "110716ENH9.csv" instead of the full path of the file.
From MSDN DateTime.ParseExact Documentation:
Converts the specified string representation of a date and time to its DateTime equivalent using the specified format and culture-specific format information. The format of the string representation must match the specified format exactly.
From what you've provided, your format does not match exactly.
--
Only pass the first 6 characters of the filename to the ParseExact function and amend your format to be "MMddyy."

replace items in a string while also confirming format

I have a string input in the format of "string#int" and I want to convert it to "string-int" for web friendliness reasons for an api i am using.
To do this I could obviously just replace the single character # with a - using string.replace, but ideally I'd like to do a check that the input (which is user provided by the way) is in the correct format (string#int) while or before converting to the web friendly version with a "-" instead. Essentially I'm wondering if there is a method in C# that I could use to check that this input is in the correct format and convert it to the required result format.
There is no built-in way obviously, since the format you request is quite specific. Also, a string can contain anything, also a hastag, #, so I guess you need to narrow that down.
You could use regular expressions to check if the string is in the correct format. This would be possible expression:
[A-Za-z ]+#[0-9]+
Which matches for:
this is a string#123
There's nothing built in, but you could do the following:
var parts = input.Split(new char[] { '#' });
if (parts.Length != 2) incorrect format
int result;
if (!int.TryParse(parts[1], out result) incorrect format
output = String.Join("-", parts);
This takes the input and splits it on the "#" character. If the result isn't two parts then the string is invalid. You then check that the second part is an integer - if the TryParse fails it's not valid. The last step is to rejoin the two parts, but this time with a - as the separator.

Surprising int.ToString output

I have been working on a project, and found an interesting problem:
2.ToString("TE"+"000"); // output = TE000
2.ToString("TR"+"000"); // output = TR002
I also have tried with several strings other than "TE" but all have the same correct output.
Out of curiosity, I am wondering how come this could have happened?
Simply based on Microsoft's documentation, Custom Numeric Format Strings, your strings "TE000" and "TR000" are both custom format strings, but clearly they are parsed differently.
2.ToString("TE000") is just a bug in the formatter; it's going down a buggy path because of the unescaped "E". So it's unexpectedly assuming the whole thing is a literal.
2.ToString("TR000") is being interpreted as an implied "TR" literal plus 3 zero-filled digits for an integer value; therefore, you get "TR002".
If you truly want TE and TR verbatim, the expressions 2.ToString("\"TE\"000") and 2.ToString("\"TR\"000") will accomplish that for you by specifying TE and TR as explicit literals, instead of letting the formatter guess if they are valid format specifiers (and getting it wrong).
The ToString needs to PARSE the format string and understand what to do with it.
Let's take a look to the following examples:
2.ToString("TE000"); //output TE000
2.ToString("E000"); //output 2E+000
2.ToString("0TE000); //output 2TE000
2.ToString("T"); //throws exception
2.ToString("TT"); //output TT
This shows that if the ToString parser can understand at least part of the format, it will assume that the rest is just extra characters to print with it. If the format is invalid for the given number (like when you use a DateTime string format on a number), it will throw an exception. If it can not make sense of the format, it will return the format string itself as the result.
You cannot use a numeric format to achieve a custom format, instead use something like this:
int i = 2;
String.Format("TE{0:X3}", i);
See Custom Numeric Format Strings. The E means the exponent part of the scientific notation of the number. Since 2 is 2E000 in exponential notation, that might explain it.

Parse DateTime in c# from strange format

if i have a datetime string in a weird format, such as YYYY##MM##DD HH**M**SS, how can i create a new datetime object base on that? i have read something about the datetimeformatinfoclass but not sure how to get it working..
You can use DateTime.ParseExact, or DateTime.TryParseExact for data which you're not confident in. For example:
using System;
class Test
{
static void Main()
{
string formatString = "yyyy'##'MM'##'dd' 'HH'*'mm'*'ss";
string sampleData = "2010##02##10 07*22*15";
Console.WriteLine(DateTime.ParseExact(sampleData,
formatString,
null));
}
}
The quotes in the format string aren't strictly necessary - this will work too:
string formatString = "yyyy##MM##dd HH*mm*ss";
However, using the quotes means you're being explicit that the characters between the quotes are to be used literally, and not understood as pattern characters - so if you changed "#" to "/" the version using quotes would definitely use "/" whereas the version without would use a culture-specific value.
The null in the call to ParseExact means "use the current culture" - in this case it's unlikely to make much difference, but a commonly useful alternative is CultureInfo.InvariantCulture.
It's unfortunate that there's no way of getting the BCL to parse the format string and retain the information; my own Noda Time project rectifies this situation, and I'm hoping it'll make parsing and formatting a lot faster - but it's far from production-ready at the moment.
You can use DateTime.ParseExact method and pass the format you need.

DotNet DateTime.ToString strange results

Why does:
DateTime.Now.ToString("M")
not return the month number? Instead it returns the full month name with the day on it.
Apparently, this is because "M" is also a standard code for the MonthDayPattern. I don't want this...I want to get the month number using "M". Is there a way to turn this off?
According to MSDN, you can use either "%M", "M " or " M" (note: the last two will also include the space in the result) to force M being parsed as the number of month format.
What's happening here is a conflict between standard DateTime format strings and custom format specifiers. The value "M" is ambiguous in that it is both a standard and custom format specifier. The DateTime implementation will choose a standard formatter over a customer formatter in the case of a conflict, hence it is winning here.
The easiest way to remove the ambiguity is to prefix the M with the % char. This char is way of saying the following should be interpreted as a custom formatter
DateTime.Now.ToString("%M");
Why not use
DateTime.Now.Month?
You can also use System.DateTime.Now.Month.ToString(); to accomplish the same thing
You can put an empty string literal in the format to make it a composite format:
DateTime.Now.ToString("''M")
It's worth mentioning that the % prefix is required for any single-character format string when using the DateTime.ToString(string) method, even if that string does not represent one of the built-in format string patterns; I came across this issue when attempting to retrieve the current hour. For example, the code snippet:
DateTime.Now.ToString("h")
will throw a FormatException. Changing the above to:
DateTime.Now.ToString("%h")
gives the current date's hour.
I can only assume the method is looking at the format string's length and deciding whether it represents a built-in or custom format string.

Categories

Resources