summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Bruederli <bruederli@kolabsys.com>2014-12-28 15:41:47 +0100
committerThomas Bruederli <bruederli@kolabsys.com>2014-12-28 15:41:47 +0100
commit09c58d1adde92a60a3e7cd67f4e66c8b1a56be6a (patch)
treeacf9a3ee67725804035c6d8bd5ae41d843343165
parentb737021a905a33c8eb4331692475cca7791e533c (diff)
Make rcube_utils::strtotime() timezone aware (#1490163)
-rw-r--r--program/lib/Roundcube/rcube_utils.php12
-rw-r--r--tests/Framework/Utils.php25
2 files changed, 33 insertions, 4 deletions
diff --git a/program/lib/Roundcube/rcube_utils.php b/program/lib/Roundcube/rcube_utils.php
index add97ee07..2e4aa323e 100644
--- a/program/lib/Roundcube/rcube_utils.php
+++ b/program/lib/Roundcube/rcube_utils.php
@@ -752,12 +752,14 @@ class rcube_utils
* 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 @@ class rcube_utils
// 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 @@ class rcube_utils
* 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 @@ class rcube_utils
}
// 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
diff --git a/tests/Framework/Utils.php b/tests/Framework/Utils.php
index 10c90fb2b..1cd9e7429 100644
--- a/tests/Framework/Utils.php
+++ b/tests/Framework/Utils.php
@@ -278,6 +278,7 @@ class Framework_Utils extends PHPUnit_Framework_TestCase
$test = array(
'1' => 1,
'' => 0,
+ 'abc-555' => 0,
'2013-04-22' => 1366581600,
'2013/04/22' => 1366581600,
'2013.04.22' => 1366581600,
@@ -286,6 +287,8 @@ class Framework_Utils extends PHPUnit_Framework_TestCase
'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 @@ class Framework_Utils extends PHPUnit_Framework_TestCase
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");
}
}