Thomas Bruederli
2014-12-28 09c58d1adde92a60a3e7cd67f4e66c8b1a56be6a
Make rcube_utils::strtotime() timezone aware (#1490163)
2 files modified
37 ■■■■ changed files
program/lib/Roundcube/rcube_utils.php 12 ●●●● patch | view | raw | blame | history
tests/Framework/Utils.php 25 ●●●●● patch | view | raw | blame | history
program/lib/Roundcube/rcube_utils.php
@@ -752,12 +752,14 @@
     * Improved equivalent to strtotime()
     *
     * @param string $date  Date string
     * @param object DateTimeZone to use for DateTime object
     *
     * @return int Unix timestamp
     */
    public static function strtotime($date)
    public static function strtotime($date, $timezone = null)
    {
        $date = self::clean_datestr($date);
        $tzname = $timezone ? ' ' . $timezone->getName() : '';
        // unix timestamp
        if (is_numeric($date)) {
@@ -766,7 +768,7 @@
        // if date parsing fails, we have a date in non-rfc format.
        // remove token from the end and try again
        while ((($ts = @strtotime($date)) === false) || ($ts < 0)) {
        while ((($ts = @strtotime($date . $tzname)) === false) || ($ts < 0)) {
            $d = explode(' ', $date);
            array_pop($d);
            if (!$d) {
@@ -782,6 +784,7 @@
     * Date parsing function that turns the given value into a DateTime object
     *
     * @param string $date  Date string
     * @param object DateTimeZone to use for DateTime object
     *
     * @return object DateTime instance or false on failure
     */
@@ -805,9 +808,12 @@
        }
        // try our advanced strtotime() method
        if (!$dt && ($timestamp = self::strtotime($date))) {
        if (!$dt && ($timestamp = self::strtotime($date, $timezone))) {
            try {
                $dt = new DateTime("@".$timestamp);
                if ($timezone) {
                    $dt->setTimezone($timezone);
                }
            }
            catch (Exception $e) {
                // ignore
tests/Framework/Utils.php
@@ -278,6 +278,7 @@
        $test = array(
            '1' => 1,
            '' => 0,
            'abc-555' => 0,
            '2013-04-22' => 1366581600,
            '2013/04/22' => 1366581600,
            '2013.04.22' => 1366581600,
@@ -286,6 +287,8 @@
            '22.04.2013' => 1366581600,
            '22.4.2013'  => 1366581600,
            '20130422'   => 1366581600,
            '2013/06/21 12:00:00 UTC' => 1371816000,
            '2013/06/21 12:00:00 Europe/Berlin' => 1371808800,
        );
        foreach ($test as $datetime => $ts) {
@@ -316,7 +319,27 @@
        foreach ($test as $datetime => $ts) {
            $result = rcube_utils::anytodatetime($datetime);
            $this->assertSame($ts, $result ? $result->format('Y-m-d') : '', "Error parsing date: $datetime");
            $this->assertSame($ts, $result ? $result->format('Y-m-d') : false, "Error parsing date: $datetime");
        }
    }
    /**
     * rcube:utils::anytodatetime()
     */
    function test_anytodatetime_timezone()
    {
        $tz = new DateTimeZone('Europe/Helsinki');
        $test = array(
            'Jan 1st 2014 +0800' => '2013-12-31 18:00',  // result in target timezone
            'Jan 1st 14 45:42'   => '2014-01-01 00:00',  // force fallback to rcube_utils::strtotime()
            'Jan 1st 2014 UK'    => '2014-01-01 00:00',
            'Invalid date'       => false,
        );
        foreach ($test as $datetime => $ts) {
            $result = rcube_utils::anytodatetime($datetime, $tz);
            if ($result) $result->setTimezone($tz);  // move to target timezone for comparison
            $this->assertSame($ts, $result ? $result->format('Y-m-d H:i') : false, "Error parsing date: $datetime");
        }
    }