Totally Zenned
- Join Date:
- Jan 2005
- Posts:
- 1,285
- Plugin Contributions:
- 0
International Date Formats
As requested to avoid confusion, here's a new and (so far) clean thread on how to set the date format to something else than the default month/day/year.
We'll start with date of birth under registration/my account, and then continue with entering dates in the advanced search form. And speaking of the search form, here's how to edit the AND and OR search operators to your specific language.
You can also now enter dates with month names, you don't need to separate numbers with slashes anymore (though you can still do that if you want), and you don't need to specify the century. For instance, when DATE_FORMAT is set to 'd,m,y', "27th of february 82" means "19820227", and "2jan05" means "20050102" (05 here doesn't mean 1905, because january the second 1905 is more than 100 years ago.).
I believe this makes entering dates much more fool-proof.
Further examples: (when DATE_FORMAT is set to 'dmy', and the current date is 2005.02.02)
2180 -> 19800102
1011 -> false (there is no 0 month)
11106 -> 19060111 (1906 and not 2006 because 1906 is less than 100 years ago)
10105 -> 20050110 (2005 and not 1905 because 10th of january 1905 is more than 100 years ago)
2011980 -> 19800110 (20th of january and not the second of january, because when day and month are only 3 digits, month will get 1 and day will get 2)
30/04-1904 -> 19040430
31/04-1904 -> false (april doesn't have 31 days)
1dec70 -> 19701201
29feb2000 -> 20000229
29feb2001 -> false (not leap year)
10feb january mar 75 -> 19750210 (when several months are named - yes, I know it's silly, but there's a reason for this example too - the first one will be taken)
abc1feb.foo-ary/\82xyz -> 19820201 (all non-digit characters will be removed after parsing for month name)
Don't worry about the examples being "day, month year", it depends on what DATE_FORMAT is set to in includes/languages/<language>.php.
Date of birth.
Here's how to do it:
Go to the admin area and edit
admin-> configuration-> minimum values-> date of birth
set it to 4.
Replace the old function
function zen_date_raw($date, $reverse = false) {
if ($reverse) {
return substr($date, 3, 2) . substr($date, 0, 2) . substr($date, 6, 4);
} else {
return substr($date, 6, 4) . substr($date, 0, 2) . substr($date, 3, 2);
}
}
with the following code
/* If MONTH_ABBR is not set, the function will try to find the proper month names anyway, by looking at the set locale */
define('MONTH_ABBR', 'jan feb mar apr may jun jul aug sep oct nov dec');
// Heavily modified version of zen_date_raw() for language-specific date format etc.
function zen_date_raw($date, $reverse = false) {
$date = strtolower($date);
/* The second " " adds a value before MONTH_ABBR, so the first string in constant MONTH_ABBR starts at $month_abbr[1], and not $month_abbr[0] */
if ((defined('MONTH_ABBR'))AND(constant('MONTH_ABBR'))) {$month_abbr = explode(" ", " " . strtolower(MONTH_ABBR));}
else {for ($i=1; $i < 13; $i++) {$month_abbr[$i] = strtolower(strftime("%b",strtotime("$i/1/2004")));}}
for ($i=1; $i < 13; $i++) {$month_strpos[$i]=strpos($date, $month_abbr[$i]); if (is_int($month_strpos[$i]) && !isset($first_case)) {$first_case=$month_strpos[$i]; $m=$i;}; if (is_int($month_strpos[$i]) && $month_strpos[$i] < $first_case) {$first_case=$month_strpos[$i]; $m=$i;};};
if (isset($m) && isset($first_case)) {$date = substr_replace($date, $m, $first_case, 0);};
/* Now, as we've converted any eventual month strings into a number, remove non-numeric characters. */
$date = ereg_replace("[^0-9]","", $date);
/* For the date format, remove all characters except d, m and y. */
$dformat = ereg_replace("[^dmy]","", strtolower(DATE_FORMAT));
/* Define regex for day, month and year. */
$dd="([0-2][1-9]|[1-3][0-1]|[1-9])";
if (isset($m) && isset($first_case)) {$mm="(" . $m . ")";} else {$mm="(0?[1-9]|1[0-2])";};
$yyyy="((19|20)?[0-9]{2})";
/* Look at the set date format, and create the entire regex line as well as set the location where day, month and year is to be found for later reference. */
if ($dformat=="dmy") {$regexp=$dd . $mm . $yyyy; $d="2"; $m="3"; $y="4";}
else if ($dformat=="mdy") {$regexp=$mm . $dd . $yyyy; $d="3"; $m="2"; $y="4";}
else if ($dformat=="ydm") {$regexp=$yyyy . $dd . $mm; $d="4"; $m="5"; $y="2";}
else {$regexp=$yyyy . $mm . $dd; $d="5"; $m="4"; $y="2";}
/* Do the magic or return false. */
if (!ereg("(^" . $regexp . "$)", $date, $regs)) {return false;};
/* If some values are too short, fix them. */
/* fix value of day */
if (strlen($regs[$d])=="1") {$regs[$d]="0" . $regs[$d];}
/* fix value of month */
if (strlen($regs[$m])=="1") {$regs[$m]="0" . $regs[$m];}
/* fix value of year. If year is less than or equal to the last 2 numbers of the current year, set century to 20. */
if (strlen($regs[$y])=="2") {if ($regs[$y] <= (date(y))) {$regs[$y]="20" . $regs[$y];} else {$regs[$y]="19" . $regs[$y];}}
/* Find maximum number of days in the current month, and make sure the day inserted is not higher. */
/* Is month one of january, march, may, july, august, october or december? */
if ($regs[$m]=="01" || $regs[$m]=="03" || $regs[$m]=="05" || $regs[$m]=="07" || $regs[$m]=="08" || $regs[$m]=="10" || $regs[$m]=="12") {$no_of_days = "31";}
/* Is month one of april, june, september or november? */
else if ($regs[$m]=="04" || $regs[$m]=="06" || $regs[$m]=="09" || $regs[$m]=="11") {$no_of_days = "30";}
/* So the month is february, but is it a leap year? */
else if (date("L", strtotime($regs[$y]."0101"))) {$no_of_days = "29";}
else {$no_of_days = "28";};
/* If the day is higher than what is allowed, it's obviously not a correct date. */
if ($regs[$d] > $no_of_days) {return false;};
/* Return date like ddmmyyyy (reverse) or the standard yyyymmdd? */
if ($reverse) {
$date=$regs[$d] . $regs[$m] . $regs[$y];
} else {
$date=$regs[$y] . $regs[$m] . $regs[$d];
}
return $date;
}
- (optional - This is probably already done in your language files.)
To set the date format, look for the line
define('DATE_FORMAT', 'm/d/Y');
inside includes/languages/<language>.php and change it to suit your needs.
That's it.
For reference, here's the old thread.
If you don't know how to set your locale correctly, here's how:
In the file inside includes/languages/<language>.php,
look for the line
@setlocale(LC_TIME, 'en_US');
``` (or similar)
and set it to the proper locale.
To find out your *nix server's availible locales, try to add this code to a test file and run it: ```
<?php
echo "<br />Locales availible on this server are:<br />";
system('locale -a'); // will list all locales availible on your server
echo "<hr><br />English locales availible on this server are:<br />";
system('locale -a | grep en'); // will list all locales that contains "en" availible on your server
?>
To find out your windows server's availible locales, see this article.
For more info on setlocale(), read the manual.