WP-Opening-Hours icon indicating copy to clipboard operation
WP-Opening-Hours copied to clipboard

getIrregularOpeningInEffect ignores timezone

Open FlorianMoser opened this issue 7 years ago • 7 comments

OpeningHours\Entity\IrregularOpening::isOpen() seems to ignore the timezone.

How to reproduce:

$openingHours = OpeningHours::getInstance();
$set = $openingHours->getSet('my-set');
$now = new \DateTime('2017-09-11 14:09:00', new \DateTimeZone('Europe/Zurich'));
$io = $set->getIrregularOpeningInEffect($now);
var_dump($now);
var_dump($io);
echo $io->isOpen($now) ? 'open' : 'closed';

These are the $now and IrregularOpening vars:

object(DateTime)[3372]
  public 'date' => string '2017-09-11 14:09:00.000000' (length=26)
  public 'timezone_type' => int 3
  public 'timezone' => string 'Europe/Zurich' (length=13)

object(OpeningHours\Entity\IrregularOpening)[3385]
  protected 'name' => string 'Today' (length=5)
  protected 'timeStart' => 
    object(DateTime)[3394]
      public 'date' => string '2017-09-11 01:10:00.000000' (length=26)
      public 'timezone_type' => int 3
      public 'timezone' => string 'UTC' (length=3)
  protected 'timeEnd' => 
    object(DateTime)[3395]
      public 'date' => string '2017-09-11 12:10:00.000000' (length=26)
      public 'timezone_type' => int 3
      public 'timezone' => string 'UTC' (length=3)
  protected 'dummy' => boolean false

The expected output would be 'closed', but it is 'open'.

As soon as I change the $now time to 14:11, it works as expected. The timezone used in the example has GMT+2, so it is simply the timezone that causes the wrong result.

FlorianMoser avatar Sep 11 '17 12:09 FlorianMoser

Hi @FlorianMoser, I think this is actually the right behavior as WordPress sets the default server timezone to UTC https://weston.ruter.net/2013/04/02/do-not-change-the-default-timezone-from-utc-in-wordpress/.

What you are checking is: Is 14:09 in Europe/Zurich (which is 12:09 in UTC) between 01:11 UTC and 12:10 UTC, which is is the case. So the method returns true. So rather than ignoring the timezone it actually takes the timezone into consideration when saying (01:10 UTC) <= (14:09 Europe/Zurich / 12:09 UTC) <= (12:10 UTC) == true. But I am not quite sure as timezones have always given me headache. Do you agree?

janizde avatar Sep 11 '17 19:09 janizde

The reference is UTC, but as a WordPress user you set your own timezone under "Settings" => "General". So one would expect that the date/time he enters for "Irregular Openings" is based on his current timezone.

When I set an "Irregular Opening" start time of 01:10 and an end time of 12:10 (as in the example above), I expect that the state is "closed" between 01:10 and 12:10, not 03:10 and 14:10. The app should figure out itself how much the offset is.

FlorianMoser avatar Sep 11 '17 19:09 FlorianMoser

By the way, Period behaves correctly in the exact same situation:

        $openingHours = OpeningHours::getInstance();
        $set = $openingHours->getSet('my-set');
        $now = new \DateTime('2017-09-11 14:09:00', new \DateTimeZone('Europe/Zurich'));
        var_dump($now);
        $data = $set->getDataForDate($now);
        foreach ($data['periods'] as $period) {
            var_dump($period);
        }
        echo $set->isOpen($now) ? 'open' : 'closed';

The output here is:

object(DateTime)[3633]
  public 'date' => string '2017-09-11 14:09:00.000000' (length=26)
  public 'timezone_type' => int 3
  public 'timezone' => string 'Europe/Zurich' (length=13)

object(OpeningHours\Entity\Period)[3649]
  protected 'weekday' => int 1
  protected 'timeStart' => 
    object(DateTime)[3648]
      public 'date' => string '2017-09-11 01:10:00.000000' (length=26)
      public 'timezone_type' => int 3
      public 'timezone' => string 'UTC' (length=3)
  protected 'timeEnd' => 
    object(DateTime)[3646]
      public 'date' => string '2017-09-11 12:10:00.000000' (length=26)
      public 'timezone_type' => int 3
      public 'timezone' => string 'UTC' (length=3)
  protected 'spansTwoDays' => boolean false
  protected 'dummy' => boolean false

And the state is as expected 'closed'.

IrregularOpening should behave equally to be consistent.

FlorianMoser avatar Sep 11 '17 19:09 FlorianMoser

Ok so you have set the values 01:10 and 12:10 in the interface, I thought it has already been converted in the dump. I will have a look at it when I have the time. Thanks for pointing out

janizde avatar Sep 11 '17 19:09 janizde

Have you come across this problem while using one of the Widgets / Shortcodes or while using the PHP API? Because when using the API you can just drop the timezone which will then be in UTC which is "fake Europe/Zurich" and it should work.

janizde avatar Sep 11 '17 19:09 janizde

Ok so you have set the values 01:10 and 12:10 in the interface, I thought it has already been converted in the dump.

I should have mentioned that, yes :-). The dump is exactly the time I entered in the interface.

Thanks for looking into it.

FlorianMoser avatar Sep 11 '17 19:09 FlorianMoser

Have you come across this problem while using one of the Widgets / Shortcodes or while using the PHP API?

API only. But as I mentioned above, Period and IrregularOpenings behave differently for exactly the same date.

FlorianMoser avatar Sep 11 '17 19:09 FlorianMoser