From f5bc3228d16e2db332a0531d92050358f891c357 Mon Sep 17 00:00:00 2001 From: Hennell Date: Mon, 9 Dec 2019 16:45:30 +0000 Subject: [PATCH 1/2] Add timezone property to city. --- Cmfcmf/OpenWeatherMap/CurrentWeather.php | 4 ++-- Cmfcmf/OpenWeatherMap/Util/City.php | 8 +++++++- Cmfcmf/OpenWeatherMap/WeatherForecast.php | 2 +- tests/FakeData.php | 4 ++++ 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Cmfcmf/OpenWeatherMap/CurrentWeather.php b/Cmfcmf/OpenWeatherMap/CurrentWeather.php index 59da32a..8e7494a 100644 --- a/Cmfcmf/OpenWeatherMap/CurrentWeather.php +++ b/Cmfcmf/OpenWeatherMap/CurrentWeather.php @@ -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']); @@ -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'); diff --git a/Cmfcmf/OpenWeatherMap/Util/City.php b/Cmfcmf/OpenWeatherMap/Util/City.php index 65f0da9..5d09ab7 100644 --- a/Cmfcmf/OpenWeatherMap/Util/City.php +++ b/Cmfcmf/OpenWeatherMap/Util/City.php @@ -43,6 +43,10 @@ class City extends Location */ public $population; + /** + * @var int The shift in seconds from UTC + */ + public $timezone; /** * Create a new city object. * @@ -52,15 +56,17 @@ class City extends Location * @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 $timezone 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, $timezone = 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($timezone) ? (int)$timezone : null; parent::__construct($lat, $lon); } diff --git a/Cmfcmf/OpenWeatherMap/WeatherForecast.php b/Cmfcmf/OpenWeatherMap/WeatherForecast.php index ba4716d..002015c 100644 --- a/Cmfcmf/OpenWeatherMap/WeatherForecast.php +++ b/Cmfcmf/OpenWeatherMap/WeatherForecast.php @@ -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); diff --git a/tests/FakeData.php b/tests/FakeData.php index 2a8bd5a..f286989 100644 --- a/tests/FakeData.php +++ b/tests/FakeData.php @@ -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}, @@ -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", @@ -110,6 +112,7 @@ public static function forecastXML() DE + 3600 @@ -137,6 +140,7 @@ public static function forecastXML() DE + 3600 From 98b173f6f8769e3e8d7b04c9d39b641b4ab2ee97 Mon Sep 17 00:00:00 2001 From: Christian Flach Date: Thu, 2 Jan 2020 00:37:33 +0100 Subject: [PATCH 2/2] Transform timezone offsets into DateTimeZones --- Cmfcmf/OpenWeatherMap/Util/City.php | 37 +++++++++++++++------ Examples/CurrentWeather.php | 5 ++- tests/Util/CityTest.php | 50 +++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 11 deletions(-) create mode 100644 tests/Util/CityTest.php diff --git a/Cmfcmf/OpenWeatherMap/Util/City.php b/Cmfcmf/OpenWeatherMap/Util/City.php index 5d09ab7..3562ec3 100644 --- a/Cmfcmf/OpenWeatherMap/Util/City.php +++ b/Cmfcmf/OpenWeatherMap/Util/City.php @@ -44,30 +44,47 @@ class City extends Location public $population; /** - * @var int The shift in seconds from UTC + * @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 $timezone The shift in seconds from UTC. + * @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, $timezone = 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($timezone) ? (int)$timezone : 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; + } } diff --git a/Examples/CurrentWeather.php b/Examples/CurrentWeather.php index 4065f08..74c3668 100644 --- a/Examples/CurrentWeather.php +++ b/Examples/CurrentWeather.php @@ -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; @@ -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"; diff --git a/tests/Util/CityTest.php b/tests/Util/CityTest.php new file mode 100644 index 0000000..9df8b7a --- /dev/null +++ b/tests/Util/CityTest.php @@ -0,0 +1,50 @@ +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], + ]; + } +}