Magic strings for converting DateTime to string Using C# - c#

I was greeted with a nasty bug today. The task is pretty trivial, all I needed to do is to convert the DateTime object to string in "yyyymmdd" format. The "yyyymmdd" part was stated in the development doc from the external software vendor. So, I conveniently copied the string from their file and pasted to my code. So I got the next
public string GetDateString(DateTime dateTime)
{
return dateTime.ToString("yyyymmdd");
}
Pretty simple. So simple that I didn't feel like to unit test the method. 20 minutes later, when other parts of my component are done. I started the app to check if things went right. Almost immediately I notice some supposed-to-be date field in my web page is displaying 20091511! This can't be right, there is no 15th month of a year. So, I rushed back to my code to check possible errors. It turns out the that I should have used "yyyyMMdd" instead of "yyyymmdd" when converting DateTime to string.
Admitted, this bug was due to my lack of attention to details. The difference between "mm" and "MM" are cleared stated in all C# references. I still would like to argue that it's pretty easy to overlook the differences if one doesn't work with this kind of tasks everyday.
My question is: Is there a clean(i.e. no magic string) way to do the coverings in one line of code? Thereturn dateTime.Year + "" + dateTime.Month + "" + dateTime.Day; code seems to be working but it's too much like hacking.
Update: Looks like the string format way is the best C# can offer. Maybe I am being brain washed, but I still think this kind of programming style belongs to low-level languages such as c.

String.Format("{0:0000}{1:00}{2:00}", dateTime.Year, dateTime.Month, dateTime.Day);
You could use this instead, I prefer the terse format though. Instead of 00 you can also use MM for specific month formatting (like in DateTime.ToString()).

See here: .NET Custom Date and Time Format Strings

return dateTime.Year.ToString() + dateTime.Month + dateTime.Day;
You don't need to keep adding empty strings, string+number returns string already and addition is interpreted from left to right.
Do note that that line doesn't return what you think it does, what you really want is:
return dateTime.Year.ToString("0000") + dateTime.Month.ToString("00")
+ dateTime.Day.ToString("00");

If that format string bugs you that much, at least make sure it is in one place. Encapsulate it e.g. in an extension method:
public string ToMyAppsPrefferedFormat(this DateTime date) {
return date.ToString("ddMMyyyy");
}
Then you can say date.ToMyAppsPrefferedFormat()

Related

c#: DateTime.Parse() -- Unrecognized datetime-string

So I got this datetime-string which I get from an external API, "2014-08-28T11:00:00:000-0400".
But I am unable to parse it into a normal DateTime object in C#, I know that last part of the string has something to do with timezone offsets or something, but I am at a loss as to what to do in order for it to parse.
What I've tried so far:
DateTime.Parse("2019-11-13T05:20:14:311-0700")
DateTime.Parse("2019-11-13T05:20:14:311-0700", new System.Globalization.CultureInfo("en-GB"))
DateTime.Parse("2019-11-13T05:20:14:311-0700", new System.Globalization.CultureInfo("en-US"))
DateTimeOffset.Parse("2019-11-13T05:20:14:311-0700")
A whole other bunch of stuff where I've passed in various format strings like "yyyy-MM-dd:HH:mm:ss" but that doesn't do any good either
Please, if someone out there can help me, you'll get a virtual cookie!
The format string you want to use is either
yyyy-MM-dd'T'HH:mm:ss:fffzzz
or
yyyy-MM-dd'T'HH:mm:ss:fffK
More information for zzz can be found here or for K here
You can use the above format string with either DateTime.ParseExact or DateTimeOffset.ParseExact depending on what you're trying to achieve.
Live example: https://rextester.com/DTNT63275

How to use string format to omit period but leave digits

I have the format string ######.00 used for formatting decimals in C#. I need to change it so that it omits the period but keeps the digits following the period. Can I accomplish this just by changing the format? I've searched, but haven't been able to find a solution online.
I found this answer to a very similar question, but it involves multiplying the decimal by 100 before formatting it. I'm not able to manipulate the number going in, nor the resulting string because I don't have access to them. This is because we're using a function from a third-party library that fetches the number from elsewhere and displays it formatted to the UI. I can only provide it with a format string. (If manipulating the number or resulting string is the only way to get it in the format we can probably do it, it would just take a good deal of refactoring, so I wanted to see if there's a simpler solution first. Hence the constraints.)
Just as an example of the output I'm looking for, consider the following code:
var myFormat = "{0:######.00}";
Console.WriteLine(string.Format(myFormat, 1234.1234));
Console.WriteLine(string.Format(myFormat, 5));
The code above currently outputs 1234.12 and 5.00, but I would like it to output 123412 and 500 just by changing myFormat. Is there a way to do this?
If only the format string is what you can change, there's probably no way to remove the dot.
However, you can implement your own Formatter, as MSDN's example.
string.Format(new CustomerFormatter(), "{0}", 1234.1234)

custom string format puzzler

We have a requirement to display bank routing/account data that is masked with asterisks, except for the last 4 numbers. It seemed simple enough until I found this in unit testing:
string.Format("{0:****1234}",61101234)
is properly displayed as: "****1234"
but
string.Format("{0:****0052}",16000052)
is incorrectly displayed (due to the zeros??): "****1600005252""
If you use the following in C# it works correctly, but I am unable to use this because DevExpress automatically wraps it with "{0: ... }" when you set the displayformat without the curly brackets:
string.Format("****0052",16000052)
Can anyone think of a way to get this format to work properly inside curly brackets (with the full 8 digit number passed in)?
UPDATE: The string.format above is only a way of testing the problem I am trying to solve. It is not the finished code. I have to pass to DevExpress a string format inside braces in order for the routing number to be formatted correctly.
It's a shame that you haven't included the code which is building the format string. It's very odd to have the format string depend on the data in the way that it looks like you have.
I would not try to do this in a format string; instead, I'd write a method to convert the credit card number into an "obscured" string form, quite possibly just using Substring and string concatenation. For example:
public static string ObscureFirstFourCharacters(string input)
{
// TODO: Argument validation
return "****" + input.Substring(4);
}
(It's not clear what the data type of your credit card number is. If it's a numeric type and you need to convert it to a string first, you need to be careful to end up with a fixed-size string, left-padded with zeroes.)
I think you are looking for something like this:
string.Format("{0:****0000}", 16000052);
But I have not seen that with the * inline like that. Without knowing better I probably would have done:
string.Format("{0}{1}", "****", str.Substring(str.Length-4, 4);
Or even dropping the format call if I knew the length.
These approaches are worthwhile to look through: Mask out part first 12 characters of string with *?
As you are alluding to in the comments, this should also work:
string.Format("{0:****####}", 16000052);
The difference is using the 0's will display a zero if no digit is present, # will not. Should be moot in your situation.
If for some reason you want to print the literal zeros, use this:
string.Format("{0:****\0\052}", 16000052);
But note that this is not doing anything with your input at all.

Parse String to Datetime

Is there a equivalent on .net of the string parsing of Datejs ( http://www.datejs.com/ ) ?
I wanna do things like
// Convert text into Date
Date.parse(‘today’);
Date.parse(‘t + 5 d’); // today + 5 days
Date.parse(‘next thursday’);
Date.parse(‘February 20th 1973′);
Date.parse(‘Thu, 1 July 2004 22:30:00′);
Tks!
The closest thing in the framwork is DateTime.Parse and DateTime.TryParse. Unfortunately, these will only handle your last 2 cases, but the first 3 will not work.
There is no built-in way to do date manipulations using the standard DateTime parsing methods. However, this answer to a different question provides a utility class which will handle some of your other cases (or something similar), using regular expressions.
As Reed mentions, there is nothing like this built into the .Net framework.
Microsoft JScript is a .Net language that can be used for server-side processing; you might look into seeing if you can integrate Datejs that way.

String syntax question

What I am trying to achieve is to merge three strings. Two are provided as strings; firstname and lastname, while the third is a simple comma/space separator. Given the following lines of code:
//Working code
var sep = ", ";
var fullName = myNewBO[0].LastName + sep + myNewBO[0].FirstName;
//Erronous code
var fullName = myNewBO[0].LastName + ", " + myNewBO[0].FirstName;
The string is returned to a cell in a DataGridView. While the first bit of code performs as expcted the latter does not. The string does not show in the cell as expected. Can someone tell me why the latter does not work? Also if you have a better solution to the problem please provide one.
EDIT: Solved. As suspected, and pointed out by several answers the problem was elsewhere in my code and the two alternatives do the exact same thing. Thanks for the syntax suggestions though :)
I prefer using string.Format("{0}, {1}",myNewBO[0].LastName,myNewBO[0].FirstName)
Now you can abstract out the format string if you want it be "First Last" for example you can use a different formatting string.
Edit
In response to your actual error, I like others here don't see what is wrong the line of code you have should work so the question becomes: "How are you binding this value to the grid?"
Are you doing this in an Eval() or code behind etc....
One suggestion would to add a ToString(string) method which takes a format string in, then you can bind to the evaluation of the method. And should your business requirements change you just change the formatting string.
string.Join(sep, new string[] {myNewBO[0].LastName, myNewBO[0].FirstName});
I suspect you have something else happening in your code, and you're mistaking where the error is occurring. I can't for the life of me see why those two would behave differently at all. I suggest you log the value after the assignment for both cases - I'm sure you'll find they're the same.
There is really no difference in your two calls, I see no error. What exception are you getting. Joel Coehoorn's answer with regards to String.Join is perfect for what you need.
What error is it throwing? That could tell you alot about why it is crashing.
Your calls both look valid on the surface to me. I would suggest that you make sure LastName and FirstName are strings and not null. To be sure, I guess you could append .ToString() to the end of FirstName and LastName.

Categories