Skip to content

Commit

Permalink
Merge pull request #137 from alexdebril/issue/134
Browse files Browse the repository at this point in the history
Issue/134
  • Loading branch information
alexdebril authored Aug 4, 2017
2 parents e7a3ff3 + bb742ca commit e4a74d8
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 5 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,18 @@ $feedIo = new FeedIo($client, $logger);

```

## Dealing with missing timezones

Sometimes you have to consume feeds in which the timezone is missing from the dates. In some use-cases, you may need to specify the feed's timezone to get an accurate value, so feed-io offers a workaround for that :

```php
$feedIo->getDateTimeBuilder()->setFeedTimezone(new \DateTimeZone($feedTimezone));
$result = $feedIo->read($feedUrl);
$feedIo->getDateTimeBuilder()->resetFeedTimezone();
```

Don't forget to reset `feedTimezone` after fetching the result, or you'll end up with all feeds located in the same timezone.

## Online documentation and API reference

The whole documentation and API reference is available at https://feed-io.net/documentation.html
44 changes: 44 additions & 0 deletions examples/force-timezone.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php
/*
* This file is part of the feed-io package.
*
* (c) Alexandre Debril <alex.debril@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

require __DIR__.DIRECTORY_SEPARATOR.'bootstrap.php';

$feedIo = \FeedIo\Factory::create()->getFeedIo();

$feedIo->getDateTimeBuilder()->setFeedTimezone(new \DateTimeZone('-0500'));
$result = $feedIo->read('http://news.php.net/group.php?group=php.announce&format=rss');

echo "First item's pubDate raw value in the feed" .PHP_EOL;

$domItems = $result->getDocument()->getDOMDocument()->getElementsByTagName('item');

/** @var \DOMElement $firstDomItem */
$firstDomItem = $domItems->item(0);
$pubDate = $firstDomItem->getElementsByTagName('pubDate')->item(0);

var_dump($pubDate->nodeValue);

$pubDateTime = new \DateTime($pubDate->nodeValue);

echo "here is its timestamp : {$pubDateTime->getTimestamp()}" . PHP_EOL;

$feed = $result->getFeed();

/** @var \FeedIo\Feed\ItemInterface $item */
$feed->rewind();
$item = $feed->current();

echo "var_dump the first item's pubDate after parsing. It's the same date converted in your local configuration's timezone" . PHP_EOL;
var_dump($item->getLastModified());
echo "here is its timestamp : {$item->getLastModified()->getTimestamp()}" . PHP_EOL;

if($pubDateTime->getTimestamp() === $item->getLastModified()->getTimestamp()) {
echo "HOURAY, both timestamps match !" . PHP_EOL;
}
39 changes: 39 additions & 0 deletions examples/missing-timezone.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php
/*
* This file is part of the feed-io package.
*
* (c) Alexandre Debril <alex.debril@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

require __DIR__.DIRECTORY_SEPARATOR.'bootstrap.php';

echo 'see https://github.com/alexdebril/feed-io/issues/134 for full explanations' . PHP_EOL;

$dateTimeBuilder = new \FeedIo\Rule\DateTimeBuilder();
$pubDate = 'Wed, 02 Aug 2017 07:21:29';

echo 'the publish date\'s timezone is America/chicago but $dateTimeBuilder ignores it. The date below is wrong' . PHP_EOL;

$dateTime = $dateTimeBuilder->convertToDateTime($pubDate);

var_dump($dateTime);
echo "timestamp : {$dateTime->getTimestamp()}" . PHP_EOL;

echo 'after setting the feed\'s timezone in the builder\'s attributes, the date is right' . PHP_EOL;

$dateTimeBuilder->setFeedTimezone(new \DateTimeZone('America/Chicago'));

$dateTime = $dateTimeBuilder->convertToDateTime($pubDate);

var_dump($dateTime);
echo "timestamp : {$dateTime->getTimestamp()}" . PHP_EOL;

echo 'if I really want the date in its original timezone, I can set it' . PHP_EOL;

$dateTime->setTimezone(new \DateTimeZone('America/Chicago'));

var_dump($dateTime);
echo "timestamp : {$dateTime->getTimestamp()}" . PHP_EOL;
72 changes: 67 additions & 5 deletions src/FeedIo/Rule/DateTimeBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,12 @@ class DateTimeBuilder
/**
* @var \DateTimeZone
*/
protected $timezone;
protected $feedTimezone;

/**
* @var \DateTimeZone
*/
protected $serverTimezone;

/**
* @var LoggerInterface
Expand Down Expand Up @@ -121,7 +126,7 @@ public function convertToDateTime($string)
{
$string = trim($string);
foreach ([$this->getLastGuessedFormat(), $this->guessDateFormat($string) ] as $format) {
$date = \DateTime::createFromFormat($format, $string);
$date = $this->newDate($format, $string);
if ($date instanceof \DateTime) {
$date->setTimezone($this->getTimezone());

Expand All @@ -145,25 +150,82 @@ public function stringToDateTime($string)
if (false === strtotime($string)) {
throw new \InvalidArgumentException('Impossible to convert date : '.$string);
}
$date = new \DateTime($string);
$date = new \DateTime($string, $this->getFeedTimezone());
$date->setTimezone($this->getTimezone());

return $date;
}

/**
* @return \DateTimeZone
*/
public function getFeedTimezone()
{
return $this->feedTimezone;
}

/**
* Specifies the feed's timezone. Do this it the timezone is missing
*
* @param \DateTimeZone $timezone
*/
public function setFeedTimezone(\DateTimeZone $timezone)
{
$this->feedTimezone = $timezone;
}

/**
* Resets feedTimezone to null.
*/
public function resetFeedTimezone()
{
$this->feedTimezone = null;
}

/**
* @return \DateTimeZone
*/
public function getServerTimezone()
{
return $this->serverTimezone;
}

/**
* @param \DateTimeZone $timezone
*/
public function setServerTimezone(\DateTimeZone $timezone)
{
$this->serverTimezone = $timezone;
}

/**
* @return \DateTimeZone
*/
public function getTimezone()
{
return $this->timezone;
return $this->getServerTimezone();
}

/**
* @param \DateTimeZone $timezone
*/
public function setTimezone(\DateTimeZone $timezone)
{
$this->timezone = $timezone;
$this->setServerTimezone($timezone);
}


/**
* @param $format
* @param $string
* @return \DateTime
*/
protected function newDate($format, $string)
{
if (!! $this->getFeedTimezone()) {
return \DateTime::createFromFormat($format, $string, $this->getFeedTimezone());
}

return \DateTime::createFromFormat($format, $string);
}
}

0 comments on commit e4a74d8

Please sign in to comment.