Skip to content

Commit

Permalink
Add timezone property to city (#140)
Browse files Browse the repository at this point in the history
Add timezone property to city
  • Loading branch information
cmfcmf authored Jan 22, 2020
2 parents 81a3ed2 + 55f2c5f commit 9c4df93
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 11 deletions.
4 changes: 2 additions & 2 deletions Cmfcmf/OpenWeatherMap/CurrentWeather.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public function __construct($data, $units)
$utctz = new \DateTimeZone('UTC');

if ($data instanceof \SimpleXMLElement) {
$this->city = new City($data->city['id'], $data->city['name'], $data->city->coord['lat'], $data->city->coord['lon'], $data->city->country);
$this->city = new City($data->city['id'], $data->city['name'], $data->city->coord['lat'], $data->city->coord['lon'], $data->city->country, null, $data->city->timezone);
$this->temperature = new Temperature(new Unit($data->temperature['value'], $data->temperature['unit']), new Unit($data->temperature['min'], $data->temperature['unit']), new Unit($data->temperature['max'], $data->temperature['unit']));
$this->humidity = new Unit($data->humidity['value'], $data->humidity['unit']);
$this->pressure = new Unit($data->pressure['value'], $data->pressure['unit']);
Expand All @@ -118,7 +118,7 @@ public function __construct($data, $units)
$this->weather = new Weather($data->weather['number'], $data->weather['value'], $data->weather['icon']);
$this->lastUpdate = new \DateTime($data->lastupdate['value'], $utctz);
} else {
$this->city = new City($data->id, $data->name, $data->coord->lat, $data->coord->lon, $data->sys->country);
$this->city = new City($data->id, $data->name, $data->coord->lat, $data->coord->lon, $data->sys->country, null, $data->timezone);
$this->temperature = new Temperature(new Unit($data->main->temp, $units), new Unit($data->main->temp_min, $units), new Unit($data->main->temp_max, $units));
$this->humidity = new Unit($data->main->humidity, '%');
$this->pressure = new Unit($data->main->pressure, 'hPa');
Expand Down
37 changes: 30 additions & 7 deletions Cmfcmf/OpenWeatherMap/Util/City.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,25 +43,48 @@ class City extends Location
*/
public $population;

/**
* @var \DateTimeZone|null The shift in seconds from UTC
*/
public $timezone;

/**
* Create a new city object.
*
* @param int $id The city id.
* @param string $name The name of the city.
* @param float $lat The latitude of the city.
* @param float $lon The longitude of the city.
* @param string $country The abbreviation of the country the city is located in
* @param int $population The city's population.
* @param int $id The city id.
* @param string $name The name of the city.
* @param float $lat The latitude of the city.
* @param float $lon The longitude of the city.
* @param string $country The abbreviation of the country the city is located in
* @param int $population The city's population.
* @param int $timezoneOffset The shift in seconds from UTC.
*
* @internal
*/
public function __construct($id, $name = null, $lat = null, $lon = null, $country = null, $population = null)
public function __construct($id, $name = null, $lat = null, $lon = null, $country = null, $population = null, $timezoneOffset = null)
{
$this->id = (int)$id;
$this->name = isset($name) ? (string)$name : null;
$this->country = isset($country) ? (string)$country : null;
$this->population = isset($population) ? (int)$population : null;
$this->timezone = isset($timezoneOffset) ? new \DateTimeZone(self::timezoneOffsetInSecondsToHours($timezoneOffset)) : null;

parent::__construct($lat, $lon);
}

/**
* @param int $offset The timezone offset in seconds from UTC.
* @return int The timezone offset in +/-HH:MM form.
*/
private static function timezoneOffsetInSecondsToHours($offset)
{
$minutes = floor(abs($offset) / 60) % 60;
$hours = floor(abs($offset) / 3600);

$result = $offset < 0 ? "-" : "+";
$result .= str_pad($hours, 2, "0", STR_PAD_LEFT);
$result .= str_pad($minutes, 2, "0", STR_PAD_LEFT);

return $result;
}
}
2 changes: 1 addition & 1 deletion Cmfcmf/OpenWeatherMap/WeatherForecast.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class WeatherForecast implements \Iterator
*/
public function __construct($xml, $units, $days)
{
$this->city = new City($xml->location->location['geobaseid'], $xml->location->name, $xml->location->location['latitude'], $xml->location->location['longitude'], $xml->location->country);
$this->city = new City($xml->location->location['geobaseid'], $xml->location->name, $xml->location->location['latitude'], $xml->location->location['longitude'], $xml->location->country, null, $xml->location->timezone);
$utctz = new \DateTimeZone('UTC');
$this->sun = new Sun(new \DateTime($xml->sun['rise'], $utctz), new \DateTime($xml->sun['set'], $utctz));
$this->lastUpdate = new \DateTime($xml->meta->lastupdate, $utctz);
Expand Down
5 changes: 4 additions & 1 deletion Examples/CurrentWeather.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@
echo $lf;

// Example 6: Get information about a city.
$weather = $owm->getWeather('Paris', $units, $lang);
$weather = $owm->getWeather('Kathmandu', $units, $lang);
echo "$lf$lf EXAMPLE 6$lf";

echo 'Id: '.$weather->city->id;
Expand All @@ -163,6 +163,9 @@
echo 'Country: '.$weather->city->country;
echo $lf;

echo 'Timezone offset to UTC: '.$weather->city->timezone->getOffset(new DateTime("now", new DateTimeZone("UTC")))." seconds";
echo $lf;

// Example 7: Get wind information.
echo "$lf$lf EXAMPLE 7$lf";

Expand Down
4 changes: 4 additions & 0 deletions tests/FakeData.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class FakeData
const WEATHER_GROUP_JSON = '{
"list":[{
"id":1851632,
"timezone": 32400,
"dt":1406106000,
"coord":{"lon":138.933334,"lat":34.966671},
"sys":{"type":3,"id":168940,"message":0.0297,"country":"US","sunrise":1427723751,"sunset":1427768967},
Expand All @@ -43,6 +44,7 @@ class FakeData
},{
"id":1851633,
"dt":1406106000,
"timezone": 32400,
"coord":{"lon":138.933334,"lat":34.966671},
"sys":{"type":3,"id":168940,"message":0.0297,"country":"US","sunrise":1427723751,"sunset":1427768967},
"name":"Shuzenji",
Expand Down Expand Up @@ -110,6 +112,7 @@ public static function forecastXML()
<city id="2950159" name="Berlin">
<coord lon="13.41" lat="52.52"></coord>
<country>DE</country>
<timezone>3600</timezone>
<sun rise="2017-01-02T07:16:51" set="2017-01-02T15:04:50"></sun>
</city>
<temperature value="36.48" min="35.6" max="37.4" unit="fahrenheit"></temperature>
Expand Down Expand Up @@ -137,6 +140,7 @@ public static function forecastXML()
<city id="2950159" name="Berlin">
<coord lon="13.41" lat="52.52"></coord>
<country>DE</country>
<timezone>3600</timezone>
<sun rise="2017-01-02T07:16:51" set="2017-01-02T15:04:50"></sun>
</city>
<temperature value="36.48" min="35.6" max="37.4" unit="fahrenheit"></temperature>
Expand Down
50 changes: 50 additions & 0 deletions tests/Util/CityTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

/*
* OpenWeatherMap-PHP-API — A PHP API to parse weather data from https://OpenWeatherMap.org.
*
* @license MIT
*
* Please see the LICENSE file distributed with this source code for further
* information regarding copyright and licensing.
*
* Please visit the following links to read about the usage policies and the license of
* OpenWeatherMap data before using this library:
*
* @see https://OpenWeatherMap.org/price
* @see https://OpenWeatherMap.org/terms
* @see https://OpenWeatherMap.org/appid
*/

namespace Cmfcmf\OpenWeatherMap\Tests\Util;

use Cmfcmf\OpenWeatherMap\Util\City;

class CityTest extends \PHPUnit_Framework_TestCase
{
/**
* @dataProvider timezoneDataProvider
*/
public function testTimezoneConversion($offsetString, $offsetSeconds)
{
$class = new \ReflectionClass(City::class);
$method = $class->getMethod("timezoneOffsetInSecondsToHours");
$method->setAccessible(true);

$this->assertSame($offsetString, $method->invoke(null, $offsetSeconds));
$offsetTimezone = new \DateTimeZone($offsetString);
$this->assertSame($offsetSeconds, $offsetTimezone->getOffset(new \DateTime("now", new \DateTimeZone("GMT"))));
}

public function timezoneDataProvider()
{
return [
["+0100", 3600],
["+0100", 3600],
["+0030", 1800],
["+0015", 900],
["+0000", 0],
["+0545", 20700],
];
}
}

0 comments on commit 9c4df93

Please sign in to comment.