From 9fd853882c0aa2813be02a3382936994b7497fb4 Mon Sep 17 00:00:00 2001 From: David Stone Date: Sun, 13 Jan 2019 02:29:25 -0700 Subject: [PATCH] Fix error when timezone is an offset instead of an olson name. (#61) * Fix error when timezone is an offset instead of an olson name. intl returns the error "datefmt_create: no such time zone: '-05:00': U_ILLEGAL_ARGUMENT_ERROR" if a DateTime object is passed as the second parameter into the RRule constructor. IntlDateFormatter::create() needs the offset to be prefixed with GMT, go figure. --- src/RRule.php | 7 +++++-- tests/RRuleTest.php | 13 +++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/RRule.php b/src/RRule.php index a7f701b..c1dd3c2 100755 --- a/src/RRule.php +++ b/src/RRule.php @@ -2367,8 +2367,11 @@ class RRule implements RRuleInterface if ( ! $opt['date_formatter'] ) { if ( $opt['use_intl'] ) { $timezone = $this->dtstart->getTimezone()->getName(); - if ( $timezone == 'Z' ) { + + if ( $timezone === 'Z' ) { $timezone = 'GMT'; // otherwise IntlDateFormatter::create fails because... reasons. + } elseif ( preg_match( '/[-+]\d{2}/', $timezone ) ) { + $timezone = 'GMT'.$timezone; // otherwise IntlDateFormatter::create fails because... other reasons. } $formatter = \IntlDateFormatter::create( $opt['locale'], @@ -2377,7 +2380,7 @@ class RRule implements RRuleInterface $timezone ); if ( ! $formatter ) { - throw new \RuntimeException('IntlDateFormatter::create() failed (this should not happen, please open a bug report!)'); + throw new \RuntimeException('IntlDateFormatter::create() failed. Error Code: '.intl_get_error_code().' "'. intl_get_error_message().'" (this should not happen, please open a bug report!)'); } $opt['date_formatter'] = function($date) use ($formatter) { return $formatter->format($date); diff --git a/tests/RRuleTest.php b/tests/RRuleTest.php index dfbad9c..2a8ab85 100755 --- a/tests/RRuleTest.php +++ b/tests/RRuleTest.php @@ -2769,6 +2769,12 @@ class RRuleTest extends TestCase array('locale' => "en"), "daily, starting from 2/2/17, until 2/5/17" ), + array( + "RRULE:FREQ=DAILY;UNTIL=20190405T055959Z", + array('locale' => "en"), + "daily, starting from 1/10/19, until 4/5/19", + '2019-01-10T12:00:00-05:00' + ), array( "DTSTART:20170202T000000Z\nRRULE:FREQ=DAILY;UNTIL=20170205T000000Z", array('locale' => "en_IE"), @@ -2805,9 +2811,12 @@ class RRuleTest extends TestCase /** * @dataProvider humanReadableStrings */ - public function testHumanReadable($rrule,$options, $string) + public function testHumanReadable($rrule, $options, $string, $dtstart = null) { - $rrule = new RRule($rrule); + if ($dtstart) { + $dtstart = new DateTime($dtstart); + } + $rrule = new RRule($rrule, $dtstart); $this->assertEquals($string, $rrule->humanReadable($options)); } }