I use asp.net 4 and c#.
I need to use a WebControl of type Validation namely RegularExpressionValidator to detect data inputed in a TextBox that IS NOT in format yyyy-MM-dd (String).
Any idea how to write the RegEx to apply ot this control?
Thanks
Here's one possible regex:
^\d{4}-((0\d)|(1[012]))-(([012]\d)|3[01])$
Note: this will prevent months >12 and days >31, but won't check specific months for length (ie it won't block 30th Feb or 31st Apr). You could write a regex to do that, but it would be quite lengthy, and 29th Feb is always going to give you problems in regex.
I'd say if you need that kind of fine-grained validation, you're better off parsing the date with a date library; regex isn't the tool for you. This regex should be sufficient for basic pre-validation though.
I've also gone lenient on the year; just checking that it's four digits. But if you want some sort of sanity check (ie within certain bounds), it shouldn't be too hard to add. Foe example, if you want to match only dates in the this century, you would replace the \d{4} at the beginning of the regex with 20\d{2}. Again, trying to validate a date with excessive accuracy in regex is going to be difficult and you should use a date parser, but you can get basic century-level matching quite easily to prevent the user entering anything really silly.
Finally, I've put ^ and $ to tie off the ends of the string so it can't match if the user enters a valid date and extra characters as well. (You may want to add a string length validator for this as well).
Hope that helps.
Spudley's answer above allows 00 for day and month.
I fixed it :
^\d{4}-((0[1-9])|(1[012]))-((0[1-9]|[12]\d)|3[01])$
Note: neither of these expressions check for days in a month that are invalid, e.g. 04/31, 06/31 or 02/29 on non-leap years.
Regular expression \d\d\d\d-\d\d-\d\d should do the trick.
I would like to add a little change in Spudley's answer:
^\d{4}$|^\d{4}-((0?\d)|(1[012]))-(((0?|[12])\d)|3[01])$
so you can use date like 2013-5-5 (month and date is not necessary the zero but can be used)
Hope it helps.
Another implementation for ISO 8601 structured dates:
^\d{4}-\d{1,2}-\d{1,2}\s\d{1,2}:\d{1,2}:\d{1,2}.?\d{0,}$
It's not quite as strict, and will accept incorrect dates, but it should validate that it follows the ISO 8601 structure even if the date is a non-existent one. It should also be fairly simple to understand for anyone with a basic Regex understanding.
If you really want to ensure the date is correct, and work with it, run DateTime.TryParse() on it.
(19|20)[0-9]{2}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])
mach result:
1999-09-12
((([0-9][0-9][0-9][1-9])|([1-9][0-9][0-9][0-9])|([0-9][1-9][0-9][0-9])|([0-9][0-9][1-9][0-9]))-((0[13578])|(1[02]))-((0[1-9])|([12][0-9])|(3[01])))|((([0-9][0-9][0-9][1-9])|([1-9][0-9][0-9][0-9])|([0-9][1-9][0-9][0-9])|([0-9][0-9][1-9][0-9]))-((0[469])|11)-((0[1-9])|([12][0-9])|(30)))|(((000[48])|([0-9]0-9)|([0-9][1-9][02468][048])|([1-9][0-9][02468][048]))-02-((0[1-9])|([12][0-9])))|((([0-9][0-9][0-9][1-9])|([1-9][0-9][0-9][0-9])|([0-9][1-9][0-9][0-9])|([0-9][0-9][1-9][0-9]))-02-((0[1-9])|([1][0-9])|([2][0-8])))
This is the regex for yyyy-MM-dd format.
You can replace - with \/ for yyyy/MM/dd...
Tested working perfect..
Related
How to parse abbreviated day-of-week name (e.g. 'Fri' or 'Sat') to NodaTime.IsoDayOfWeek? Preferrably looking for something that uses NodaTime built in pattern matching capabilities. If that's not possible, alternative approaches or workarounds are welcome. This does not have to be culture sensitive, okay to assume CultureInfo.InvariantCulture.
I tried using LocalDatePattern "ddd" with a LocalDate template but it will fail unless the day of week I'm parsing (e.g. 'Fri') matches the template day of week. I could iterate over 7 different templates and return the first one that succeeds to parse but surely there must be a better way?
I was looking at a code in an application (Someone else wrote it),on some cases it worked fine and on some cases it gave exceptions,it was actually converting strings in datetime,here is the code
//5000 is the year,but what about "1" is it month or day ?,if its month
//then what about the day ?
DateTime time = DateTime.Parse("1.5000");//1.5000 doesn't looks a date to me ?
time.ToString();//returns "1/1/5000 12:00:00 AM"
//where as if I give this string to DateTime.Parse();
time = DateTime.Parse("2341.70");
//FormatException was unhandled
//String was not recognized as a valid DateTime.
A Confusing thought
How does this string "3.5000" (it matches the 1.5000 pattern) evaluates , does this means 3-3-5000 or 1-3-5000 ,the format is ambiguous its unclear and confusing !
My questions are,
What kind of formats can DateTime.Parse expects ?
Whats happening in the code above ?
Suggestions to improve the code ?
Many people have commented on the possible reasons for the parse that you have seen being successful but your question seems to have several separate parts...
1. What kind of formats can DateTime.Parse expects ?
DateTime.Parse has been written to be as inclusive as possible. Pretty much anything that it can find someway to make into a DateTime it will do its best to do so which means in addition to the usual familiar yyyy-MM-dd type formats more strange ones like M.yyyy or yyyy.M and so on.
2. Whats happening in the code above ?
That is very complicated because the DateTime.Parse method is itself very complicated. You can probably fidn the source code out there somewhere but the complexity made it very hard for me to follow. Without being able to give precise details I'm going to answer this the same as above. What is happening is that the framework is trying its best to give you a date back and not throw an exception. The date it gives is the best guess as to what you meant.
3. Suggestions to improve the code ?
It sounds like if you are getting parse exceptions that you are passing dates in formats that are unexpected. Without knowing what those inputs are its hard to say. Two things could improve your code though. Making sure a single consistent date format is used and then using DateTime.ParseExact to ensure that it conforms to the right format. You will remove all ambiguity this way but you will sacrifice flexibility.
The second option is to use DateTime.TryParse. This will attempt to parse your date and then return a boolean saying whether it succeeded or not. If successful the date parse will be returned in a ref parameter. This won't make your code any better at recognising unknown date formats but will let your code know when such an unparsable format crops up and you can deal with it (eg by providing user feedback reporting the wrong format and suggesting a correct one, or just by logging it or something else).
What the best method is depends mostly on where your input is coming from. If it is user input then I'd go with the second option. If it is automated input then you probably want to make sure your input is standardized and then use the first option. Of course circumstances always vary so this is not a hard and fast rule. :)
In regards to "2. Whats happening in the code above ?":
In some cultures, the date separator is a dot instead of a slash. So for example 13.12.2013 is a valid date (2013-12-13) in the format "dd.MM.yyyy". Now by whatever design choice, the day part in this example is not mandatory and if left out, is automatically filled with 1. So parsing 12.2013 would result in 2013-12-01. And therefore it's easy to see how 1.5000 would become 5000-01-01. 2341.70 can not be parsed, because 2341 is not a valid month. - So in this case 1.5000 is a "valid" date in the format M.yyyy.
I have some data picked up from an excel file.
I want to validate that the user has entered a valid date time string. I have tried to use DateTime.Parse method but found that certain values seem to be accepted.
For example,
If I submit 3.3 as a date time this is accepted by the DateTime.Parse method as a valid date time and outputs 03/03/2012 00:00:00
I want to want to block this. Only allowing the user to enter correctly formatted date times.
So for example a user could supply 03/03/2012 or 03/03/2012 12:30:00 but not values like 01022012 or 3.3.2012
Any Ideas?
You want to use DateTime.ParseExact or DateTime.TryParseExact
This allows you do parse from a date format string of your choice.
http://msdn.microsoft.com/en-us/library/system.datetime.tryparseexact.aspx
Examples here:-
http://msdn.microsoft.com/en-us/library/ms131044.aspx
You can use RegEx to to this. Something like this should help #"\d{2}/\d{2}/\d{4}(\s+\d{2}\:\d{2}\:\d{2})?"
You can handle it on the client side with various jquery plugin/functions like this or a simple Google search can return many other useful results.
if you want to handle it on the server side, (I am not sure on what project you are working) but depending over it you can write your own method/use Regex or Data Annotation MVC.
If you are still having trouble try adding few details about your project such as Language, Architecture etc. that would help more in providing the right solution.
Hope it helps. Thankyou
The jquery FullCalendar plugin has a neat format for time.
If it the time is 7:00pm, the format shows up as 7p.
If it the time is 7:30am, the format shows up as 7:30a.
Question: Is there any way to use standard formatting to accomplish this with c# sharp? Obviously I can create logic to do this myself, but I'm hoping there is a format string that will accopmlish this.
ie (doesn't work):
MyDateTime.ToString("h{:mm}t");
Formatting strings do not have conditionals - there is no way to specify a condition within a format string.
You will need to use a standard if and format accordingly.
if(MyDateTime.Minutes == 0)
{
return MyDateTime.ToString("h");
}
return MyDateTime.ToString"h:mmt");
Or, in one line:
return MyDateTime.ToString((MyDateTime.Minutes == 0)?"h":"h:mmt");
No, there's nothing like this within the built-in .NET date/time formatting. You'll have to write the code yourself.
(I haven't seen anything similar for dates and times in other date/time libraries, to be honest. I've seen conditional formatting for periods, but that's a different matter. The only exception to this is "fractional seconds" which can be expressed such that they're removed - including the decimal point - if the time is a whole number of seconds.)
I'm making a timecard program, where the user enters the start time, end time, and project name. They can click "Add" and it adds the entered details to a listbox.
I don't allow the data to be added unless the start time and end time are formatted like this: 08:14am It gets annoying, though, having to enter it exactly like that each time, so I decided to, via regexes, have it automatically format. So if you enter 8:14, it will change it to 08:14am. How can I accomplish this via Regex.Replace()?
If you have any other methods, don't hesitate to list them.
Edit 1: I also have other replacements in mind; for example 814 goes to 08:14am, and 8 goes to 08:00am
Edit 2: So Now I'm using this code:
string[] formats = { "h:mm", "h", "hh", "hmm", "hhmm", "h:mmtt", "htt", "hhtt" };
DateTime dt = DateTime.ParseExact(t.Text, formats, new CultureInfo("en-US"), DateTimeStyles.None);
t.Text = dt.ToString("hh:mmtt").ToLower();
And it replaces some things, like h:mm but not others like h.
Have you looked at DateTime.Parse? It accepts "08:14am", "8:14"[1] and other variants, and returns a DateTime set to 8:14 am on today's date.
[1] In the UK culture at least -- consider providing a CultureInfo parameter depending on whether you want to pay attention to the user's local format preferences, or adopt a fixed format.
EDIT I also have other replacements in mind; for example 814 goes to 08:14am, and 8 goes to 08:00am
Take a look at DateTime.ParseExact: you can provide an array of valid time formats (such as "hh:mm", "hmm", "h" etc.)
Coming at it from a completely different direction, how about using a mask on the input?
For example, there are a number of JavaScript and jQuery tools available to do this.
Using this approach retains some user control over the input, and lets the user see their input.
have you considered using a DateTimePicker? Making the user write the time looks like more of a hassle.
See e.g. http://msdn.microsoft.com/en-us/library/system.windows.forms.datetimepicker.aspx
I think regex are overkill for this. Why not simply append the "am" at the end, in case nto already added is a 2 line code in case you are working with strings in the method.
I would recommend against using regular expressions if possible (as others have said, it seems like overkill) and try using datetime formats. See here: http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx
The "HH" format tag will format the hour as a 24-hour time from 00 to 23. Traditionally, 12 hour times are not zero-padded to the left, but 24 hour times are (at least as often as I see them), probably to avoid confusion between 1800 and 0800 . Alternatively, if you don't want 24 hour times, you could probably just left-pad the hour part of the string with a zero to up to 2 digits.
EDIT:
Based on your new requirements, I'd say write a simple parser to let users input "814" meaning "08:14 AM" and make use of the time-formatting functionality for display.