Skip to content

Commit 9c4df93

Browse files
authored
Add timezone property to city (#140)
Add timezone property to city
2 parents 81a3ed2 + 55f2c5f commit 9c4df93

File tree

6 files changed

+91
-11
lines changed

6 files changed

+91
-11
lines changed

Cmfcmf/OpenWeatherMap/CurrentWeather.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ public function __construct($data, $units)
104104
$utctz = new \DateTimeZone('UTC');
105105

106106
if ($data instanceof \SimpleXMLElement) {
107-
$this->city = new City($data->city['id'], $data->city['name'], $data->city->coord['lat'], $data->city->coord['lon'], $data->city->country);
107+
$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);
108108
$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']));
109109
$this->humidity = new Unit($data->humidity['value'], $data->humidity['unit']);
110110
$this->pressure = new Unit($data->pressure['value'], $data->pressure['unit']);
@@ -118,7 +118,7 @@ public function __construct($data, $units)
118118
$this->weather = new Weather($data->weather['number'], $data->weather['value'], $data->weather['icon']);
119119
$this->lastUpdate = new \DateTime($data->lastupdate['value'], $utctz);
120120
} else {
121-
$this->city = new City($data->id, $data->name, $data->coord->lat, $data->coord->lon, $data->sys->country);
121+
$this->city = new City($data->id, $data->name, $data->coord->lat, $data->coord->lon, $data->sys->country, null, $data->timezone);
122122
$this->temperature = new Temperature(new Unit($data->main->temp, $units), new Unit($data->main->temp_min, $units), new Unit($data->main->temp_max, $units));
123123
$this->humidity = new Unit($data->main->humidity, '%');
124124
$this->pressure = new Unit($data->main->pressure, 'hPa');

Cmfcmf/OpenWeatherMap/Util/City.php

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,25 +43,48 @@ class City extends Location
4343
*/
4444
public $population;
4545

46+
/**
47+
* @var \DateTimeZone|null The shift in seconds from UTC
48+
*/
49+
public $timezone;
50+
4651
/**
4752
* Create a new city object.
4853
*
49-
* @param int $id The city id.
50-
* @param string $name The name of the city.
51-
* @param float $lat The latitude of the city.
52-
* @param float $lon The longitude of the city.
53-
* @param string $country The abbreviation of the country the city is located in
54-
* @param int $population The city's population.
54+
* @param int $id The city id.
55+
* @param string $name The name of the city.
56+
* @param float $lat The latitude of the city.
57+
* @param float $lon The longitude of the city.
58+
* @param string $country The abbreviation of the country the city is located in
59+
* @param int $population The city's population.
60+
* @param int $timezoneOffset The shift in seconds from UTC.
5561
*
5662
* @internal
5763
*/
58-
public function __construct($id, $name = null, $lat = null, $lon = null, $country = null, $population = null)
64+
public function __construct($id, $name = null, $lat = null, $lon = null, $country = null, $population = null, $timezoneOffset = null)
5965
{
6066
$this->id = (int)$id;
6167
$this->name = isset($name) ? (string)$name : null;
6268
$this->country = isset($country) ? (string)$country : null;
6369
$this->population = isset($population) ? (int)$population : null;
70+
$this->timezone = isset($timezoneOffset) ? new \DateTimeZone(self::timezoneOffsetInSecondsToHours($timezoneOffset)) : null;
6471

6572
parent::__construct($lat, $lon);
6673
}
74+
75+
/**
76+
* @param int $offset The timezone offset in seconds from UTC.
77+
* @return int The timezone offset in +/-HH:MM form.
78+
*/
79+
private static function timezoneOffsetInSecondsToHours($offset)
80+
{
81+
$minutes = floor(abs($offset) / 60) % 60;
82+
$hours = floor(abs($offset) / 3600);
83+
84+
$result = $offset < 0 ? "-" : "+";
85+
$result .= str_pad($hours, 2, "0", STR_PAD_LEFT);
86+
$result .= str_pad($minutes, 2, "0", STR_PAD_LEFT);
87+
88+
return $result;
89+
}
6790
}

Cmfcmf/OpenWeatherMap/WeatherForecast.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ class WeatherForecast implements \Iterator
7474
*/
7575
public function __construct($xml, $units, $days)
7676
{
77-
$this->city = new City($xml->location->location['geobaseid'], $xml->location->name, $xml->location->location['latitude'], $xml->location->location['longitude'], $xml->location->country);
77+
$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);
7878
$utctz = new \DateTimeZone('UTC');
7979
$this->sun = new Sun(new \DateTime($xml->sun['rise'], $utctz), new \DateTime($xml->sun['set'], $utctz));
8080
$this->lastUpdate = new \DateTime($xml->meta->lastupdate, $utctz);

Examples/CurrentWeather.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@
145145
echo $lf;
146146

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

151151
echo 'Id: '.$weather->city->id;
@@ -163,6 +163,9 @@
163163
echo 'Country: '.$weather->city->country;
164164
echo $lf;
165165

166+
echo 'Timezone offset to UTC: '.$weather->city->timezone->getOffset(new DateTime("now", new DateTimeZone("UTC")))." seconds";
167+
echo $lf;
168+
166169
// Example 7: Get wind information.
167170
echo "$lf$lf EXAMPLE 7$lf";
168171

tests/FakeData.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class FakeData
2323
const WEATHER_GROUP_JSON = '{
2424
"list":[{
2525
"id":1851632,
26+
"timezone": 32400,
2627
"dt":1406106000,
2728
"coord":{"lon":138.933334,"lat":34.966671},
2829
"sys":{"type":3,"id":168940,"message":0.0297,"country":"US","sunrise":1427723751,"sunset":1427768967},
@@ -43,6 +44,7 @@ class FakeData
4344
},{
4445
"id":1851633,
4546
"dt":1406106000,
47+
"timezone": 32400,
4648
"coord":{"lon":138.933334,"lat":34.966671},
4749
"sys":{"type":3,"id":168940,"message":0.0297,"country":"US","sunrise":1427723751,"sunset":1427768967},
4850
"name":"Shuzenji",
@@ -110,6 +112,7 @@ public static function forecastXML()
110112
<city id="2950159" name="Berlin">
111113
<coord lon="13.41" lat="52.52"></coord>
112114
<country>DE</country>
115+
<timezone>3600</timezone>
113116
<sun rise="2017-01-02T07:16:51" set="2017-01-02T15:04:50"></sun>
114117
</city>
115118
<temperature value="36.48" min="35.6" max="37.4" unit="fahrenheit"></temperature>
@@ -137,6 +140,7 @@ public static function forecastXML()
137140
<city id="2950159" name="Berlin">
138141
<coord lon="13.41" lat="52.52"></coord>
139142
<country>DE</country>
143+
<timezone>3600</timezone>
140144
<sun rise="2017-01-02T07:16:51" set="2017-01-02T15:04:50"></sun>
141145
</city>
142146
<temperature value="36.48" min="35.6" max="37.4" unit="fahrenheit"></temperature>

tests/Util/CityTest.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
/*
4+
* OpenWeatherMap-PHP-API — A PHP API to parse weather data from https://OpenWeatherMap.org.
5+
*
6+
* @license MIT
7+
*
8+
* Please see the LICENSE file distributed with this source code for further
9+
* information regarding copyright and licensing.
10+
*
11+
* Please visit the following links to read about the usage policies and the license of
12+
* OpenWeatherMap data before using this library:
13+
*
14+
* @see https://OpenWeatherMap.org/price
15+
* @see https://OpenWeatherMap.org/terms
16+
* @see https://OpenWeatherMap.org/appid
17+
*/
18+
19+
namespace Cmfcmf\OpenWeatherMap\Tests\Util;
20+
21+
use Cmfcmf\OpenWeatherMap\Util\City;
22+
23+
class CityTest extends \PHPUnit_Framework_TestCase
24+
{
25+
/**
26+
* @dataProvider timezoneDataProvider
27+
*/
28+
public function testTimezoneConversion($offsetString, $offsetSeconds)
29+
{
30+
$class = new \ReflectionClass(City::class);
31+
$method = $class->getMethod("timezoneOffsetInSecondsToHours");
32+
$method->setAccessible(true);
33+
34+
$this->assertSame($offsetString, $method->invoke(null, $offsetSeconds));
35+
$offsetTimezone = new \DateTimeZone($offsetString);
36+
$this->assertSame($offsetSeconds, $offsetTimezone->getOffset(new \DateTime("now", new \DateTimeZone("GMT"))));
37+
}
38+
39+
public function timezoneDataProvider()
40+
{
41+
return [
42+
["+0100", 3600],
43+
["+0100", 3600],
44+
["+0030", 1800],
45+
["+0015", 900],
46+
["+0000", 0],
47+
["+0545", 20700],
48+
];
49+
}
50+
}

0 commit comments

Comments
 (0)