i love strtotime but it is no use in New Zealand

  • Follow


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)


Reply: