diff --git a/include/class.dynamic_forms.php b/include/class.dynamic_forms.php
index 2b112078d8f92d037cbdef4107395b9ff5f05cb8..172a1580901259b03aff20a0878e90212b8f69f5 100644
--- a/include/class.dynamic_forms.php
+++ b/include/class.dynamic_forms.php
@@ -321,8 +321,7 @@ class DynamicForm extends VerySimpleModel {
         $f = $answer->getField();
         $name = $f->get('name') ? $f->get('name')
             : 'field_'.$f->get('id');
-        $fields = sprintf('`%s`=', $name) . db_input(
-            implode(',', $answer->getSearchKeys()));
+        $fields = sprintf('`%s`=', $name) . db_input($answer->getSearchKeys());
         $sql = 'INSERT INTO `'.$cdata['table'].'` SET '.$fields
             . sprintf(', `%s`= %s',
                     $cdata['object_id'],
@@ -533,8 +532,7 @@ class TicketForm extends DynamicForm {
             return;
 
         $name = $f->get('name') ?: ('field_'.$f->get('id'));
-        $fields = sprintf('`%s`=', $name) . db_input(
-            implode(',', $answer->getSearchKeys()));
+        $fields = sprintf('`%s`=', $name) . db_input($answer->getSearchKeys());
         $sql = 'INSERT INTO `'.TABLE_PREFIX.'ticket__cdata` SET '.$fields
             .', `ticket_id`='.db_input($answer->getEntry()->get('object_id'))
             .' ON DUPLICATE KEY UPDATE '.$fields;
@@ -1443,14 +1441,7 @@ class DynamicFormEntryAnswer extends VerySimpleModel {
     }
 
     function getSearchKeys() {
-        $val = $this->getField()->to_php(
-            $this->get('value'), $this->get('value_id'));
-        if (is_array($val))
-            return array_keys($val);
-        elseif (is_object($val) && method_exists($val, 'getId'))
-            return array($val->getId());
-
-        return array($val);
+        return implode(',', (array) $this->getField()->getKeys($this->getValue()));
     }
 
     function asVar() {
@@ -1570,6 +1561,14 @@ class SelectionField extends FormField {
         return $value;
     }
 
+    function getKeys($value) {
+        if (!is_array($value))
+            $value = $this->getChoice($value);
+        if (is_array($value))
+            return implode(', ', array_keys($value));
+        return (string) $value;
+    }
+
     // PHP 5.4 Move this to a trait
     function whatChanged($before, $after) {
         $before = (array) $before;
diff --git a/include/class.forms.php b/include/class.forms.php
index 939f1ac55bc78dc7eb547d8a66e0c14df531b3ca..8c3ab09970900867cc6d10a43236cdc92e4b6cbb 100644
--- a/include/class.forms.php
+++ b/include/class.forms.php
@@ -884,6 +884,10 @@ class FormField {
         return Format::searchable($this->toString($value));
     }
 
+    function getKeys($value) {
+        return $this->to_database($value);
+    }
+
     /**
      * Fetches a list of options for searching. The values returned from
      * this method are passed to the widget's `::render()` method so that
@@ -1379,9 +1383,8 @@ class TextareaField extends FormField {
     }
 
     function searchable($value) {
-        $value = preg_replace(array('`<br(\s*)?/?>`i', '`</div>`i'), "\n", $value); //<?php
-        $value = Format::htmldecode(Format::striptags($value));
-        return Format::searchable($value);
+        $body = new HtmlThreadEntryBody($value);
+        return $body->getSearchable();
     }
 
     function export($value) {
@@ -1597,6 +1600,14 @@ class ChoiceField extends FormField {
         return (string) $value;
     }
 
+    function getKeys($value) {
+        if (!is_array($value))
+            $value = $this->getChoice($value);
+        if (is_array($value))
+            return implode(', ', array_keys($value));
+        return (string) $value;
+    }
+
     function whatChanged($before, $after) {
         $B = (array) $before;
         $A = (array) $after;
@@ -1743,14 +1754,14 @@ class DatetimeField extends FormField {
 
     function to_database($value) {
         // Store time in gmt time, unix epoch format
-        return (string) $value;
+        return date('Y-m-d H:i:s', $value);
     }
 
     function to_php($value) {
         if (!$value)
             return $value;
         else
-            return (int) $value;
+            return (int) strtotime($value);
     }
 
     function asVar($value, $id=false) {
@@ -1766,20 +1777,14 @@ class DatetimeField extends FormField {
         $config = $this->getConfiguration();
         // If GMT is set, convert to local time zone. Otherwise, leave
         // unchanged (default TZ is UTC)
+        if (!$value)
+            return '';
         if ($config['time'])
             return Format::datetime($value, false, !$config['gmt'] ? 'UTC' : false);
         else
             return Format::date($value, false, false, !$config['gmt'] ? 'UTC' : false);
     }
 
-    function export($value) {
-        $config = $this->getConfiguration();
-        if (!$value)
-            return '';
-        else
-            return Format::date($value, false, 'y-MM-dd HH:mm:ss', !$config['gmt'] ? 'UTC' : false);
-    }
-
     function getConfigurationOptions() {
         return array(
             'time' => new BooleanField(array(
@@ -1884,8 +1889,9 @@ class DatetimeField extends FormField {
 
     function getSearchQ($method, $value, $name=false) {
         $name = $name ?: $this->get('name');
+        $config = $this->getConfiguration();
         $value = is_int($value)
-            ? DateTime::createFromFormat('U', Misc::dbtime($value)) ?: $value
+            ? DateTime::createFromFormat('U', !$config['gmt'] ? Misc::dbtime($value) : $value) ?: $value
             : $value;
         switch ($method) {
         case 'equal':
@@ -1909,7 +1915,7 @@ class DatetimeField extends FormField {
         case 'between':
             foreach (array('left', 'right') as $side) {
                 $value[$side] = is_int($value[$side])
-                    ? DateTime::createFromFormat('U', Misc::dbtime($value[$side])) ?: $value[$side]
+                    ? DateTime::createFromFormat('U', !$config['gmt'] ? Misc::dbtime($value[$side]) : $value[$side]) ?: $value[$side]
                     : $value[$side];
             }
             return new Q(array(
@@ -2118,6 +2124,10 @@ class PriorityField extends ChoiceField {
         return null;
     }
 
+    function getKeys($value) {
+        return ($value instanceof Priority) ? array($value->getId()) : null;
+    }
+
     function getConfigurationOptions() {
         $choices = $this->getChoices();
         $choices[''] = __('System Default');
diff --git a/include/upgrader/streams/core/0d6099a6-98ad7d55.patch.sql b/include/upgrader/streams/core/0d6099a6-98ad7d55.patch.sql
index e6a054535316800e3a97ab3ab0cadd03c2fbb282..c388747703e7d831fe9da1d02bb38c71be2290b8 100644
--- a/include/upgrader/streams/core/0d6099a6-98ad7d55.patch.sql
+++ b/include/upgrader/streams/core/0d6099a6-98ad7d55.patch.sql
@@ -52,6 +52,15 @@ UPDATE `%TABLE_PREFIX%form_field` A1
   SET A1.`flags` = A1.`flags` | 0x00002
   WHERE A2.`type` = 'T' AND A1.`name` = 'message';
 
+-- Change storage type for `DatetimeField` values to Y-m-d format
+UPDATE `%TABLE_PREFIX%form_entry_values` A1
+  JOIN `%TABLE_PREFIX%form_field` A2 ON (A2.`id` = A1.`field_id`)
+  SET A1.`value` = DATE_FORMAT(FROM_UNIXTIME(A1.`value`), '%Y-%m-%d %H:%i:%s')
+  WHERE A2.`type` = 'datetime';
+
+-- Updates should happen in the %cdata tables too; however, those are more
+-- complex and the tables are being dropped anyway
+
 -- Finished with patch
 UPDATE `%TABLE_PREFIX%config`
     SET `value` = '98ad7d550c26ac44340350912296e673'
diff --git a/scp/tickets.php b/scp/tickets.php
index 44b474960eb3e7ec0a9cd091ccd3aa79fd1bbbe7..aa8347f8173b777762ee92ccc3e40944bce5cc0e 100644
--- a/scp/tickets.php
+++ b/scp/tickets.php
@@ -406,6 +406,7 @@ if($stats['overdue']) {
 
 if (isset($_SESSION['advsearch'])) {
     // XXX: De-duplicate and simplify this code
+    TicketForm::ensureDynamicDataView();
     $search = SavedSearch::create();
     $form = $search->getFormFromSession('advsearch');
     $tickets = TicketModel::objects();