I'm trying to parse a date. The problem, is my regular expression omits any letter because I want to avoid 01-28-2019 UTC or any letters outside of the main date. Now, it works fine when the date is formatted like I just listed, however it fails when we get a date formatted like 28-JAN-19.
var sourceValue = Regex.Replace("28-JAN-19", #"[A-Za-z]", "");
var parsed = DateTime.Parse(sourceValue);
The date I need to parse can be in a few different formats. Can a regular expression be used to handle this? If so, what tweaks are needed to trim any letters outside of the xx-xx-xx part of the string?
28-JAN-19
28-01-19
28-JAN-19 13:15:00
28-01-19 13:15:00
28-01-2019 13:15:00
This RegEx should match all the examples you provided:
[0-9]{2}-([A-Za-z]{3}|[0-9]{2})-[0-9]{2,4}( [0-9][0-9]?:[0-9][0-9]?:[0-9][0-9])?
It does make a couple of assumptions though, based on your examples. First, it assumes all your dates will always start with a 2-digit day. It also assumes that your month abbreviations will be 3 letters long. It also assumes that your hours, minutes and seconds will all be 2 digits long. Let me know if any of these assumptions are incorrect.
Here is a fiddle
Regular expressions are likely not your best bet. If you know the full set of formats you might encounter then you can use the regular DateTime.ParseExact with a format string. Check for a FormatException to know if you've successfully parsed the date. If your months are using English abbreviations then be sure to pass in an English culture
DateTime.ParseExact("28-JAN-19", "dd-MMM-yy", new CultureInfo("en"));
Related
I have a little Problem.
i use [0-9\,.]*
to finde a decimal in a string.
And ([^\s]+) to find the text behind the first number.
The string looks normally like this. 1 number a text and than a date:
1.023,45 stück
24.05.10
but sometimes I had just the date and then i become 240510 as decimal.
And sometimes I had just the decimal.
How should I modify the regex to find the date if existing and remove it?
And then look for a decimal an select this if existing.
Thanks in advance.
Divide and conquer
Check for the date first and remove the match from the string
([0-9]{1,2}\.){2}[0-9]{1,2}
Find the number using your original regex
[0-9\,.]*
If you need it find the unit of quantity (assuming that you will only have it as lower case with u Umlaut)
([a-zü]+)
See http://regexe.de/ (German) and http://www.regexr.com/ (English) for some useful information and tools for dealing with regex.
I suggest matching the number in a more restricted way (1-3 digits, then . + 3 digits groups if any, and a decimal separator with digits, optional).
(?s)(?<number>\d{1,3}(?:\.\d{3})*(?:,\d+)?)\s+(.*?)(?:$|\n|(?<date>\d{2}\.?`\d{2}\.?(?:\d{4}|\d{2})))
See demo
The number will be held in ${number}, and the date in ${date}. If the string starts with something very similar to a date (6 or 8 digits with optional periods), it won't be captured. If the date format is known (say, the periods are always present), remove the ?s from \.?s.
(?s) at the beginning will force the period . to match a new line (maybe it is not necessary).
I want to use regular expression for matching these date formats as below in C#.
YYYY/MM/DD 2013/11/12
YYYY/M/DD 2013/5/11
YYYY/MM/D 2013/10/5
YYYY/M/D 2013/5/6
I have tried some regular expressions but they can't match the 4 date formats.
such as
^(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])
check this to get an idea of the compexity of regex and validating dates. so i would use
\d{4}(?:/\d{1,2}){2}
then in c# do whatever to validate the match. while it can be done, you'll be spending a lot of time trying to achieve it, though there is a regex in that post that with a bit of fiddling supposedly will validate dates in regex, but it is a scary looking regex
Try
^\d{4}[-/.]\d{1,2}[-/.]\d{1,2}$
The curly braces {} give the number allowed. E.g., \d{1,2} means either one or two digits.
You may need more than that to match date. Try this:
(19|20)\d\d([-/.])(0?[1-9]|1[012])\2(0?[1-9]|[12][0-9]|3[01])
Ajit's regex is nearer to perfect but leaks the evaluation of the leap years that end with 12 and 16. Here is the correction to be just perfect
((([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])|([0-9]0-9)|([0-9][1-9][13579][26])|([1-9][0-9][13579][26]))-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])))
((([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](([13579][26])|([2468][048])))|([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..
Try this. This accepts all four patterns
#"\d{4}[- /.]([1-9]|0[1-9]|1[012])[- /.]([1-9]|0[1-9]|[12][0-9]|3[01])"
Hi I am trying to wright Regular Expression for date mm/dd/yyyy C#.
I have this
^(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\d\d$
But it doesn't work
How to do so it will works with 3/1/2013 and with 03/01/2013
Don't use regular expressions, use DateTime.TryParse or DateTime.TryParseExact.
Also be aware of the current culture and the user's expectations. Americans use "MM/dd/yyyy" but the rest of the world (generally) uses "dd/MM/yyyy", both are indistinguishable for large ranges of dates.
I agree that you should use DateTime methods for this. But if you want to make the leading zeros optional you can add a ? after them, like so:
^(0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])[- /.](19|20)\d\d$
I feel like I am chasing my tail.
I am trying to arrive at a .Net regex that will match on the following:
mm-dd-yy
m-dd-yy
mm-d-yy
m-d-yy
and (no dashes)
yyyymmdd
One or two digits followed by a dash, followed by one or two digits, followed by a dash, follows by to digits or eight digits:
(\d{1,2}-\d{1,2}-\d{2})|(\d{8})
A very simple RegEx that just matches to the digits being in the correct places and matches all your formats:
^[0-9]{1,2}-[0-9]{1,2}-[0-9]{2}$|^[0-9]{8}$
This does not validate those dates as actual possible dates, to do this you would be better off using DateTime.TryParse
Do you need to use Regex, or do you just care that it is a valid date?
DateTime result;
if(DateTime.TryParse(input, out result))
{
// you have your date in result
}
Well it all comes down to how strict you want the matching to be.
[0-9]+\-[0-9]+\-[0-9]+
will match all the four top ones. But you can enter "99-99-99".
You can be a bit more strict with:
([0-1][0-2]|[0-9])\-(3[0-1]|[0-2]?[0-9]+)\-[0-9]{1,2}
This will only match dates where each component is in a valid range, but only to an extent. It would still match a February with 31 days (which it won't have in the Gregorian calendar). Also it will match 13-04-18 from 3 and onwards. You can use anchors to make it match the whole text (add ^ at the beginning and $ at the end of the regex), but then it won't be able to find the dates inside a text.
You can add a precondition to make sure there's no weird digits around it though. Negative look-behind and negative look-ahead.
(?<![0-9])([0-1][0-2]|[0-9])\-(3[0-1]|[0-2]?[0-9]+)\-[0-9]{1,2}(?![0-9])
And so forth, but this regex has already become a proper behemoth. I would go with the second or third version and use DateTime.Parse to validate it.
There's only so far you can go with regex for dates before they become write-once and insane :) (what about leap years for example, etc. etc.)
I've got DateTime variable and i want to convert it to string "DD.MM.YYYY"
Please note, the values must be separated by "dot" sign.
Of course I can do manual string composition. But I wonder if I can use DateTime.ToString()
to do required conversion.
Yes, you can:
string formatted = dt.ToString("dd'.'MM'.'yyyy");
Now in this case the quotes aren't actually required, as custom date/time format strings don't interpret dot in any special way. However, I like to make it explicit - if change '.' for ':' for example, then while it's quoted it will stay with the explicit character, but unquoted it would be "the culture-specific time separator". It wasn't entirely obvious to me whether "." would be interpreted as "the culture-specific decimal separator" or not, hence the quoting. You may feel that's over the top, of course - it's entirely your decision.
You may also want to specify the invariant culture, just to remove any other traces of doubt:
string formatted = dt.ToString("dd'.'MM'.'yyyy", CultureInfo.InvariantCulture);
(At that point the quotes around the dot become less relevant, as "." is the decimal separator in the invariant culture anyway.)
Yes, you can use DateTime.ToString like this:
myDateVariable.ToString("dd.MM.yyyy");
Note that you have to use capital MM here, since mm evaluates to minutes instead of months.
Here's an alternative for you:
DateTime.Now.ToString("d", new CultureInfo("de-DE"))
German's use . as the date separator.
You can format the date like this:
date.ToString("dd.MM.yyyy")
When formatting numbers the period . will change depending on the CultureInfo used, but not when formatting dates.
If you are verifying your code against the code analysis rule CA1304: Specify CultureInfo you will have to use the invariant culture even though it doesn't matter for this particular format:
date.ToString("dd.MM.yyyy", CultureInfo.InvariantCulture)