Hi Folk
I love the strtotime function, because I can make a date field in a form and
just tell my users to enter whatever they want and as long as it is a date,
it will work.
HOWEVER, this obviously does not work for the day/month vs month/day
scenario. That is, in New Zealand we use day/month/year, while the function
assumes it to be month/day/year.
Does anyone have a simple function that helps me close that loophole (I am
using PHP 4.4).
I copied the function below from php.net, but I dont think it will work in
all cases.
Cheers
> Nicolaas
# Returns a timestamp from a string based on the given format and default
timezone if it's ambiguous.
# %Y - year as a decimal number including the century
# %m - month as a decimal number (range 01 to 12)
# %d - day of the month as a decimal number (range 01 to 31)
# %H - hour as a decimal number using a 24-hour clock (range 00 to 23)
# %M - minute as a decimal number
function parseDate( $date, $format = "%d/%m/%Y") {
// Builds up date pattern from the given $format, keeping delimiters in
place.
if( !preg_match_all( "/%([YmdHMp])([^%])*/", $format, $formatTokens,
PREG_SET_ORDER ) ) {
return false;
}
foreach( $formatTokens as $formatToken ) {
$delimiter = preg_quote( $formatToken[2], "/" );
$datePattern .= "(.*)".$delimiter;
}
// Splits up the given $date
if( !preg_match( "/".$datePattern."/", $date, $dateTokens) ) {
return false;
}
$dateSegments = array();
for($i = 0; $i < count($formatTokens); $i++) {
$dateSegments[$formatTokens[$i][1]] = $dateTokens[$i+1];
}
// Reformats the given $date into US English date format, suitable for
strtotime()
if( $dateSegments["Y"] && $dateSegments["m"] && $dateSegments["d"] ) {
$dateReformated =
$dateSegments["Y"]."-".$dateSegments["m"]."-".$dateSegments["d"];
}
else {
return false;
}
if( $dateSegments["H"] && $dateSegments["M"] ) {
$dateReformated .= " ".$dateSegments["H"].":".$dateSegments["M"];
}
return strtotime( $dateReformated );
}
|
|
0
|
|
|
|
Reply
|
winandwaves (256)
|
4/25/2006 1:41:31 AM |
|
windandwaves wrote:
it could probably be as simple as writing a regular expression that changes
around anything like
11/12/2006 to 12/11/2006
and
11-12-2006 to 12-11-2006
and
27-05-2006 to 05-27-2006
but leaves
05-30-2006, because 30 > 12 and therefore is the day in the right place.
TIA
> Nicolaas
|
|
0
|
|
|
|
Reply
|
winandwaves (256)
|
4/25/2006 1:53:12 AM
|
|
windandwaves wrote:
> windandwaves wrote:
> it could probably be as simple as writing a regular expression that changes
> around anything like
> 11/12/2006 to 12/11/2006
> and
> 11-12-2006 to 12-11-2006
> and
> 27-05-2006 to 05-27-2006
> but leaves
> 05-30-2006, because 30 > 12 and therefore is the day in the right place.
>
> TIA
>
> > Nicolaas
There is no real way of knowing if someone ment Dec. or Nov. if they
enter 12/11/2006. I think your solution lies in providing seperate form
fields for day month and year, OR providing a key that says the desired
format (dd/mm/yyyy)
-Andy
|
|
0
|
|
|
|
Reply
|
lifesizeandrew (2)
|
4/25/2006 2:14:54 AM
|
|
windandwaves wrote:
This is what I came up with:
function eurostrtotime($d) {
// regular expression version
if
(preg_match('!(0[1-9]|[1-2]{1}[0-9]{1}|3[0-1]{1})/(0[1-9]{1}|1[0-2]{1})/(19[0-9]{1}[0-9]{1}|200[0-9]{1})!',
$d, $matches)) {
list(,$d,$m,$y) = $matches;
$ts = mktime(0,0,0,$m,$d,$y);
}
else {
$ts = strtotime($d);
}
return $ts;
}
Can anyone tell me how to include other formats in the regular expression.
Right now, it picks up 27/05/2006, but I would like it to include 27/05/06
and the like.
TIA
> Nicolaas
|
|
0
|
|
|
|
Reply
|
winandwaves (256)
|
4/25/2006 2:22:55 AM
|
|
lifesizeandrew@gmail.com wrote:
....
> There is no real way of knowing if someone ment Dec. or Nov. if they
> enter 12/11/2006.
....
There is, because all users are from New Zealand and in New Zealand no-one
in the right frame of mind would enter 12/11/2006 if they meant Dec 11 2006
and if they did then they would understand it was their mistake and enter it
correctly next time. On the other hand, if the web application would
interpret their date in the US format then they would be disappointed with
the site as it did not cater for the New Zealand format.
What I like about strtotime is that you do not have to have some set format.
You can just enter tomorrow, next week or whatever and it will pick it up.
I think that is just awesome!
Thanks for your reply.
> Nicolaas
|
|
0
|
|
|
|
Reply
|
winandwaves (256)
|
4/25/2006 2:30:00 AM
|
|
On Tue, 25 Apr 2006 13:41:31 +1200, windandwaves wrote:
> HOWEVER, this obviously does not work for the day/month vs month/day
> scenario. That is, in New Zealand we use day/month/year, while the function
> assumes it to be month/day/year.
Have you considered moving to Wyoming or Iowa? No waves there, but no
great white sharks, either. Alternatively, you can use PEAR::Date class
which contains different functions to format dates and time.
--
http://www.mgogala.com
|
|
0
|
|
|
|
Reply
|
gogala (1324)
|
4/25/2006 4:55:54 AM
|
|
windandwaves wrote:
> HOWEVER, this obviously does not work for the day/month vs month/day
> scenario. That is, in New Zealand we use day/month/year, while the function
> assumes it to be month/day/year.
Generally what I do is something like this (pseudo-code):
<?php
function mystrtotime($date)
{
if ($date is "??/??/??" || $date is "??-??-??")
{
list($d, $m, $y) = preg_split('/\/\-/', $date);
if ($y<70)
$y += 2000;
else
$y += 1900;
}
elseif ($date is "??/??/????" || $date is "??-??-????")
list($d, $m, $y) = preg_split('/\/\-/', $date);
if (isset($d))
$date = sprintf("%04d-%02d-%02d", $y, $m, $d);
return strtotime($date);
}
?>
I'll let you work out the regular expressions for the conditionals
yourself. :-)
--
Toby A Inkster BSc (Hons) ARCS
Contact Me ~ http://tobyinkster.co.uk/contact
|
|
0
|
|
|
|
Reply
|
usenet200604 (7)
|
4/25/2006 7:38:30 AM
|
|
windandwaves wrote:
> Hi Folk
>
> I love the strtotime function, because I can make a date field in a form
> and just tell my users to enter whatever they want and as long as it is a
> date, it will work.
>
> HOWEVER, this obviously does not work for the day/month vs month/day
> scenario. That is, in New Zealand we use day/month/year, while the
> function assumes it to be month/day/year.
And that's a pain, isn't it?
I always solve this problem in one of the following ways:
1) Ask the user 3 inputfields, day/month/year, or whatever order is
appropriate in some country.
2) Make my own datestring for the database-insert, or make my own date for
PHP purposes, which is easy once you know what field is what.
Alernatively, if you want to offer your visitor ONE field for a date, just
make sure YOU parse it the way it should be before using.
eg:
[html]
format: d/m/y
<input type="text" name="somedate">
[php]
$dateparts = split("/",$_POST["somedate"]);
// now reasssemble any way you want: eg:
DateForPostgres = $dateparts[1]."/"$dateparts[0]."/".$dateparts[2];
(assuming Postgres is set to take m/d/y dates.)
Regards,
Erwin Moller
>
> Does anyone have a simple function that helps me close that loophole (I am
> using PHP 4.4).
>
> I copied the function below from php.net, but I dont think it will work in
> all cases.
>
> Cheers
>
>> Nicolaas
> # Returns a timestamp from a string based on the given format and default
> timezone if it's ambiguous.
> # %Y - year as a decimal number including the century
> # %m - month as a decimal number (range 01 to 12)
> # %d - day of the month as a decimal number (range 01 to 31)
> # %H - hour as a decimal number using a 24-hour clock (range 00 to 23)
> # %M - minute as a decimal number
>
> function parseDate( $date, $format = "%d/%m/%Y") {
> // Builds up date pattern from the given $format, keeping delimiters in
> place.
> if( !preg_match_all( "/%([YmdHMp])([^%])*/", $format, $formatTokens,
> PREG_SET_ORDER ) ) {
> return false;
> }
> foreach( $formatTokens as $formatToken ) {
> $delimiter = preg_quote( $formatToken[2], "/" );
> $datePattern .= "(.*)".$delimiter;
> }
>
> // Splits up the given $date
> if( !preg_match( "/".$datePattern."/", $date, $dateTokens) ) {
> return false;
> }
> $dateSegments = array();
> for($i = 0; $i < count($formatTokens); $i++) {
> $dateSegments[$formatTokens[$i][1]] = $dateTokens[$i+1];
> }
>
> // Reformats the given $date into US English date format, suitable for
> strtotime()
> if( $dateSegments["Y"] && $dateSegments["m"] && $dateSegments["d"] ) {
> $dateReformated =
> $dateSegments["Y"]."-".$dateSegments["m"]."-".$dateSegments["d"];
> }
> else {
> return false;
> }
> if( $dateSegments["H"] && $dateSegments["M"] ) {
> $dateReformated .= " ".$dateSegments["H"].":".$dateSegments["M"];
> }
>
> return strtotime( $dateReformated );
> }
|
|
0
|
|
|
|
Reply
|
since_humans_read_this_I_am_spammed_too_much (2368)
|
4/25/2006 8:08:46 AM
|
|
> HOWEVER, this obviously does not work for the day/month vs month/day
> scenario. That is, in New Zealand we use day/month/year, while the function
> assumes it to be month/day/year.
Doesn't setlocale() sort this out? What locale is the server your using
running? I always thought strtotime() obeyed the current locale
settings, strftime() certainly does.
|
|
0
|
|
|
|
Reply
|
richard.a.fletcher (86)
|
4/25/2006 8:13:41 AM
|
|
Erwin Moller wrote:
[typocorrection]
$DateForPostgres = $dateparts[1]."/".$dateparts[0]."/".$dateparts[2];
|
|
0
|
|
|
|
Reply
|
since_humans_read_this_I_am_spammed_too_much (2368)
|
4/25/2006 8:23:29 AM
|
|
Toby Inkster wrote:
....
> I'll let you work out the regular expressions for the conditionals
> yourself. :-)
Thanks Toby, especially because that is the one thing I really suck at most.
Do you know the best way to learn regex? I have been looking on the net a
lot but never found a good tutorial.
Thanks again man!
> Nicolaas
|
|
0
|
|
|
|
Reply
|
winandwaves (256)
|
4/25/2006 10:19:37 PM
|
|
Mladen Gogala wrote:
> On Tue, 25 Apr 2006 13:41:31 +1200, windandwaves wrote:
>
>> HOWEVER, this obviously does not work for the day/month vs month/day
>> scenario. That is, in New Zealand we use day/month/year, while the
>> function assumes it to be month/day/year.
>
> Have you considered moving to Wyoming or Iowa? No waves there, but no
> great white sharks, either. Alternatively, you can use PEAR::Date
> class which contains different functions to format dates and time.
hmmm, i dont control the server ... so no Pear I think.
|
|
0
|
|
|
|
Reply
|
winandwaves (256)
|
4/26/2006 12:52:50 AM
|
|
windandwaves wrote:
> Mladen Gogala wrote:
>> On Tue, 25 Apr 2006 13:41:31 +1200, windandwaves wrote:
>>
>>> HOWEVER, this obviously does not work for the day/month vs month/day
>>> scenario. That is, in New Zealand we use day/month/year, while the
>>> function assumes it to be month/day/year.
>>
>> Have you considered moving to Wyoming or Iowa? No waves there, but no
>> great white sharks, either. Alternatively, you can use PEAR::Date
>> class which contains different functions to format dates and time.
>
> hmmm, i dont control the server ... so no Pear I think.
You can still download the PEAR libraries you require and put them in a
directory in your web tree (eg called 'pear') and then add that to your
include path. I've done this many times before for PEAR libraries that
a third party host does not have.
--
Chris Hope | www.electrictoolbox.com | www.linuxcdmall.com
|
|
0
|
|
|
|
Reply
|
blackhole11 (349)
|
4/26/2006 1:02:53 AM
|
|
Chris Hope wrote:
......
> You can still download the PEAR libraries you require and put them in
> a directory in your web tree (eg called 'pear') and then add that to
> your include path. I've done this many times before for PEAR
> libraries that a third party host does not have.
HMMMM, that is way cool! Thanks for that. Superuseful!
|
|
0
|
|
|
|
Reply
|
winandwaves (256)
|
4/26/2006 2:24:33 AM
|
|
On Tue, 25 Apr 2006 04:55:54 GMT, Mladen Gogala wrote:
>On Tue, 25 Apr 2006 13:41:31 +1200, windandwaves wrote:
>
>> HOWEVER, this obviously does not work for the day/month vs month/day
>> scenario. That is, in New Zealand we use day/month/year, while the function
>> assumes it to be month/day/year.
>
>Have you considered moving to Wyoming or Iowa? No waves there, but no
>great white sharks, either. Alternatively, you can use PEAR::Date class
>which contains different functions to format dates and time.
Aaah yes ... but are there any *sheep*???
Adam (also in NZ).
|
|
0
|
|
|
|
Reply
|
anon5262 (93)
|
4/27/2006 10:39:15 AM
|
|
On 25 Apr 2006 01:13:41 -0700, fletch wrote:
>> HOWEVER, this obviously does not work for the day/month vs month/day
>> scenario. That is, in New Zealand we use day/month/year, while the function
>> assumes it to be month/day/year.
>
>Doesn't setlocale() sort this out? What locale is the server your using
>running? I always thought strtotime() obeyed the current locale
>settings, strftime() certainly does.
Wouldn't you still have the problem of (let's say) US visitors
entering the date in the US format - regardless of the locale setting
on the server?
I tend to go for belt & braces - Erwin's 3-field solution. I just
create 3 (clearly labelled) drop-downs.
Adam.
|
|
0
|
|
|
|
Reply
|
anon5262 (93)
|
4/27/2006 10:44:00 AM
|
|
windandwaves wrote:
> Thanks Toby, especially because that is the one thing I really suck at most.
> Do you know the best way to learn regex? I have been looking on the net a
> lot but never found a good tutorial.
Google: "perlre".
--
Toby A Inkster BSc (Hons) ARCS
Contact Me ~ http://tobyinkster.co.uk/contact
|
|
0
|
|
|
|
Reply
|
usenet200604 (7)
|
4/30/2006 9:57:37 PM
|
|
Toby Inkster wrote:
> windandwaves wrote:
>
>> Thanks Toby, especially because that is the one thing I really suck
>> at most. Do you know the best way to learn regex? I have been
>> looking on the net a lot but never found a good tutorial.
>
> Google: "perlre".
Will do!
|
|
0
|
|
|
|
Reply
|
winandwaves (256)
|
4/30/2006 11:09:27 PM
|
|
> Wouldn't you still have the problem of (let's say) US visitors
> entering the date in the US format - regardless of the locale setting
> on the server?
Generally yes, but that was stated not to be a concern iirc
|
|
0
|
|
|
|
Reply
|
richard.a.fletcher (86)
|
5/2/2006 12:19:31 PM
|
|
|
18 Replies
13 Views
(page loaded in 0.238 seconds)
|