mirror of
https://github.com/e107inc/e107.git
synced 2025-08-03 13:17:24 +02:00
Merge pull request #4077 from Deltik/fix-4076
Have e_date::strptime() use eShims::strptime()
This commit is contained in:
64
e107_handlers/Shims/Internal/ReadfileTrait.php
Normal file
64
e107_handlers/Shims/Internal/ReadfileTrait.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/**
|
||||
* e107 website system
|
||||
*
|
||||
* Copyright (C) 2008-2020 e107 Inc (e107.org)
|
||||
* Released under the terms and conditions of the
|
||||
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt)
|
||||
*
|
||||
* Shims for PHP internal functions
|
||||
* readfile()
|
||||
*/
|
||||
|
||||
namespace e107\Shims\Internal;
|
||||
|
||||
trait ReadfileTrait
|
||||
{
|
||||
/**
|
||||
* Outputs a file
|
||||
*
|
||||
* Resilient replacement for PHP internal readfile()
|
||||
*
|
||||
* @see https://github.com/e107inc/e107/issues/3528 Why this method was implemented
|
||||
* @param string $filename The filename being read.
|
||||
* @param bool $use_include_path You can use the optional second parameter and set it to TRUE,
|
||||
* if you want to search for the file in the include_path, too.
|
||||
* @param resource $context A context stream resource.
|
||||
* @return int|bool Returns the number of bytes read from the file.
|
||||
* If an error occurs, FALSE is returned.
|
||||
*/
|
||||
public static function readfile($filename, $use_include_path = FALSE, $context = NULL)
|
||||
{
|
||||
$output = @readfile($filename, $use_include_path, $context);
|
||||
if ($output === NULL)
|
||||
{
|
||||
return self::readfile_alt($filename, $use_include_path, $context);
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a file
|
||||
*
|
||||
* Alternative implementation using file streams
|
||||
*
|
||||
* @param $filename
|
||||
* @param bool $use_include_path
|
||||
* @param resource $context
|
||||
* @return bool|int
|
||||
*/
|
||||
public static function readfile_alt($filename, $use_include_path = FALSE, $context = NULL)
|
||||
{
|
||||
// fopen() silently returns false if there is no context
|
||||
if (!is_resource($context)) $context = stream_context_create();
|
||||
|
||||
$handle = @fopen($filename, 'rb', $use_include_path, $context);
|
||||
if ($handle === FALSE) return FALSE;
|
||||
while (!feof($handle))
|
||||
{
|
||||
echo(fread($handle, 8192));
|
||||
}
|
||||
fclose($handle);
|
||||
return filesize($filename);
|
||||
}
|
||||
}
|
163
e107_handlers/Shims/Internal/StrptimeTrait.php
Normal file
163
e107_handlers/Shims/Internal/StrptimeTrait.php
Normal file
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
/**
|
||||
* e107 website system
|
||||
*
|
||||
* Copyright (C) 2008-2020 e107 Inc (e107.org)
|
||||
* Released under the terms and conditions of the
|
||||
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt)
|
||||
*
|
||||
* Shims for PHP internal functions
|
||||
* strptime()
|
||||
*/
|
||||
|
||||
namespace e107\Shims\Internal;
|
||||
|
||||
trait StrptimeTrait
|
||||
{
|
||||
/**
|
||||
* Parse a time/date generated with strftime()
|
||||
*
|
||||
* Resilient replacement for PHP internal strptime()
|
||||
*
|
||||
* @see https://www.php.net/manual/en/function.strptime.php what this function approximates
|
||||
* @param string $date The string to parse (e.g. returned from strftime()).
|
||||
* @param string $format The format used in date (e.g. the same as used in strftime()).
|
||||
* @return array|bool Returns FALSE on failure.
|
||||
* The following parameters are returned in the array:
|
||||
* "tm_sec" Seconds after the minute (0-61)
|
||||
* "tm_min" Minutes after the hour (0-59)
|
||||
* "tm_hour" Hour since midnight (0-23)
|
||||
* "tm_mday" Day of the month (1-31)
|
||||
* "tm_mon" Months since January (0-11)
|
||||
* "tm_year" Years since 1900
|
||||
* "tm_wday" Days since Sunday (0-6)
|
||||
* "tm_yday" Days since January 1 (0-365)
|
||||
* "unparsed" the date part which was not recognized using the specified format
|
||||
*/
|
||||
public static function strptime($date, $format)
|
||||
{
|
||||
$result = false;
|
||||
if (function_exists('strptime'))
|
||||
$result = strptime($date, $format);
|
||||
if (!is_array($result))
|
||||
$result = self::strptime_alt($date, $format);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a time/date generated with strftime()
|
||||
*
|
||||
* Alternative implementation based on public domain library:
|
||||
* https://github.com/Polycademy/upgradephp/
|
||||
*
|
||||
* @param string $date
|
||||
* @param string $format
|
||||
* @return array|bool
|
||||
*/
|
||||
public static function strptime_alt($date, $format)
|
||||
{
|
||||
static $expand = array('%D' => '%m/%d/%y', '%T' => '%H:%M:%S',);
|
||||
static $map_r = array(
|
||||
'%S' => 'tm_sec',
|
||||
'%M' => 'tm_min',
|
||||
'%H' => 'tm_hour',
|
||||
'%I' => 'tm_hour',
|
||||
'%d' => 'tm_mday',
|
||||
'%m' => 'tm_mon',
|
||||
'%Y' => 'tm_year',
|
||||
'%y' => 'tm_year',
|
||||
'%W' => 'tm_wday',
|
||||
'%D' => 'tm_yday',
|
||||
'%u' => 'unparsed',
|
||||
);
|
||||
|
||||
$fullmonth = array();
|
||||
$abrevmonth = array();
|
||||
|
||||
for ($i = 1; $i <= 12; $i++)
|
||||
{
|
||||
$k = strftime('%B', mktime(0, 0, 0, $i));
|
||||
$fullmonth[$k] = $i;
|
||||
|
||||
$j = strftime('%b', mktime(0, 0, 0, $i));
|
||||
$abrevmonth[$j] = $i;
|
||||
}
|
||||
|
||||
|
||||
#-- transform $format into extraction regex
|
||||
$format = str_replace(array_keys($expand), array_values($expand), $format);
|
||||
$preg = preg_replace('/(%\w)/', '(\w+)', preg_quote($format));
|
||||
|
||||
#-- record the positions of all STRFCMD-placeholders
|
||||
preg_match_all('/(%\w)/', $format, $positions);
|
||||
$positions = $positions[1];
|
||||
|
||||
$vals = array();
|
||||
|
||||
#-- get individual values
|
||||
if (preg_match("#$preg#", $date, $extracted))
|
||||
{
|
||||
#-- get values
|
||||
foreach ($positions as $pos => $strfc)
|
||||
{
|
||||
$v = $extracted[$pos + 1];
|
||||
#-- add
|
||||
if (isset($map_r[$strfc]))
|
||||
{
|
||||
$n = $map_r[$strfc];
|
||||
$vals[$n] = ($v > 0) ? (int)$v : $v;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!isset($vals['unparsed'])) $vals['unparsed'] = '';
|
||||
$vals['unparsed'] .= $v . ' ';
|
||||
}
|
||||
}
|
||||
|
||||
#-- fixup some entries
|
||||
//$vals["tm_wday"] = $names[ substr($vals["tm_wday"], 0, 3) ];
|
||||
if ($vals['tm_year'] >= 1900)
|
||||
{
|
||||
$vals['tm_year'] -= 1900;
|
||||
}
|
||||
elseif ($vals['tm_year'] > 0)
|
||||
{
|
||||
$vals['tm_year'] += 100;
|
||||
}
|
||||
|
||||
if ($vals['tm_mon'])
|
||||
{
|
||||
$vals['tm_mon'] -= 1;
|
||||
}
|
||||
|
||||
if (!isset($vals['tm_sec']))
|
||||
{
|
||||
$vals['tm_sec'] = 0;
|
||||
}
|
||||
|
||||
if (!isset($vals['tm_min']))
|
||||
{
|
||||
$vals['tm_min'] = 0;
|
||||
}
|
||||
|
||||
if (!isset($vals['tm_hour']))
|
||||
{
|
||||
$vals['tm_hour'] = 0;
|
||||
}
|
||||
|
||||
|
||||
if (!isset($vals['unparsed']))
|
||||
{
|
||||
$vals['unparsed'] = '';
|
||||
}
|
||||
|
||||
$unxTimestamp = mktime($vals['tm_hour'], $vals['tm_min'], $vals['tm_sec'], ($vals['tm_mon'] + 1), $vals['tm_mday'], ($vals['tm_year'] + 1900));
|
||||
|
||||
$vals['tm_wday'] = (int)strftime('%w', $unxTimestamp); // Days since Sunday (0-6)
|
||||
$vals['tm_yday'] = (strftime('%j', $unxTimestamp) - 1); // Days since January 1 (0-365)
|
||||
}
|
||||
|
||||
return !empty($vals) ? $vals : false;
|
||||
|
||||
}
|
||||
}
|
@@ -2,7 +2,7 @@
|
||||
/**
|
||||
* e107 website system
|
||||
*
|
||||
* Copyright (C) 2008-2018 e107 Inc (e107.org)
|
||||
* Copyright (C) 2008-2020 e107 Inc (e107.org)
|
||||
* Released under the terms and conditions of the
|
||||
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt)
|
||||
*
|
||||
|
@@ -2,7 +2,7 @@
|
||||
/**
|
||||
* e107 website system
|
||||
*
|
||||
* Copyright (C) 2008-2018 e107 Inc (e107.org)
|
||||
* Copyright (C) 2008-2020 e107 Inc (e107.org)
|
||||
* Released under the terms and conditions of the
|
||||
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt)
|
||||
*
|
||||
@@ -13,51 +13,6 @@ namespace e107\Shims;
|
||||
|
||||
trait InternalShimsTrait
|
||||
{
|
||||
/**
|
||||
* Outputs a file
|
||||
*
|
||||
* Resilient replacement for PHP internal readfile()
|
||||
*
|
||||
* @see https://github.com/e107inc/e107/issues/3528 Why this method was implemented
|
||||
* @param string $filename The filename being read.
|
||||
* @param bool $use_include_path You can use the optional second parameter and set it to TRUE,
|
||||
* if you want to search for the file in the include_path, too.
|
||||
* @param resource $context A context stream resource.
|
||||
* @return int|bool Returns the number of bytes read from the file.
|
||||
* If an error occurs, FALSE is returned.
|
||||
*/
|
||||
public static function readfile($filename, $use_include_path = FALSE, $context = NULL)
|
||||
{
|
||||
$output = @readfile($filename, $use_include_path, $context);
|
||||
if ($output === NULL)
|
||||
{
|
||||
return self::readfile_alt($filename, $use_include_path, $context);
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a file
|
||||
*
|
||||
* Alternative implementation using file streams
|
||||
*
|
||||
* @param $filename
|
||||
* @param bool $use_include_path
|
||||
* @param resource $context
|
||||
* @return bool|int
|
||||
*/
|
||||
public static function readfile_alt($filename, $use_include_path = FALSE, $context = NULL)
|
||||
{
|
||||
// fopen() silently returns false if there is no context
|
||||
if (!is_resource($context)) $context = stream_context_create();
|
||||
|
||||
$handle = @fopen($filename, 'rb', $use_include_path, $context);
|
||||
if ($handle === FALSE) return FALSE;
|
||||
while (!feof($handle))
|
||||
{
|
||||
echo(fread($handle, 8192));
|
||||
}
|
||||
fclose($handle);
|
||||
return filesize($filename);
|
||||
}
|
||||
use Internal\ReadfileTrait;
|
||||
use Internal\StrptimeTrait;
|
||||
}
|
@@ -770,184 +770,22 @@ class e_date
|
||||
|
||||
|
||||
/**
|
||||
* This work of Lionel SAURON (http://sauron.lionel.free.fr:80) is licensed under the
|
||||
* Creative Commons Attribution-Noncommercial-Share Alike 2.0 France License.
|
||||
* To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/2.0/fr/
|
||||
* or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
|
||||
*
|
||||
* http://snipplr.com/view/4964/emulate-php-5-for-backwards-compatibility/
|
||||
*
|
||||
* Parse a date generated with strftime().
|
||||
*
|
||||
* @author Lionel SAURON and reworked by e107 Inc. for month names.
|
||||
* @version 1.0
|
||||
* @public
|
||||
* Parse a time/date generated with strftime()
|
||||
* With extra output keys for localized month
|
||||
*
|
||||
* @deprecated Use eShims::strptime() instead
|
||||
* @see eShims::strptime()
|
||||
* @param string $str date string to parse (e.g. returned from strftime()).
|
||||
* @param $format
|
||||
* @return array|bool Returns an array with the <code>$str</code> parsed, or <code>false</code> on error.
|
||||
*/
|
||||
public function strptime($str, $format)
|
||||
{
|
||||
if(STRPTIME_COMPAT !== TRUE && function_exists('strptime')) // Unix Only.
|
||||
{
|
||||
$vals = strptime($str,$format); // PHP5 is more accurate than below.
|
||||
$vals['tm_amon'] = strftime('%b', mktime(0,0,0, $vals['tm_mon'] +1) );
|
||||
$vals['tm_fmon'] = strftime('%B', mktime(0,0,0, $vals['tm_mon'] +1) );
|
||||
return $vals;
|
||||
}
|
||||
|
||||
// Below is for Windows machines. (XXX TODO - Currently not as accurate as Linux PHP5 strptime() function above. )
|
||||
|
||||
static $expand = array('%D'=>'%m/%d/%y', '%T'=>'%H:%M:%S', );
|
||||
|
||||
$ampm = (preg_match("/%l|%I|%p|%P/",$format)) ? 'true' : 'false';
|
||||
|
||||
static $map_r = array(
|
||||
'%S' =>'tm_sec',
|
||||
'%M' =>'tm_min',
|
||||
'%H' =>'tm_hour',
|
||||
'%I' =>'tm_hour',
|
||||
'%d' =>'tm_mday',
|
||||
'%m' =>'tm_mon',
|
||||
'%Y' =>'tm_year',
|
||||
'%y' =>'tm_year',
|
||||
'%W' =>'tm_wday',
|
||||
'%D' =>'tm_yday',
|
||||
'%B' =>'tm_fmon', // full month-name
|
||||
'%b' =>'tm_amon', // abrev. month-name
|
||||
'%p' =>'tm_AMPM', // AM/PM
|
||||
'%P' =>'tm_ampm', // am/pm
|
||||
'%u' =>'unparsed',
|
||||
|
||||
);
|
||||
|
||||
$fullmonth = array();
|
||||
$abrevmonth = array();
|
||||
|
||||
for ($i = 1; $i <= 12; $i++)
|
||||
{
|
||||
$k = strftime('%B',mktime(0,0,0,$i));
|
||||
$fullmonth[$k] = $i;
|
||||
|
||||
$j = strftime('%b',mktime(0,0,0,$i));
|
||||
$abrevmonth[$j] = $i;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#-- transform $format into extraction regex
|
||||
$format = str_replace(array_keys($expand), array_values($expand), $format);
|
||||
$preg = preg_replace('/(%\w)/', '(\w+)', preg_quote($format));
|
||||
|
||||
#-- record the positions of all STRFCMD-placeholders
|
||||
preg_match_all('/(%\w)/', $format, $positions);
|
||||
$positions = $positions[1];
|
||||
|
||||
$vals = array();
|
||||
|
||||
#-- get individual values
|
||||
if (preg_match("#$preg#", $str, $extracted))
|
||||
{
|
||||
#-- get values
|
||||
foreach ($positions as $pos => $strfc)
|
||||
{
|
||||
$v = $extracted[$pos + 1];
|
||||
#-- add
|
||||
if (isset($map_r[$strfc]))
|
||||
{
|
||||
$n = $map_r[$strfc];
|
||||
$vals[$n] = ($v > 0) ? (int) $v : $v;
|
||||
}
|
||||
else
|
||||
{
|
||||
$vals['unparsed'] .= $v.' ';
|
||||
}
|
||||
}
|
||||
|
||||
#-- fixup some entries
|
||||
//$vals["tm_wday"] = $names[ substr($vals["tm_wday"], 0, 3) ];
|
||||
if ($vals['tm_year'] >= 1900)
|
||||
{
|
||||
$vals['tm_year'] -= 1900;
|
||||
}
|
||||
elseif ($vals['tm_year'] > 0)
|
||||
{
|
||||
$vals['tm_year'] += 100;
|
||||
}
|
||||
|
||||
if ($vals['tm_mon'])
|
||||
{
|
||||
$vals['tm_mon'] -= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if(isset($fullmonth[$vals['tm_fmon']]))
|
||||
{
|
||||
$vals['tm_mon'] = $fullmonth[$vals['tm_fmon']];
|
||||
}
|
||||
elseif(isset($abrevmonth[$vals['tm_amon']]))
|
||||
{
|
||||
$vals['tm_mon'] = $abrevmonth[$vals['tm_amon']];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if($ampm && isset($vals['tm_hour']))
|
||||
{
|
||||
if($vals['tm_hour'] == 12 && ($vals['tm_AMPM'] == 'AM' || $vals['tm_ampm'] == 'am'))
|
||||
{
|
||||
$vals['tm_hour'] = 0;
|
||||
}
|
||||
|
||||
if($vals['tm_hour'] < 12 && ($vals['tm_AMPM'] == 'PM' || $vals['tm_ampm'] == 'pm'))
|
||||
{
|
||||
$vals['tm_hour'] = intval($vals['tm_hour']) + 12;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//$vals['tm_sec'] -= 1; always increasing tm_sec + 1 ??????
|
||||
|
||||
#-- calculate wday/yday
|
||||
//$vals['tm_mon'] = $vals['tm_mon'] + 1; // returns months from 0 - 11 so we need to +1
|
||||
|
||||
if (!isset($vals['tm_sec']))
|
||||
{
|
||||
$vals['tm_sec'] = 0;
|
||||
}
|
||||
|
||||
if (!isset($vals['tm_min']))
|
||||
{
|
||||
$vals['tm_min'] = 0;
|
||||
}
|
||||
|
||||
if (!isset($vals['tm_hour']))
|
||||
{
|
||||
$vals['tm_hour'] = 0;
|
||||
}
|
||||
|
||||
|
||||
if (!isset($vals['unparsed']))
|
||||
{
|
||||
$vals['unparsed'] = '';
|
||||
}
|
||||
|
||||
$unxTimestamp = mktime($vals['tm_hour'], $vals['tm_min'], $vals['tm_sec'], ($vals['tm_mon'] + 1), $vals['tm_mday'], ($vals['tm_year'] + 1900));
|
||||
|
||||
$vals['tm_amon'] = strftime('%b', mktime($vals['tm_hour'], $vals['tm_min'], $vals['tm_sec'], $vals['tm_mon'] + 1));
|
||||
$vals['tm_fmon'] = strftime('%B', mktime($vals['tm_hour'], $vals['tm_min'], $vals['tm_sec'], $vals['tm_mon'] + 1));
|
||||
$vals['tm_wday'] = (int) strftime('%w', $unxTimestamp); // Days since Sunday (0-6)
|
||||
$vals['tm_yday'] = (strftime('%j', $unxTimestamp) - 1); // Days since January 1 (0-365)
|
||||
|
||||
|
||||
//var_dump($vals, $str, strftime($format, $unxTimestamp), $unxTimestamp);
|
||||
}
|
||||
|
||||
return !empty($vals) ? $vals : false;
|
||||
|
||||
}
|
||||
$vals = eShims::strptime($str, $format); // PHP5 is more accurate than below.
|
||||
$vals['tm_amon'] = strftime('%b', mktime(0, 0, 0, $vals['tm_mon'] + 1));
|
||||
$vals['tm_fmon'] = strftime('%B', mktime(0, 0, 0, $vals['tm_mon'] + 1));
|
||||
return $vals;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@@ -26,17 +26,12 @@ if (!defined('e107_INIT'))
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
if (!function_exists('strptime'))
|
||||
{
|
||||
|
||||
define('STRPTIME_COMPAT', true);
|
||||
function strptime($str, $format)
|
||||
function strptime($date, $format)
|
||||
{
|
||||
return e107::getDate()->strptime($str,$format);
|
||||
}
|
||||
|
||||
return eShims::strptime($date, $format);
|
||||
}
|
||||
}
|
||||
|
||||
//PHP < 5.2 compatibility
|
||||
|
94
e107_tests/tests/unit/e107/Shims/StrptimeTest.php
Normal file
94
e107_tests/tests/unit/e107/Shims/StrptimeTest.php
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
/**
|
||||
* e107 website system
|
||||
*
|
||||
* Copyright (C) 2008-2020 e107 Inc (e107.org)
|
||||
* Released under the terms and conditions of the
|
||||
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt)
|
||||
*
|
||||
*/
|
||||
|
||||
namespace e107\Shims;
|
||||
|
||||
class StrptimeTest extends \Codeception\Test\Unit
|
||||
{
|
||||
public function testStrptimeDefault()
|
||||
{
|
||||
$this->testStrptimeImplementation([\e107\Shims\InternalShims::class, 'strptime']);
|
||||
}
|
||||
|
||||
public function testStrptimeDefaultLegacy()
|
||||
{
|
||||
$this->testStrptimeImplementation([\eShims::class, 'strptime']);
|
||||
}
|
||||
|
||||
public function testStrptimeAlt()
|
||||
{
|
||||
$this->testStrptimeImplementation([\e107\Shims\InternalShims::class, 'strptime_alt']);
|
||||
}
|
||||
|
||||
protected function testStrptimeImplementation($implementation)
|
||||
{
|
||||
$this->testStrptimeDateOnly($implementation);
|
||||
$this->testStrptimeDateTime($implementation);
|
||||
$this->testStrptimeUnparsed($implementation);
|
||||
$this->testStrptimeInvalid($implementation);
|
||||
}
|
||||
|
||||
protected function testStrptimeDateOnly($implementation)
|
||||
{
|
||||
$actual = call_user_func($implementation, '2018/05/13', '%Y/%m/%d');
|
||||
$expected = array(
|
||||
'tm_year' => 118,
|
||||
'tm_mon' => 4,
|
||||
'tm_mday' => 13,
|
||||
'tm_sec' => 0,
|
||||
'tm_min' => 0,
|
||||
'tm_hour' => 0,
|
||||
'unparsed' => '',
|
||||
'tm_wday' => 0,
|
||||
'tm_yday' => 132,
|
||||
);
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
protected function testStrptimeDateTime($implementation)
|
||||
{
|
||||
$actual = call_user_func($implementation, '2018/05/13 20:10', '%Y/%m/%d %H:%M');
|
||||
$expected = array(
|
||||
'tm_year' => 118,
|
||||
'tm_mon' => 4,
|
||||
'tm_mday' => 13,
|
||||
'tm_hour' => 20,
|
||||
'tm_min' => 10,
|
||||
'tm_sec' => 0,
|
||||
'unparsed' => '',
|
||||
'tm_wday' => 0,
|
||||
'tm_yday' => 132,
|
||||
);
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
protected function testStrptimeUnparsed($implementation)
|
||||
{
|
||||
$actual = call_user_func($implementation, '1607-09-04 08:10 PM', '%Y-%m-%d %l:%M %P');
|
||||
$expected = array(
|
||||
'tm_year' => 1707,
|
||||
'tm_mon' => 8,
|
||||
'tm_mday' => 4,
|
||||
'tm_hour' => 0,
|
||||
'tm_min' => 10,
|
||||
'tm_sec' => 0,
|
||||
'unparsed' => '08 PM ',
|
||||
'tm_wday' => 2,
|
||||
'tm_yday' => 246,
|
||||
);
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
protected function testStrptimeInvalid($implementation)
|
||||
{
|
||||
$actual = call_user_func($implementation, 'garbage', '%Y-%m-%d');
|
||||
$this->assertFalse($actual);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user