Solved

date range ...

Posted on 2011-03-16
23
640 Views
Last Modified: 2012-05-11
Hi experts. Regular expressions are, to be perfectly honest with you, a bit of a black art to me, so I don't even know where to start.


Basically this is what I want to do. I have two dates presented to me as strings in

"YYYY-MM-DD" format

What I want to be able to do is use a regular expression that recognises any other date that falls within the range specified by the two dates I got.

I trust this is somewhat helped by the fact that if you write any dates out as numbers like YYYYMMDD, the > and < operators would always work. so if date 3 falls between date 1 and date 2, then the YYYYMMDD representations of these three dates also follow a simple numeric comparison.


But how do you express that in "regular expressions"?


cheeeeers.
0
Comment
Question by:WernerVonBraun
  • 9
  • 7
  • 4
  • +2
23 Comments
 
LVL 74

Expert Comment

by:käµfm³d 👽
Comment Utility
Parsing dates is a frightening task in regex. To actually "parse" a date for validity, the pattern is quite extensive and complicated. If you merely want to validate structure, then the regex is not nearly as bad.

Is there a reason why you can't parse the dates in your language using some built-in construct?
0
 
LVL 4

Author Comment

by:WernerVonBraun
Comment Utility
I don't need to validate dates, I merely need to be able to confirm that one string that looks like yyyy-mm-dd alphabetically falls between two others.
0
 
LVL 41

Expert Comment

by:HonorGod
Comment Utility
> What I want to be able to do is use a regular expression that recognises any other date that falls within the range specified by the two dates I got.

  This is a really difficult task.

  I would suggest that you start by taking a look at this article I wrote:
2 Dates - What's the difference? http://www.experts-exchange.com/A_483.html

  My suggestion would be to:
- verify/validate that each date is valid using a RegExp
- convert each date into a Date object
- use a simple comparison to test if a third date is between the start and end date

  Does this make sense?
0
 
LVL 41

Expert Comment

by:HonorGod
Comment Utility
> I merely need to be able to confirm that one string that looks like yyyy-mm-dd alphabetically falls between two others.

  The problem with this is that the date may "look" valid (e.g., Feb 29th, 2011) but may not, in fact, be a real date.

  So it is much better to have the string verified using a RegExp, then converting it to a actual Date object (which can then be formatted and compared to the user specified value).  Then, this Date object should be used for the kind of comparison you describe.
0
 
LVL 74

Expert Comment

by:käµfm³d 👽
Comment Utility
>>  I merely need to be able to confirm that one string that looks like yyyy-mm-dd

Regex can satisfy this requirement.


>>  alphabetically falls between two others.

Regex can not satisfy this requirement.
0
 
LVL 4

Author Comment

by:WernerVonBraun
Comment Utility
Ok, let's see if I can explain this better, because I think I made a balls of it first time around.

The validity or non-validity of the dates are actually completely irrelevant to me. Yes, the actual strings in question *are* produced by some tool converting actual dates into a "YYYY-MM-DD" format, but by the time I come to look at that it is no longer important where the strings came from. They are now stored in a kind of "database", as strings, and the only way I have to interrogate the database is to ask it, in a language that *it* understands, to give me all the rows for which field X conforms to any regular expression that I care to provide.

Say the database contains the rows:

1292-44-77
9290-33-36
2883-33-46
3565-52-33

Say I have two values:

2322-99-87
and
8208-11-37

When you look at all the strings on a purely *alphabetical* basis, you will see that the first row does not fall between the two provided values. Nor does the second row. But the 3rd and 4th do.


And that's what I'm looking for. A formula that, given two of such values that are formatted like 4 digits, a dash, 2 digits, a dash and 2 more digits can give me, for any third value that is also formatted like that, a "yay" or "nay" for the question "does the 3rd value fall between the first and the second one".

I'll make sure that the first one is always the smaller one and the second the larger one.
0
 
LVL 4

Author Comment

by:WernerVonBraun
Comment Utility

>> >>  alphabetically falls between two others.

>> Regex can not satisfy this requirement.


Why not?
0
 
LVL 4

Author Comment

by:WernerVonBraun
Comment Utility
>> Regex can not satisfy this requirement.

I would be surprised if it couldn't. Let me describe the mechanism in pseudocode. Say you have two two-character values and one for comparison:

23
67

I would do it something like this:

If Char1 < 2 then "nay"
ElseIf Char1 > 6 then "nay"
Else
  If Char2 < 3 then "nay"
  ElseIf Char2 > 7 then "nay"
  Else
     "yaaaaay"!!!!!!
  EndIf
EndIf


Obviously I'm talking about 10-character comparison strings of which the 5th and the 7th character are *always* a dash, so the real pseudocode would be much more complex but that is the basic principle. I would be surprised if something like that could not be done in regex
0
 
LVL 41

Expert Comment

by:HonorGod
Comment Utility
> > Regex can not satisfy this requirement.

> Why not?

  Because in order for the RegExp to do this kind of thing, it would have to have patterns to explicitly identify the end points, as well as the allowed intermediate values.

- For example:
  You can have a pattern identify that a character is a digit using this meta-character \d
 
  And, you can identify that a numeric value is within a specific range by adding modifiers, and making the RegExp much more complex.

  To identify a 3 digit value we might want to use something like: \d\d\d  or \d{3}
  this would match things like 000 001 002 003 all the way to 999

  Here's one way to validate that a number is in the range of 0..255:
(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])

  But, there is no way to have a RegExp say that you have 3 numeric values ... in increasing order.

  Does that make sense?


0
 
LVL 4

Author Comment

by:WernerVonBraun
Comment Utility
I can construct the regex in my calling program so getting the "2" and the "6", and the "3" and the "7" in there as per the example I gave shouldn't be a problem.
0
 
LVL 41

Expert Comment

by:HonorGod
Comment Utility
> I would be surprised if something like that could not be done in regex

  Unfortunately, your pseudo-code "knows" where each two digit number exists, and is able to say

  compare the 1st digit of value #1 against the 1st digit of value #2

  A RegExp must provide a pattern to analyze the characters in order.
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 41

Expert Comment

by:HonorGod
Comment Utility
You could have a RegExp that validates the three different dates.
However, you would need extra code to compare the different pieces of each date value outside of the RegExp.
0
 
LVL 4

Author Comment

by:WernerVonBraun
Comment Utility
> But, there is no way to have a RegExp say that you have 3 numeric values ... in increasing order.

But that's not what I'm looking for. I'm only checking *one* number against criteria that, yes, consist of two other numbers but I'm willing and able to process those to generate a brand-new regular expression "on the fly" so to speak.

Even simpler example

Say you have a word

"fish"

Surely you could construe a regular expression that will tell you whether "fish" falls between "boat" and "water" or not?
0
 
LVL 41

Expert Comment

by:HonorGod
Comment Utility
Consider a string containing 3 dates...

YYYY-MM-DD  YYYY-MM-DD  YYYY-MM-DD

How, looking at the characters in order, can you say that the 2nd and 3rd date are "numerically larger" than the first?

You could have a RegExp that is able to determine where each part of each date exists, e.g.,

- Year1
- Month1
- Date1

- Year2
- Month2
- Date2

- Year3
- Month3
- Date3

  But, being able to take each as a whole value, and saying that the next date, as a whole value, is larger is not possible with RegExp
0
 
LVL 41

Expert Comment

by:HonorGod
Comment Utility
> Surely you could construe a regular expression that will tell you whether "fish" falls between "boat" and "water" or not?

  That is not how RegExp are designed to work.

  They are used to define a pattern against which values can be compared.

  You could have a RegExp that was able to identify "fish", "boat" and "water", or 3 different words in an input string. But the RegExp can't be used to say that "word1" must be less than "word2" must be less than "word3" in the input value.
0
 
LVL 74

Expert Comment

by:käµfm³d 👽
Comment Utility
>>  Why not?

Because what you are saying is you want to compare the values of two widgets. Regular expressions are about matching patterns, not comparing values, per se. A typical use of regular expression would be:

    verify that the target string is, "formatted like 4 digits, a dash, 2 digits, a dash and 2 more digits."

What you are talking about doing is comparing the value of A to the value of B and to the value of C.

Regular expressions are a form of state machine--a very simple state machine. We say that a pattern accepts input if we can transition from state to state based on the source data. Given the pattern:

    \d*[a-z][a-z]*

and the input:

    123abc

The different states of this machine are shown below (states are the circles).

  State Machine for Regex Example
The triangle points to our initial state; the double-circle is our terminating state (acceptance state). You should be able to see from the diagram, we can loop an indefinite number of times whenever we find a digit, so long as we are in the first state (q0). This part of the machine would match the "123" in our source data. Once we find a letter, matched by the transition between q0 and q1, we transition to the next state (q1). "a" would be matched during this transition. While at q2, we can loop an indefinite number of times to find more letters. "bc" would be matched by this action. Once we no longer find a letter, the double-circle part of the state machine is enforced and we say the source data was accepted by the pattern if we reach this double-circle. If we never get to q1 (because we found, say, a question mark, which is not defined by this pattern), then the source data was not accepted by the pattern.

You'll notice there's no way, according to the diagram, to compare two things to each other. There's not even a way to compare if one thing is less than or greater than another. This is the same concept behind regex. Your pattern is what you are comparing against the source data. You pattern basically only checks for conditions of equality, and when it can't find such, it abandons the matching process and indicates failure.

I realize that's more than you probably wanted to know, but I'm hoping to shed some light on how regex works  = )
0
 
LVL 35

Assisted Solution

by:Terry Woods
Terry Woods earned 150 total points
Comment Utility
Given 2 values, say:
2322-99-87
and
8208-11-37

It should be possible to programmatically *build* a regular expression that accepts values between those values. I think RegexBuddy can do this, maybe?
0
 
LVL 84

Accepted Solution

by:
ozo earned 350 total points
Comment Utility
2322-99-87
and
8208-11-37

2322-99-8[7-9]|2322-99-9[0-9]|232[3-9]-[0-9][0-9]-[0-9][0-9]|23[3-9][0-9]-[0-9][0-9]-[0-9][0-9]|2[4-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]|[3-7][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]|8[0-1][0-9][0-9]-[0-9][0-9]-[0-9][0-9]|820[0-7]-[0-9][0-9]-[0-9][0-9]|8208-0[0-9]-[0-9][0-9]|8208-10-[0-9][0-9]|8208-11-[0-2][0-9]|8208-11-3[0-7]
0
 
LVL 35

Expert Comment

by:Terry Woods
Comment Utility
Exactly!
0
 
LVL 4

Author Comment

by:WernerVonBraun
Comment Utility
And there we have it. That is actually quite simple. Now all I need to do is write a proggy that can produce a similar kind of RegEx given *any* "start" and "end" value and ozo's yer uncle .... or aunt .... whatever the case may be. Thanks a mill.
0
 
LVL 4

Author Closing Comment

by:WernerVonBraun
Comment Utility
350 for ozo for providing the actual solution, and a 150 point acknowledgement to TerryAtOpus for thinking along the right lines before ozo posted it.
0
 
LVL 74

Expert Comment

by:käµfm³d 👽
Comment Utility
I stand corrected  = )
0
 
LVL 4

Author Comment

by:WernerVonBraun
Comment Utility
No problem. Probably also due to the clunky and confusing way in which I presented the true nature of the problem.
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

I have been reconstructing a PHP-based application that has grown into a full blown interface system over the last ten years by a developer that has now gone into business for himself building websites. I am not incredibly fond of writing PHP code o…
Whatever be the reason, if you are working on web development side,  you will need day-today validation codes like email validation, date validation , IP address validation, phone validation on any of the edit page or say at the time of registration…
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now