Skip to content

Timezone specifications are missing in some instances #119

Closed
@Clpsplug

Description

@Clpsplug

I think we have a Timezone issue. I found this out by getting weird weather icons in hourly forecasts.

Summary

This library requests weather forecasts in XML. Upon parsing the response, we are using DateTime to store the data for a 'block' of forecast (Example, this calls this,) and all the notation of time in the XML is in UTC. However, if PHP itself or the application is configured to default the timezone to anything other than UTC, the times are parsed wrong.

Reproduction Steps

Simply try calling getWeatherForecast, but make sure your timezone is NOT UTC.

<?php
use Cmfcmf\OpenWeatherMap

// Any timezone you are familiar with, except for UTC and equivalent, will do
date_default_timezone_set('America/Los_Angeles');

$forecast = (new OpenWeatherMap())->getWeatherForecast('ANY CITY', 'metric', 'en', 'APPKEY', 1);

var_dump($forecast);

You will need to compare the raw XML and the content of $forecast.

Actual Result

Timestamps for '3-hour forecast' are messed up.
If XML says 2018-04-13T00:00:00, The corresponding 3-hour forecast will have the timestamp of 2018-04-13T00:00:00 in the timezone we specified first.

Expected

It must consider the timezone for the XML response UTC.

Possible solution

  • Apply $utctz (defined in the constructor of WeatherForecast) to all occurrences of DateTime.
  • Switch over to JSON. JSON response will have unix timestamp instead of formatted date. DateTime ignores any timezone specification when it gets unix timestamp in the constructor.

Detailed explanation

I was using your lib through Laravel-OWM and I used \Gmopx\LaravelOWM\LaravelOWM::getWeatherForecast, which internally calls your \Cmfcmf\OpenWeatherMap::getWeatherForecast.
Things looked working minus the weather icon. Take a look at this screenshot:

Night icon for 12:00???

The time shown in <th> are the to value of the time in the forecast data.
There are 2 weird things:

  1. We are getting the 'day icon' for 12AM.
  2. The first forecast data is at 12AM. Shouldn't it be 3AM?

I looked into the code and I found that we are retrieving our forecast data in XML and in function WeatherForecast, we feed formatted times to \DateTime to set the time for the weather.

Here's the part of the output I got by XML while I tested the code (data truncated for clarity)

<forecast>
  <time from="2018-04-12T06:00:00" to="2018-04-12T09:00:00">
    <temperature unit="celsius" value="3.69" min="2.29" max="3.69"/>  </time>

However, if we take a look at the output from the same setup by JSON, notice that dt is written in UNIXTIME. (also truncated for clarity)

{
  "dt":1523523600,
  "main":
    {
      "temp":3.69,
      "temp_min":2.29,
      "temp_max":3.69,

It looks like $forecast->time['to'] == $dt.
However, (and here's the problem) when we make a DateTime instance, we don't specify any timezone. It's fine as long as we use the UNIXTIME - though we aren't, and this is causing problems for me :( DateTime by default will set its timezone to date.timezone in php.ini or whatever an application declare it to be. But every notation of time in API responses is in UTC! In my case, I'm using Laravel, and my config/app.php is configured to work in Asia/Tokyo (and I used Carbon for converting things!)

I also found that the library wrongly omits the forecast that is really a forecast. Here we get a DateTime instance without parameters so this is in the default timezone and is always correct, but we are comparing it with UTC at here. This also wreaks havoc on non-UTC environments.

I suspect this will be fixed by specifying UTC wherever we parse formatted time, or requesting JSON format to API, which returns unixtime (which will make DateTime ignore the timezone.)
So for example this line should be:

 $date = new \DateTime(isset($time['day']) ? $time['day'] : $time['to'], new \DateTimeZone('UTC'));

I didn't have time to send a PR right now, but I'm sending one once I get some :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions