convert String to different datetime formats - c#

My input is an annoying free text in which I need to extract the date. This date could be present in any of the formats with anomalies.
eg. This is 9.9.12 date
This is 9912 date
This is 0992012 date
Any possible format.
dMy
ddMMyy
ddMMyyyy
Mdyy etc..
I am able to validate if the text is in date format for ddMMy* but not any other. I was looking into this https://www.c-sharpcorner.com/blogs/date-and-time-format-in-c-sharp-programming1 link to see what other formats could be possible but I got no leads.
Is this correct to write like in the following method for a date format say - 9912?
Date.ParseExact(test.ToString,"dMy", Globalization.CultureInfo.InvariantCulture)
If yes, the system is populating me the following err:
System.FormatException: String was not recognized as a valid DateTime.
Can anyone please share a reliable approach to tackle such problems?

There is no single way to accomplish what you're trying to do. Specifically, because the intent is so broad, it becomes hard to infer what the user actually means (e.g. how do you differentiate month vs. day).
Depending on how you're implementing your application, you need to implement input validation.
For a console app, I can envision you using something like:
if (DateTime.TryParse(line, out value))
{
// Parse-able date.
}
else
{
// Non-parseable date.
}
If you're building a WPF application, you can use binding validation. If you're building an ASP.NET MVC application, you can also implement model validation. Your mileage may vary - you should definitely consider constraining what your users can feed the application.

Related

FormatException of DateTime.Parse. Check which part is wrong in my date string

I'd like to validate a date string in my TextBox.
If I have 2018-06-07 string in my TextBox, I can parse it with success with DateTime.TryParse or DateTime.Parse.
But if I have 2018-12-35 in my TextBox, the DateTime.Prase throws FormatException that is absolutely right.
How can I determine which part of DateTime is wrong. For Example how to determine if Day or Month is wrong.
DateTime.Parse tries a number of formats - some to do with the current culture, and some more invariant ones. It looks like it's including an attempt to parse with the ISO-8601 format of "yyyy-MM-dd" - which is valid for your first example, but not for your second. (There aren't 35 days in December.)
As it's trying to parse multiple formats, it doesn't necessarily make sense to isolate which part is "wrong" - different parts could be invalid for different formats.
How you should tackle this depends on where your data comes from. If it's meant to be machine-readable data, it's best to enforce a culture-invariant format (ideally ISO-8601) rather than using DateTime.Parse: specify the format you expect using DateTime.ParseExact or DateTime.TryParseExact. You still won't get information about which part is wrong, but it's at least easier to reason about. (That will also make it easier to know which calendar system is being used.)
If the data is from a user, ideally you'd present them with some form of calendar UI so they don't have to enter the text at all. At that point, only users who are entering the text directly would produce invalid input, and you may well view it as "okay" for them to get a blanket error message of "this value is invalid".
I don't believe .NET provides any indication of where the value was first seen to be invalid, even for a single value. Noda Time provides more information when parsing via the exception, but not in a machine-readable way. (The exception message provides diagnostic information, but that's probably not something to show the user.)
In short: you probably can't do exactly what you want to do here (without writing your own parser or validator) so it's best to try to work out alternative approaches. Writing a general purpose validator for this would be really hard.
If you only need to handle ISO-8601 dates, it's relatively straightforward:
Split the input by dashes. If there aren't three dashes, it's invalid
Parse each piece of the input as an integer. That can fail (on each piece separately)
Validate that the year is one you're happy to handle
Validate that the month is in the range 1-12
Validate that the day is valid for the month (use DateTime.DaysInMonth to help with that)
Each part of that is reasonably straightforward, but what you do with that information will be specific to your application. We don't really have enough context to help write the code without making significant assumptions.

Move to Following Date Part on Data Entry in DateTimePicker

I have a user request that I'm trying to accommodate, the simplest way I can think to explain is to use illustrate with a picture:
Essentially the user is typing a ton of dates in. Instead of typing the
MM [Backslash (Or Right Arrow)]
DD [Backslash]
YYYY [Backslash] etc ...
They'd like to Key the value and be moved to the next Date Part Value. While this doesn't seem like much I can imagine it adds up to allot of additional keystrokes and takes the end user off the number pad. I'm currently using Telerik's Winform RadDateTimePicker with Custom Format:
MM/dd/yyyy hh:mm tt
but would not be opposed to changing to the Winforms DateTimePicker.
Can anyone suggest an elegant solution for this ? The only thing I can currently think of is catching the keystrokes when the control is in focus but I feel like this could be messy.
Thankyou
RadMaskedEditBox (and respectively RadDateTimeEditor, which uses RadMaskedEditBox internally), have build in functionality to select the next part, however, it seems it does not work correctly with this mask, so I reported it as an issue. Here is the link to it: issue link. You can subscribe for status change alerts in order to get notified once its done.
What you can look at is the free form date time parsing introduced recently. It allows you to type in "10162014" which will get parsed to "10\16\2014". More information no parsing dates is available here: Parsing Dates
And the last thing would be to work with KeyDown and manually move the selection. There is API for this on the provider. Here is how to access it:
(this.radDateTimePicker1.DateTimePickerElement.TextBoxElement.Provider as MaskDateTimeProvider).SelectNextEditableItem();
I hope some of this works for you.
This is not intended to be a link answer but I have to refer to the Telerik documentation to allow the OP to customize the control according to his needs.
My understanding is that your customer needs to type the date and time in a specific culture avoiding to type the separators.
You should use the maskedEditBox which already have a mask for your need MM/dd/yyyy hh:mm tt
Particularly you should set the pattern "s" which correspond to "Sortable date time pattern (based on ISO 8601) using local time"
Have a look at Telerik documentation here to set up your control as needed and the relevant validator.
This should solve your problem.
This is how it looks when empty:
and this si show it appears when filled in:
Using the relevant event (I have used radMaskedEditBox1_Leave) you can still use also a dateTimePicker taking the input from the radMasketTextBox:
dateTimePicker1.Format = DateTimePickerFormat.Custom;
dateTimePicker1.CustomFormat = "dd/MM/yyyy HH:mm ss";
dateTimePicker1.Text = radMaskedEditBox1.Text;
Please check below URL fiddle URL for datetime mask:
1]. http://jsfiddle.net/jensbits/3yUes/light/
2]. http://jsfiddle.net/LkpPJ/5/

get the format of a string date in c#

I have a string date like 'Wednesday, May 15, 2013' when I Parse it o lost the original format, is there a way to know what was the original format date or get it before the final Parse?
No, you'll lose the original format, if will now be a different object type with no care for its original format prior to parsing.
Your best option would be to store the pre-parse format prior to parsing as a different variable.
However if you simply wish to format the date in that original format, see Farhad's answer.
You can use this for getting date in a fromat you wish.
String.Format("{0:D}", DateTime.Now); // Tuseday, May 21, 2013
The DateTime struct does not have a format, it stores all of those values on various properties. When you want to display it you specify which format to use.
Using a format specifier when displaying it will likely do what you want. This mdsn article provides some basic information on format specifiers. The only way you can use the exact format you show there is if you know it ahead of time and have a format specifier for it. If you know you'll want to display strings in that format throughout the program it will be easy, if you get many different formats and want to decide how to display your dt at runtime it will be fairly complicated. I'm sure you could write some code to figure out what it is, but once the DateTime is created it will have no notion of what format the string used to create it was in.

DateTime Conversion with Different Cultures

I am wondering what is the best way to figure out how to convert a datetime?
Right now my computer is setup as dd/mm/yyyy yet I am taking date as mm/dd/yyy so when I try to do
DateTime.Convert();
DateTime.Parse();
DateTime.TryParse();
I either get nothing back or it crashes. Now I could tell it about the mm/dd/yyyy format and it probably would convert. However the problem is these dates are are coming from user uploaded files.
They could be in any format combination. I am trying to find ways to do it.
The problem I see is that I am looking at the dates in an uploaded file so I am not sure if looking say at the browser date format would help or not.
I am using asp.net mvc and I am trying to get a solution that handle date formats automatically so I don't have to ask the user about the date format they have (I figure the more things I have to ask them the less likely the user will continue on)
No, you can't figure out automatically what date-time format a user meant to use once the value is on the server. You need more information to parse it correctly (e.g. 1/2/3 can mean a lot of different dates depending on the culture).
Consider one of the following solutions:
Convert the entered date to a text representation in a standard format (i.e. ISO 8601 - 2012-02-09) using JavaScript on the client before you send it to the server. The code would look something like this: d.getUTCFullYear()+"-" + d.getUTCMonth() + "-" + d.getUTCDate().
Send the local culture information to the server along with date value to be converted and do the conversion on the server.
Force the user to enter the date in a specific format (e.g. Use 3 text boxes labeled "Month", "Day", and "Year" instead of one text box with free input).
chobo2 (I like the 'handle') :)
you can detect the locale culture and work on that at will. see the following SO Q/A for pointers:
Where is the system locale/culture set for .Net
the key is to NOT have to set anything in particular, but identify the locale and act accordingly.

current date format

Is there any way to find the current format of date in the time zone? I am retrieving date in the form of string from database and in case the current datetime format does not match, crash comes, "String was not recognized as valid datetime"
It sounds like what's important isn't the current format of the date as your code understand it, but as it gets it from the database. Why is it in the database as a string to start with? If at all possible you should make it an appropriate date/time related field in the database and make the driver do the conversion.
If that's not possible, you should perform the conversion in your code using a custom date/time format which matches what the server gives you, and in an appropriate culture (quite possibly the invariant one).
The DateTime.Parse method uses the format that is set on the executing thread. See the Thread.CurrentCulture to retrieve the CultureInfo that use used when parsing. The CultureInfo.DateTimeFormat returns the format you are looking for.
If you know the format, you should use the DateTime.ParseExact method to parse the input string with a known format.
Sound like you need to use the DateTime.TryParse-method:
http://msdn.microsoft.com/en-us/library/system.datetime.tryparse.aspx
If you don't know in which format the date is passed and .NET can't figure it out I think your out of luck. You could of cause try to see if you could figure out the format by yourself by using regex.

Categories

Resources