Bug 16376 - Koha::Calendar->is_holiday date truncation creates fatal errors for TZ...
authorDavid Cook <dcook@prosentient.com.au>
Mon, 23 May 2016 01:57:04 +0000 (11:57 +1000)
committerKyle M Hall <kyle@bywatersolutions.com>
Fri, 9 Dec 2016 15:25:01 +0000 (15:25 +0000)
Using a DateTime object with a timezone of America/Santiago
was causing fatal errors for Koha::Calendar->is_holiday
and Koha::Calendar->exception_holidays, when the objects
were truncated to an invalid local time.

Using a floating zone allows us to use the same day, month, year
for comparison purposes without running into the possibility of
creating an invalid local time and thus a fatal software error.

Edit:

While the changes to is_holiday and single_holiday make sense (Jonathan agrees too)
I didn't manage to have them fail, because truncate is not failing in my trials, but
days_between. So to me, it narrows down to have exception_holiday return floating tz
datetime objects so it doesn't break days_between.

Anyway, it is ok to push this patch, and the regression test I provide covers this scenario
I'm describing.

To test:
- Apply the regression tests patch
- Run:
  $ prove t/db_dependent/Holidays.t
=> FAIL: Unexpected error due to bad timezone/date combination
- Apply this patch
- Run:
  $ prove t/db_dependent/Holidays.t
=> SUCCESS: Tests pass

Signed-off-by: Chris Cormack <chris@bigballofwax.co.nz>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>

Koha/Calendar.pm

index eed55cb..f6cb58c 100644 (file)
@@ -72,7 +72,7 @@ sub exception_holidays {
             day       => $day,
             month     => $month,
             year      => $year,
-            time_zone => C4::Context->tz()
+            time_zone => "floating",
           )->truncate( to => 'day' );
     }
     $self->{exception_holidays} =
@@ -118,7 +118,7 @@ sub single_holidays {
                     day       => $day,
                     month     => $month,
                     year      => $year,
-                    time_zone => C4::Context->tz()
+                    time_zone => 'floating',
                 )->truncate( to => 'day' );
                 push @ymd_arr, $dt->ymd('');
             }
@@ -235,6 +235,8 @@ sub is_holiday {
     my $day   = $localdt->day;
     my $month = $localdt->month;
 
+    #Change timezone to "floating" before doing any calculations or comparisons
+    $localdt->set_time_zone("floating");
     $localdt->truncate( to => 'day' );