views:

218

answers:

4
+8  Q: 

English to Time

Does anyone know of a good class / library to convert English representations of time into timestamps?

The goal is to convert natural language phrases such as "ten years from now" and "three weeks" and "in 10 minutes" and working out a best match unix timestamp for them.

I have hacked up some pretty poor and untested code to get going on it, but I am sure there are great parsers out there for calendars and such.

private function timeparse($timestring)
{
    $candidate = @strtotime($timestring);
    if ($candidate > time()) return $candidate; // Let php have a bash at it

    //$thisyear = date("Y");
    if (strpos($timestring, "min") !== false) // Context is minutes
    {
            $nummins = preg_replace("/\D/", "", $timestring);
            $candidate = @strtotime("now +$nummins minutes");
            return $candidate;
    }

    if (strpos($timestring, "hou") !== false) // Context is hours
    {
            $numhours = preg_replace("/\D/", "", $timestring);
            $candidate = @strtotime("now +$numhours hours");
            return $candidate;
    }

    if (strpos($timestring, "day") !== false) // Context is days
    {
            $numdays = preg_replace("/\D/", "", $timestring);
            $candidate = @strtotime("now +$numdays days");
            return $candidate;
    }

    if (strpos($timestring, "year") !== false) // Context is years (2 years)
    {
            $numyears = preg_replace("/\D/", "", $timestring);
            $candidate = @strtotime("now +$numyears years");
            return $candidate;
    }

    if (strlen($timestring) < 5) // 10th || 2nd (or probably a number)
    {
            $day = preg_replace("/\D/", "", $timestring);
            if ($day > 0)
            {
                    $month = date("m");
                    $year = date("y");
                    return strtotime("$month/$day/$year");
            }
            else
            {
                    return false;
            }
    }

    return false; // No can do.
}
A: 

Cocoa's and GNUStep's NSDateFormatter are able to handle such time representations. The GNUStep version is open-source.

mouviciel
unlikely to help much given the php tag. doubt he's looking for cocoa libraries
Jonathan Fingland
I think the point that mouviciel is trying to make is that he can port the library to php.
Chris Gutierrez
Thank you for posting this. I appreciate this suggestion, but there is quite a large barrier to entry there, and I don't know how well it works and I am thus reluctant to invest time. I will look at it if I am unable to find another solution.
Antony Carthy
+2  A: 

Use the DateTime class.

e.g.:

$string='four days ago';
$d=date_create($string);
$d->getTimestamp();

ETA: which you could extend:

class myDateTime extends DateTime {
  static $defined_expressions=array(...);

  function __construct($expression=NULL) {
     if ($exp=$this->translate($expression)) {
       parent::__construct($exp); 
     }
  }

  function translate($exp) {
     //check to see if strtotime errors or not
     //if it errors, check if $exp matches a pattern in self::$defined_expressions
     return $exp, modified $exp or false
  }

}
dnagirl
It looks like this class just uses strtotime() which is not quite adequate or powerful enough...
Antony Carthy
It can take both strtotime and ISO8601 (using the constructor) phrases. What I've found dealing with natural language dates, is that you pretty much have to limit the syntax to a definable set. You might consider extending DateTime by defining a superset of expressions that you could map to standard PHP date expressions.
dnagirl
OK am giving this a try, thanks.
Antony Carthy
+1  A: 

Sometime ago I had come across http://www.timeapi.org which converts natural language queries into time. It is an API though.

The ruby source code is on github. If need be, I guess you could try to port it to PHP.

vsr
+1  A: 

Just got a notification from PHPClasses, with one of the runner-ups of the monthly innovation award: Text to Timestamp

You could try that...

Franz
Looking at it, it is very nice. You can even configure it and add other items yourself very easily...
Franz
After 20 minutes looking at the examples, I have no clue how to use it even if it does what I want... It looks as if the user is expected to add all the possible queries and map them to a time? "$obj->addTimer(time()-60*60*60, time(), '1 hour ago');"
Antony Carthy
Yeah, I admit, the documentation looks horrible. Nontheless, I believe there are a few default strings already "installed"...
Franz