From bf5c5a9c5e329ef51abf925bd58fbcec92630c7f Mon Sep 17 00:00:00 2001
From: Demian Katz <demian.katz@villanova.edu>
Date: Tue, 21 May 2013 11:32:54 -0400
Subject: [PATCH] Force ChangeTracker to always work in UTC time. Resolves
 VUFIND-659.

---
 .../src/VuFind/Db/Table/ChangeTracker.php     | 44 ++++++++++++++++---
 .../src/Db/Table/ChangeTrackerTest.php        |  8 ++--
 2 files changed, 42 insertions(+), 10 deletions(-)

diff --git a/module/VuFind/src/VuFind/Db/Table/ChangeTracker.php b/module/VuFind/src/VuFind/Db/Table/ChangeTracker.php
index bb5e428655c..f2020fa7c86 100644
--- a/module/VuFind/src/VuFind/Db/Table/ChangeTracker.php
+++ b/module/VuFind/src/VuFind/Db/Table/ChangeTracker.php
@@ -99,7 +99,7 @@ class ChangeTracker extends Gateway
             $row = $this->createRow();
             $row->core = $core;
             $row->id = $id;
-            $row->first_indexed = $row->last_indexed = date($this->dateFormat);
+            $row->first_indexed = $row->last_indexed = $this->getUtcDate();
         }
         return $row;
     }
@@ -125,11 +125,43 @@ class ChangeTracker extends Gateway
         }
 
         // Save new value to the object:
-        $row->deleted = date($this->dateFormat);
+        $row->deleted = $this->getUtcDate();
         $row->save();
         return $row;
     }
 
+    /**
+     * Get a UTC time.
+     *
+     * @param int $ts Timestamp (null for current)
+     *
+     * @return string
+     */
+    protected function getUtcDate($ts = null)
+    {
+        $oldTz = date_default_timezone_get();
+        date_default_timezone_set('UTC');
+        $date = date($this->dateFormat, null === $ts ? time() : $ts);
+        date_default_timezone_set($oldTz);
+        return $date;
+    }
+
+    /**
+     * Convert a string to time in UTC.
+     *
+     * @param string $str String to parse
+     *
+     * @return int
+     */
+    protected function strToUtcTime($str)
+    {
+        $oldTz = date_default_timezone_get();
+        date_default_timezone_set('UTC');
+        $time = strtotime($str);
+        date_default_timezone_set($oldTz);
+        return $time;
+    }
+
     /**
      * Update the change_tracker table to reflect that a record has been indexed.
      * We need to know the date of the last change to the record (independent of
@@ -155,7 +187,7 @@ class ChangeTracker extends Gateway
         // Make sure there is a change date in the row (this will be empty
         // if we just created a new row):
         if (empty($row->last_record_change)) {
-            $row->last_record_change = date($this->dateFormat, $change);
+            $row->last_record_change = $this->getUtcDate($change);
             $saveNeeded = true;
         }
 
@@ -163,11 +195,11 @@ class ChangeTracker extends Gateway
         // record change date before current record change date?  Either way,
         // we need to update the table!
         if (!empty($row->deleted)
-            || strtotime($row->last_record_change) < $change
+            || $this->strToUtcTime($row->last_record_change) < $change
         ) {
             // Save new values to the object:
-            $row->last_indexed = date($this->dateFormat);
-            $row->last_record_change = date($this->dateFormat, $change);
+            $row->last_indexed = $this->getUtcDate();
+            $row->last_record_change = $this->getUtcDate($change);
 
             // If first indexed is null, we're restoring a deleted record, so
             // we need to treat it as new -- we'll use the current time.
diff --git a/module/VuFind/tests/unit-tests/src/Db/Table/ChangeTrackerTest.php b/module/VuFind/tests/unit-tests/src/Db/Table/ChangeTrackerTest.php
index 73bfa51aaad..20d1db89cfa 100644
--- a/module/VuFind/tests/unit-tests/src/Db/Table/ChangeTrackerTest.php
+++ b/module/VuFind/tests/unit-tests/src/Db/Table/ChangeTrackerTest.php
@@ -55,7 +55,7 @@ class ChangeTrackerTest extends \VuFindTest\Unit\DbTestCase
         $this->assertTrue(is_object($row));
         $this->assertTrue(empty($row->deleted));
         $this->assertEquals($row->first_indexed, $row->last_indexed);
-        $this->assertEquals($row->last_record_change, '2012-01-17 15:46:10');
+        $this->assertEquals($row->last_record_change, '2012-01-17 20:46:10');
 
         // Try to index an earlier record version -- changes should be ignored:
         $tracker->index($core, 'test1', 1326830000);
@@ -63,7 +63,7 @@ class ChangeTrackerTest extends \VuFindTest\Unit\DbTestCase
         $this->assertTrue(is_object($row));
         $this->assertTrue(empty($row->deleted));
         $this->assertEquals($row->first_indexed, $row->last_indexed);
-        $this->assertEquals($row->last_record_change, '2012-01-17 15:46:10');
+        $this->assertEquals($row->last_record_change, '2012-01-17 20:46:10');
 
         // Index a later record version -- this should lead to changes:
         $tracker->index($core, 'test1', 1326833176);
@@ -74,7 +74,7 @@ class ChangeTrackerTest extends \VuFindTest\Unit\DbTestCase
             // use <= in case test runs too fast for values to become unequal:
             strtotime($row->first_indexed) <= strtotime($row->last_indexed)
         );
-        $this->assertEquals($row->last_record_change, '2012-01-17 15:46:16');
+        $this->assertEquals($row->last_record_change, '2012-01-17 20:46:16');
 
         // Delete the record:
         $tracker->markDeleted($core, 'test1');
@@ -94,7 +94,7 @@ class ChangeTrackerTest extends \VuFindTest\Unit\DbTestCase
         $row = $tracker->retrieve($core, 'test2');
         $this->assertTrue(is_object($row));
         $this->assertTrue(empty($row->deleted));
-        $this->assertEquals($row->last_record_change, '2012-01-17 15:46:10');
+        $this->assertEquals($row->last_record_change, '2012-01-17 20:46:10');
 
         // Clean up after ourselves:
         $tracker->delete(array('core' => $core));
-- 
GitLab