Rewrite ereg() to preg_match()

In ancient times I wrote a small class, but now ereg() has been deprecated. Therefore I need to rewrite it using preg_match(), but I need a helping hand getting started.

The purpose of the class is to make it possible to input various date formats, but still be able to get correct date data. If you have other suggestions than rewriting the ereg() I am also listening.

Thank you in advance. (by the way there is a test case for the class at http://svn.intraface.dk/intrafacepublic/3Party/Ilib_Date/)


<?php
/**
 * Ilib_Date
 *
 * Takes dates in various formats and converts them to iso YYYY-mm-dd which
 * can be used in databases.
 *
 * <code>
 * $date = new Ilib_Date('10-10-2009');
 * $date = new Ilib_Date('10 10 2009');
 * $date = new Ilib_Date('10/10/2009');
 *
 * $date->converttodb();
 * $date->get(); // outputs 2009-10-10
 *
 * $date = new Ilib_Date('10-10');
 * $date->converttodb();
 * $date->get(); // outputs date('Y')-10-10
 * </code>
 *
 * PHP Version 5
 *
 * @package Ilib_Date
 * @author  Lars Olesen <lars@legestue.net>
 * @author  Sune Jensen <sj@sunet.dk>
 * @license MIT
 * @version 1.0.0
 *
 */
class Ilib_Date
{
    /**
     * @var string
     */
    private $date;

    /**
     * Constructor
     *
     * @param string $date Various date formats
     *
     * @return void
     */
    function __construct($date)
    {
        $this->date = $date;
    }

    /**
     * Converts date to db-format
     *
     * @param string $default_year Default year if current year will not work
     *
     * @return boolean
     */
    function convert2db($default_year = "")
    {
        // @todo Remember to edit both the validator an this class
        $d = "([0-3]?[0-9])";
        $m = "([0-1]?[0-9])";
        $y = "([0-9][0-9][0-9][0-9]|[0-9]?[0-9])";
        $s = "(-|\\.|/| )";

        if ($default_year == "") {
            $default_year = date("Y");
        }

        if (ereg("^".$d.$s.$m.$s.$y."$", $this->date, $parts)) {
            // true
        } elseif(ereg("^".$d.$s.$m."$", $this->date, $parts)) {
            $parts[5] = $default_year;
            // true
        } else {
            return false;
        }

        $this->date = $parts[5]."-".$parts[3]."-".$parts[1];
        return true;
    }

    /**
     * Gets the date
     *
     * @return string
     */
    function get()
    {
        return $this->date;
    }
}

Please show your updated class, the changes work fine on my end; 10-10 becomes 2010-10-10

Not true on both counts. The problem is that my suggestion removed a pair of parentheses, my mistake was assuming that the OP would see that and change the $parts keys to reflect the fewer capturing groups.

So, $parts[3] would become $parts[2] and $parts[5] would become $parts[3].

If I rewrite $s all of my tests fail.

That’s because the dot should be escaped and the space should be implemented as \s

$s = “[-\.\/\s]”;

$s = “(-|\.|\/| )”; could be simplified to $s = “[-.\/ ]”;

Also, if you haven’t already, you can read through the very thorough PCRE syntax description in the pattern syntax section of the PHP manual.

You were rigth. I missed a spot, so you suggestion worked. http://github.com/intraface/Ilib_Date/blob/master/src/Ilib/Date.php. Thank you for help.

If I change that this test will fail.


    function testDateCanAutomaticallyTakeYearIsConvertedToDatabaseFormat()
    {
        $date = new Ilib_Date('10-10');
        $this->assertTrue($date->convert2db());
        $this->assertEquals(date('Y') . '-10-10', $date->get());
    }

The regex is not directly parsable by preg_match(), as I get the following error: preg_match(): Unknown modifier ‘|’

The regex seems parsable by preg_match. As far as I can see this should work


preg_match("/^".$d.$s.$m.$s.$y."$/", $this->date, $parts);

And


ereg("/^".$d.$s.$m."$/", $this->date, $parts)

Note the /'s at the start and at the end of the regular expression.

P.S. I like the ([0-3]?[0-9]). I normally use \d{1,2}, but your approach is way better :slight_smile: (although it allows for > 31)
Maybe it should be /^(0?[1-9]|[1-2][0-9]|3[0-1])$/ , that only accepts number in the range 1-31.

I solved it by escaping /. The solution can be seen at http://svn.intraface.dk/intrafacepublic/3Party/Ilib_Date/src/Ilib/Date.php.