By James Kanjo
Description
Sometimes we have specific syntax requirements for when our users provide us input. For example, lets say we wanted to user to enter a number… if the user enters a letter, we want an error message to inform them that they haven't entered a number.
In Wikidot, we are given the ability to use Regular Expressions (RegExp) to ensure our users enter the correct data inside textboxes (including when creating new pages, data forms or even mail forms).
Creating a RegExp to validate a user's input for a date, is no easy task. Why not? Because the RegExp needs to account for the fact that not every month in the year has 31 days. It also needs to account for the fact that February has only 28 days. And, of course, it needs to account for February's 29th day during leap years only.
With this Wizard, you can generate a RegExp for validating Dates according to the syntax you specify.
And yes, it does account for days in the month, and leap years.
The RegExp Date Wizard uses the following code:
<html>
<head>
<title>RegExp Date Wizard</title>
<style type="text/css">
@import url("/common--theme/base/css/style.css");
</style>
<script type="text/javascript">
function Generate() {
var str_format = document.forms["regexp-wizard"].format.value;
var str_year = '\\d\\d';
if (document.forms["regexp-wizard"].year[0].checked) {str_year = '';}
var str_separator = '[';
if (document.forms["regexp-wizard"].hyphen.checked) {str_separator = str_separator + '-';}
if (document.forms["regexp-wizard"].slash.checked) {str_separator = str_separator + '\\/';}
if (document.forms["regexp-wizard"].period.checked) {str_separator = str_separator + '.';}
if (document.forms["regexp-wizard"].space.checked) {str_separator = str_separator + ' ';}
str_separator = str_separator + ']';
if (str_separator == '[]') {str_separator = ''}
var str_regexp;
if (str_format == 'ymd') {str_regexp = '/^((' + str_year + '([02468][048]|[13579][26])' + str_separator + '(0[13578]' + str_separator + '(0[1-9]|[12][0-9]|3[01])|0[469]' + str_separator + '(0[1-9]|[12][0-9]|30)|02' + str_separator + '(0[1-9]|[12][0-9])|1[02]' + str_separator + '(0[1-9]|[12][0-9]|3[01])|11' + str_separator + '(0[1-9]|[12][0-9]|30)))|(' + str_year + '([02468][1235679]|[13579][01345789])' + str_separator + '(0[13578]' + str_separator + '(0[1-9]|[12][0-9]|3[01])|0[469]' + str_separator + '(0[1-9]|[12][0-9]|30)|02' + str_separator + '(0[1-9]|1[0-9]|2[0-8])|1[02]' + str_separator + '(0[1-9]|[12][0-9]|3[01])|11' + str_separator + '(0[1-9]|[12][0-9]|30))))$/'}
if (str_format == 'dmy') {str_regexp = '/^((((0[1-9]|[12][0-9]|3[01])' + str_separator + '0[13578]|(0[1-9]|[12][0-9]|30)' + str_separator + '0[469]|(0[1-9]|[12][0-9])' + str_separator + '02|(0[1-9]|[12][0-9]|3[01])' + str_separator + '1[02]|(0[1-9]|[12][0-9]|30)' + str_separator + '11)' + str_separator + '' + str_year + '([02468][048]|[13579][26]))|(((0[1-9]|[12][0-9]|3[01])' + str_separator + '0[13578]|(0[1-9]|[12][0-9]|30)' + str_separator + '0[469]|(0[1-9]|1[0-9]|2[0-8])' + str_separator + '02|(0[1-9]|[12][0-9]|3[01])' + str_separator + '1[02]|(0[1-9]|[12][0-9]|30)' + str_separator + '11)' + str_separator + '' + str_year + '([02468][1235679]|[13579][01345789])))$/'}
if (str_format == 'mdy') {str_regexp = '/^(((0[13578]' + str_separator + '(0[1-9]|[12][0-9]|3[01])|0[469]' + str_separator + '(0[1-9]|[12][0-9]|30)|02' + str_separator + '(0[1-9]|[12][0-9])|1[02]' + str_separator + '(0[1-9]|[12][0-9]|3[01])|11' + str_separator + '(0[1-9]|[12][0-9]|30))' + str_separator + '' + str_year + '([02468][048]|[13579][26]))|((0[13578]' + str_separator + '(0[1-9]|[12][0-9]|3[01])|0[469]' + str_separator + '(0[1-9]|[12][0-9]|30)|02' + str_separator + '(0[1-9]|1[0-9]|2[0-8])|1[02]' + str_separator + '(0[1-9]|[12][0-9]|3[01])|11' + str_separator + '(0[1-9]|[12][0-9]|30))' + str_separator + '' + str_year + '([02468][1235679]|[13579][01345789])))$/'}
document.getElementById('regexp').innerHTML = str_regexp;
if (document.forms["test-regexp"]["test-input"].value != '') {TestRegExp(document.forms["test-regexp"]["test-input"].value);}
}
function TestRegExp(tmp_str) {
var exp_regexp = eval(document.getElementById('regexp').innerHTML);
if (exp_regexp.test(tmp_str)) {tmp_str = 'Date Accepted';}
else {tmp_str = 'Invalid Date';}
document.getElementById('regexp-evaluation').innerHTML = tmp_str;
}
</script>
</head>
<body style="margin: 0;" onload="Generate();">
<h2>RegExp Date Wizard:</h2>
<form name="regexp-wizard" onsubmit="return false;">
<strong>Format:</strong>
<select onchange="Generate();" name="format">
<option value="ymd">Year Month Day</option>
<option value="dmy">Day Month Year</option>
<option value="mdy">Month Day Year</option>
</select>
<strong>Year:</strong>
<input onchange="Generate();" type="radio" name="year" value="2" /> 2 Digits
<input onchange="Generate();" type="radio" name="year" value="4" checked="true" /> 4 Digits <br />
<strong>Separator:</strong>
<input onchange="Generate();" type="checkbox" name="hyphen" checked="true" /> -
<input onchange="Generate();" type="checkbox" name="slash" style="margin-left: 30px;" /> /
<input onchange="Generate();" type="checkbox" name="period" style="margin-left: 30px;" /> .
<input onchange="Generate();" type="checkbox" name="space" style="margin-left: 30px;" /> space
</form>
<h2>RegExp Code:</h2>
<div class="code"><pre><code id="regexp"></code></pre></div>
<h2>Test RegExp:</h2>
<form name="test-regexp" onsubmit="return false;">
<input name="test-input" size="10" onkeyup="TestRegExp(this.value);" value="" /> <span id="regexp-evaluation" style="font-weight: bold;"></span>
</form>
</body>
</html>
Don't worry if looking at that scares you. You shouldn't need to use it in your wiki at all.
Code
After specifying your date syntax below, the RegExp is automatically generated for you to copy and paste from the “RegExp Code” box.
You can also test the RegExp by typing a date into the “Test RegExp” text box.
Also be aware that the generated RegExp only accepts days and months with two digits (the 1st of September = 01 of 09).
Other snippets posted by James Kanjo
Rate this solution
If you think this solution is useful — rate it up!
That's clever that it does leap years as well :D
Too bad I couldn't set the date for Caesar's assassination ;)
Timothy Foster - @tfAuroratide
Auroratide.com - Go here if you're nerdy like me
One suggestion:
I'd like the ability to allow single-digit values for the day and month, particularly for the "Day Month Year" option.
i.e. I'd like to allow both 5/6/11 and 05/06/11 as valid dates (DD/MM/YYYY).
Other than that… excellent! :)
Edit: Perhaps change year to checkboxes (to allow 2-digit and 4-digit dates in the same RegEx) - and then do the same thing for dates/months (but with 1-2 digits instead of 2-4). Then it will be perfect :)
~ Leiger - Wikidot Community Admin - Volunteer
Wikidot: Official Documentation | Wikidot Discord server | NEW: Wikiroo, backup tool (in development)
Oh god no! If I allowed that, and people used it in data forms, and in the future Wikidot support sorting by data form fields… it would be disastrously inconsistent!
Imagine the dates been ordered like so:
But then again, it is a RegExp wizard, the choice should be the user's not my own…
Exactly - but it stood out as something that was missing from your tool. Now it's pretty much complete.
The idea is to validate dates, right? (Not with the intention of converting to a date field later.) It's for that reason that I also suggested the single-digit option for day/month. But it's easy for me to modify the RegEx myself to support that if needed.
~ Leiger - Wikidot Community Admin - Volunteer
Wikidot: Official Documentation | Wikidot Discord server | NEW: Wikiroo, backup tool (in development)
Wow! Awesome! :D
Kenneth Tsang (@jxeeno)
Nice to know how much dates excite you :D
Personally, I like to have them with my WeetBix for breakfast.