Deconstructing dates

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
kdidymus
Forum Contributor
Posts: 196
Joined: Tue May 13, 2008 3:37 am

Deconstructing dates

Post by kdidymus »

Long time no post. Things have been going well.

I have something I'm stuck with.

My genealogy website uses full dates of birth (i.e. Wednesday 4th September 1975). These are manually entered in to the MySQL database and have been since the start so it's not an option for me to change them all to a DD-MM-YYYY format now.

What I WANT to be able to do is write a PHP script that will deconstruct the dates and give me an output which is in the DD-MM-YYYY format.

I tried the following as a starter (this is just a test code, usually the date of birth is acquired from MySQL as $dateofbirth):

Code: Select all

$dateofbirth = "Wednesday 4th September 1975";
$date1 = trim($dateofbirth, "Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday");
$date2 = trim($date1, "st,nd,rd,th");
This successfully gets rid of the day and gives me 4th September 1975. For some reason it doesn't get rid of the st, nd, rd or th suffixes.

Can anybody take this a stage further and suggest a way of writing a code that will take a full date and convert it to a more code-friendly format?

And whilst I'm on, I need to build in the ability to handle dates of birth entered as:

(Q1) 1975
c.1975 and
1975

Any ideas

Many, MANY thanks in advance.

Kris.
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Deconstructing dates

Post by VladSun »

Try using strtotime() to extract the dates then use date() to format them the way you want.
There are 10 types of people in this world, those who understand binary and those who don't
kdidymus
Forum Contributor
Posts: 196
Joined: Tue May 13, 2008 3:37 am

Re: Deconstructing dates

Post by kdidymus »

Got ya. Looks good. HOWEVER, alot of the people listed on my site were born BEFORE 1970.

This is my script:

Code: Select all

$dateofbirth = "Saturday 4th February 1888";
$date = strtotime($dateofbirth);
$date1 = date('d-m-Y',$date);
echo "$date1";
This returns 01-01-1970 so the theory is great but the reality is that strtotime() isn't flexible enough.


Aaaargh!
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Deconstructing dates

Post by VladSun »

Right :)
Probably a regexp would do a better job then:

Code: Select all

$s = 'Wednesday 4th September 1805';
 
preg_match('/^(\w+)\s+(\d{1,2})\w*\s+(\w+)\s+(\d{4})/', $s, $matches);
print_r($matches);
=>

Code: Select all

Array
(
    [0] => Wednesday 4th September 1805
    [1] => Wednesday
    [2] => 4
    [3] => September
    [4] => 1805
)
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Deconstructing dates

Post by VladSun »

Or without regexp:

Code: Select all

$s = 'Wednesday 4th September 1805';
 
$matches = explode(' ', $s);
$matches[1] = intval($matches[1]);
$matches[3] = intval($matches[3]);
 
print_r($matches);
There are 10 types of people in this world, those who understand binary and those who don't
kdidymus
Forum Contributor
Posts: 196
Joined: Tue May 13, 2008 3:37 am

Re: Deconstructing dates

Post by kdidymus »

Thank you.

I'm NEARLY there. So now my code looks like this:

Code: Select all

$dateofbirth = "Saturday 4th February 1888";
preg_match('/^(\w+)\s+(\d{1,2})\w*\s+(\w+)\s+(\d{4})/', $dateofbirth, $matches);
$date = $matches[2];
$mnth = $matches[3];
$year = $matches[4];
if ($mnth == "January")
{$month = "01";}
elseif ($mnth == "February")
{$month = "02";}
elseif ($mnth == "March")
{$month = "03";}
elseif ($mnth == "April")
{$month = "04";}
elseif ($mnth == "May")
{$month = "05";}
elseif ($mnth == "June")
{$month = "06";}
elseif ($mnth == "July")
{$month = "07";}
elseif ($mnth == "August")
{$month = "08";}
elseif ($mnth == "September")
{$month = "09";}
elseif ($mnth == "October")
{$month = "10";}
elseif ($mnth == "November")
{$month = "11";}
elseif ($mnth == "December")
{$month = "12";}
$dateborn = "$date-$month-$year";
echo "$dateborn";
Is there a shorter version of this?!
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Deconstructing dates

Post by VladSun »

Yes, construct a map object - an array with "month-name" keys, and values - their numerical representation.

Or use a switch/case statement
There are 10 types of people in this world, those who understand binary and those who don't
kdidymus
Forum Contributor
Posts: 196
Joined: Tue May 13, 2008 3:37 am

Re: Deconstructing dates

Post by kdidymus »

Not an expert at this so it's taken me several hours. This is the code I've come up with as a test...
<?php

$dateofbirth = "Monday 4th September 1975";
$dateofdeath = "Wednesday 5th September 1980";

//AGE RELATED ALGORITHMS

if ($dateofbirth == "")
{$deathform = "none";}
elseif (strlen($dateofbirth) < 9)
{$birthform = "yearonly";}
elseif (strlen($dateofbirth) > 10)
{$birthform = "fulldate";}

if ($dateofdeath == "")
{$deathform = "none";}
elseif (strlen($dateofdeath) < 9)
{$deathform = "yearonly";}
elseif (strlen($dateofdeath) > 10)
{$deathform = "fulldate";}

if ($birthform == "none" && $deathform == "none")
{$ageatdeath = "";}

elseif ($birthform == "yearonly" && $deathform == "none")
{$ageatdeath = "";}

elseif ($birthform == "none" && $deathform == "yearonly")
{$ageatdeath = "";}

elseif ($birthform == "yearonly" && $deathform == "yearonly")
{
$birthtrim = substr($dateofbirth, -4);
$deathtrim = substr($dateofdeath, -4);
$ageatdeath = "(aged approx. $deathtrim - $birthtrim years)";
}

elseif ($birthform == "fulldate" && $deathform == "fulldate")
{
$birthcode = explode(' ', $dateofbirth);
$birthdte = intval($birthcode[1]);
$birthmth = $birthcode[2];
$birthyer = intval($birthcode[3]);
switch (true){
case ($birthmth==="January"): $birthmnth="1"; break;
case ($birthmth==="February"): $birthmnth="2"; break;
case ($birthmth==="March"): $birthmnth="3"; break;
case ($birthmth==="April"): $birthmnth="4"; break;
case ($birthmth==="May"): $birthmnth="5"; break;
case ($birthmth==="June"): $birthmnth="6"; break;
case ($birthmth==="July"): $birthmnth="7"; break;
case ($birthmth==="August"): $birthmnth="8"; break;
case ($birthmth==="September"): $birthmnth="9"; break;
case ($birthmth==="October"): $birthmnth="10"; break;
case ($birthmth==="November"): $birthmnth="11"; break;
case ($birthmth==="December"): $birthmnth="12"; break;
}
$deathcode = explode(' ', $dateofdeath);
$deathdte = intval($deathcode[1]);
$deathmth = $deathcode[2];
$deathyer = intval($deathcode[3]);
switch (true){
case ($deathmth==="January"): $deathmnth="1"; break;
case ($deathmth==="February"): $deathmnth="2"; break;
case ($deathmth==="March"): $deathmnth="3"; break;
case ($deathmth==="April"): $deathmnth="4"; break;
case ($deathmth==="May"): $deathmnth="5"; break;
case ($deathmth==="June"): $deathmnth="6"; break;
case ($deathmth==="July"): $deathmnth="7"; break;
case ($deathmth==="August"): $deathmnth="8"; break;
case ($deathmth==="September"): $deathmnth="9"; break;
case ($deathmth==="October"): $deathmnth="10"; break;
case ($deathmth==="November"): $deathmnth="11"; break;
case ($deathmth==="December"): $deathmnth="12"; break;
}
$diedaged = $deathyer - $birthyer;
if (($deathmnth < $birthmnth) || ($deathmnth == $birthmnth && $deathdte < $birthdte))
{
$diedaged--;
$ageatdeath = "(aged $diedaged years)";
}
}
else
{break;}
echo "$ageatdeath";
?>
But when I put this on-line and access it in my browser, there are no errors BUT nothing happens either. Just a blank screen. Anybody help with what I'm doing wrong?

TIA.

KD.
kdidymus
Forum Contributor
Posts: 196
Joined: Tue May 13, 2008 3:37 am

Re: Deconstructing dates

Post by kdidymus »

Solved it. I made a schoolboy error and forgot to provide an "else" argument for the last section. The finished code is:

Code: Select all

<?php
 
$dateofbirth = "Monday 4th September 1975";
$dateofdeath = "Wednesday 5th September 1980";
 
//AGE RELATED ALGORITHMS
 
if ($dateofbirth == "")
{$birthform = "none";}
elseif (strlen($dateofbirth) < 9)
{$birthform = "yearonly";}
elseif (strlen($dateofbirth) > 10)
{$birthform = "fulldate";}
 
if ($dateofdeath == "")
{$deathform = "none";}
elseif (strlen($dateofdeath) < 9)
{$deathform = "yearonly";}
elseif (strlen($dateofdeath) > 10)
{$deathform = "fulldate";}
 
if ($birthform == "none" && $deathform == "none")
{$ageatdeath = "";}
 
elseif ($birthform == "yearonly" && $deathform == "none")
{$ageatdeath = "";}
 
elseif ($birthform == "none" && $deathform == "yearonly")
{$ageatdeath = "";}
 
elseif ($birthform == "yearonly" && $deathform == "yearonly")
{
$birthtrim = substr($dateofbirth, -4);
$deathtrim = substr($dateofdeath, -4);
$ageatdeath = "(aged approx. $deathtrim - $birthtrim years)";
}
 
elseif ($birthform == "yearonly" && $deathform == "fulldate")
{
$birthtrim = substr($dateofbirth, -4);
$deathtrim = substr($dateofdeath, -4);
$ageatdeath = "(aged approx. $deathtrim - $birthtrim years)";
}
 
elseif ($birthform == "fulldate" && $deathform == "yearonly")
{
$birthtrim = substr($dateofbirth, -4);
$deathtrim = substr($dateofdeath, -4);
$ageatdeath = "(aged approx. $deathtrim - $birthtrim years)";
}
 
elseif ($birthform == "fulldate" && $deathform == "fulldate")
{
$birthcode = explode(' ', $dateofbirth);
$birthdte = intval($birthcode[1]);
$birthmth = $birthcode[2];
$birthyer = intval($birthcode[3]);
switch (true){ 
case ($birthmth==="January"): $birthmnth="1"; break;
case ($birthmth==="February"): $birthmnth="2"; break;
case ($birthmth==="March"): $birthmnth="3"; break;
case ($birthmth==="April"): $birthmnth="4"; break;
case ($birthmth==="May"): $birthmnth="5"; break;
case ($birthmth==="June"): $birthmnth="6"; break;
case ($birthmth==="July"): $birthmnth="7"; break;
case ($birthmth==="August"): $birthmnth="8"; break;
case ($birthmth==="September"): $birthmnth="9"; break;
case ($birthmth==="October"): $birthmnth="10"; break;
case ($birthmth==="November"): $birthmnth="11"; break;
case ($birthmth==="December"): $birthmnth="12"; break;
}
$deathcode = explode(' ', $dateofdeath);
$deathdte = intval($deathcode[1]);
$deathmth = $deathcode[2];
$deathyer = intval($deathcode[3]);
switch (true){ 
case ($deathmth==="January"): $deathmnth="1"; break;
case ($deathmth==="February"): $deathmnth="2"; break;
case ($deathmth==="March"): $deathmnth="3"; break;
case ($deathmth==="April"): $deathmnth="4"; break;
case ($deathmth==="May"): $deathmnth="5"; break;
case ($deathmth==="June"): $deathmnth="6"; break;
case ($deathmth==="July"): $deathmnth="7"; break;
case ($deathmth==="August"): $deathmnth="8"; break;
case ($deathmth==="September"): $deathmnth="9"; break;
case ($deathmth==="October"): $deathmnth="10"; break;
case ($deathmth==="November"): $deathmnth="11"; break;
case ($deathmth==="December"): $deathmnth="12"; break;
}
$diedaged = $deathyer - $birthyer;
 if (($deathmnth < $birthmnth) || ($deathmnth == $birthmnth && $deathdte < $birthdte))
 {
$diedaged--;
$ageatdeath = "(aged $diedaged years)";
}
else
{$ageatdeath = "(aged $diedaged years)";
}
}
else
{break;}
echo "$ageatdeath";
?>
This may be helpful to others trying to achieve the same result as I was.

Thanks to you all for your help.

KD.
Post Reply